Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic implementation of proof dependency analysis #4461

Merged
merged 34 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9ed559a
Basic implementation of proof dependency analysis
atomb Jul 20, 2023
b52bec3
Merge branch 'master' into verification-coverage-ids
jtristan Aug 24, 2023
088eca9
Rename utility methods
atomb Aug 23, 2023
adbe5bc
Basic tracking of assignments
atomb Aug 23, 2023
d260984
Track a few more proof dependencies
atomb Aug 24, 2023
d6f9eea
Fix customBoogie.patch
atomb Aug 25, 2023
8bb2303
Fix unit test for slightly different message
atomb Aug 25, 2023
671b7f6
Revert message change for preconditions
atomb Aug 25, 2023
9ab8bfd
Better dependency messages, assignment tracking
atomb Aug 25, 2023
2b8d580
Order text logger output by source location
atomb Aug 25, 2023
ac55f3f
Add test for proof dependency logging
atomb Aug 25, 2023
d40f73a
Adjust test output to account for changes
atomb Aug 25, 2023
595bded
Silence warning
atomb Aug 28, 2023
2804ef9
Remove obsolete statement
atomb Aug 28, 2023
698b067
Sort proof dependencies in text logger
atomb Aug 28, 2023
6803cad
Fix some expected test outputs
atomb Aug 29, 2023
8e098f9
Merge remote-tracking branch 'upstream/master' into verification-cove…
atomb Aug 29, 2023
80d174a
Move ProofDependencyManager to its own file
atomb Aug 30, 2023
5c6deff
Clean up ProofDependency
atomb Aug 30, 2023
6a671dd
Fix duplicate IDs in Boogie code
atomb Aug 30, 2023
3e4a91b
Fix NPE in test generation code
atomb Aug 30, 2023
ea859c5
Merge remote-tracking branch 'upstream/master' into verification-cove…
atomb Aug 30, 2023
50ee917
Merge remote-tracking branch 'upstream/master' into verification-cove…
atomb Aug 30, 2023
9e2ad02
Fix expected test output
atomb Aug 30, 2023
9133cf7
Various small cleanups
atomb Aug 30, 2023
2dc0052
Merge remote-tracking branch 'upstream/master' into verification-cove…
atomb Sep 1, 2023
04fca88
Use structured dependency labels from Boogie
atomb Sep 5, 2023
3c9b47d
Merge remote-tracking branch 'upstream/master' into verification-cove…
atomb Sep 5, 2023
813b190
Limit proof dependency analysis to one core
atomb Sep 5, 2023
5e75656
Fix customBoogie.patch
atomb Sep 5, 2023
1f9f243
Bump Boogie dependency
atomb Sep 6, 2023
c2a7c60
Merge remote-tracking branch 'upstream/master' into verification-cove…
atomb Sep 6, 2023
9e4bd05
Bump Boogie version in dotnet-tools.json, too
atomb Sep 6, 2023
582421c
Merge branch 'master' into verification-coverage-ids
atomb Sep 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Source/DafnyCore/AST/Expressions/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Numerics;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 1 addition & 0 deletions Source/DafnyCore/AST/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ void ObjectInvariant() {
public SystemModuleManager SystemModuleManager;
public DafnyOptions Options => Reporter.Options;
public ErrorReporter Reporter { get; set; }
public ProofDependencyManager ProofDependencyManager { get; set; }

public Program(string name, [Captured] LiteralModuleDecl module, [Captured] SystemModuleManager systemModuleManager, ErrorReporter reporter,
CompilationData compilation) {
Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/AST/SystemModuleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Linq;
using System.Security.Cryptography;
using System.Security.Policy;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/AST/TypeDeclarations/TupleTypeDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Diagnostics.Contracts;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Compilers/Python/Compiler-python.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using JetBrains.Annotations;
using ExtensionMethods;
using Microsoft.BaseTypes;
using Microsoft.Boogie;

namespace ExtensionMethods {
using Microsoft.Dafny;
Expand Down
2 changes: 1 addition & 1 deletion Source/DafnyCore/DafnyCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="System.Runtime.Numerics" Version="4.3.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.7.0" />
<PackageReference Include="Boogie.ExecutionEngine" Version="3.0.0" />
<PackageReference Include="Boogie.ExecutionEngine" Version="3.0.1" />
<PackageReference Include="Tomlyn" Version="0.16.2" />
</ItemGroup>

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Feature.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/JsonDiagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.Boogie;
using VCGeneration;
using static Microsoft.Dafny.ErrorRegistry;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Options/CommonOptionBag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.IO;
using System.Linq;
using DafnyCore;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Resolver/BoundsDiscovery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.Contracts;
using Microsoft.Boogie;

namespace Microsoft.Dafny {
public partial class ModuleResolver {
Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Resolver/FindFriendlyCalls_Visitor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.Contracts;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Resolver/GhostInterestVisitor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Diagnostics.Contracts;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Boogie;
using static Microsoft.Dafny.ResolutionErrors;

namespace Microsoft.Dafny;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.BaseTypes;
using Microsoft.Boogie;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Dafny.Plugins;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Resolver/PreType/PreTypeAdvice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.Contracts;
using Microsoft.Boogie;

namespace Microsoft.Dafny {
public class Advice {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.Contracts;
using Microsoft.Boogie;
using ResolutionContext = Microsoft.Dafny.ResolutionContext;

namespace Microsoft.Dafny {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using System.Linq;
using System.Numerics;
using System.Diagnostics.Contracts;
using Microsoft.Boogie;
using ResolutionContext = Microsoft.Dafny.ResolutionContext;

namespace Microsoft.Dafny {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using System.Diagnostics.Contracts;
using System.Runtime.Intrinsics.X86;
using JetBrains.Annotations;
using Microsoft.Boogie;
using Bpl = Microsoft.Boogie;
using ResolutionContext = Microsoft.Dafny.ResolutionContext;

Expand Down
2 changes: 0 additions & 2 deletions Source/DafnyCore/Resolver/TypeConstraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
using System.Numerics;
using System.Diagnostics.Contracts;
using JetBrains.Annotations;
using Microsoft.BaseTypes;
using Microsoft.Boogie;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Microsoft.Dafny {
Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Rewriters/BitvectorOptimization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Linq.Expressions;
using System.Numerics;
using Microsoft.Boogie;

namespace Microsoft.Dafny;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Rewriters/RunAllTestsMainMethod.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Boogie;
using System.Text.RegularExpressions;
using static Microsoft.Dafny.RewriterErrors;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Triggers/QuantifierSplitter.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright by the contributors to the Dafny Project
// SPDX-License-Identifier: MIT

using Microsoft.Boogie;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Triggers/QuantifiersCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Boogie;
using System.Diagnostics.Contracts;
using static Microsoft.Dafny.ErrorRegistry;

Expand Down
1 change: 0 additions & 1 deletion Source/DafnyCore/Triggers/QuantifiersCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Boogie;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;

Expand Down
209 changes: 209 additions & 0 deletions Source/DafnyCore/Verifier/ProofDependency.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright (C) Microsoft Corporation. All Rights Reserved.
// Copyright by the contributors to the Dafny Project
// SPDX-License-Identifier: MIT
//
//-----------------------------------------------------------------------------
using Microsoft.Dafny;
using IToken = Microsoft.Dafny.IToken;
using PODesc = Microsoft.Dafny.ProofObligationDescription;

namespace DafnyCore.Verifier;

// A proof dependency represents a particular part of a Dafny program
// that may be used in the process of proving its correctness. When
// Boogie proves a particular verification condition, it returns a
// list of strings, returned by the SMT solver, indicating which
// program elements were used in completing the proof. After this, the
// ProofDependencyManager can map each string to a more structured
// ProofDependency.
public abstract class ProofDependency {
keyboardDrummer marked this conversation as resolved.
Show resolved Hide resolved
keyboardDrummer marked this conversation as resolved.
Show resolved Hide resolved
public abstract string Description { get; }

public abstract RangeToken Range { get; }

public string LocationString() {
if (Range?.StartToken is null) {
return "<no location>";
}
var fn = Range.StartToken.filename;
var sl = Range.StartToken.line;
var sc = Range.StartToken.col - 1;
return $"{fn}({sl},{sc})";
}

public string RangeString() {
if (Range?.StartToken is null) {
return "<no range>";
}
var fn = Range.StartToken.filename;
var sl = Range.StartToken.line;
var sc = Range.StartToken.col - 1;
var el = Range.EndToken.line;
var ec = Range.EndToken.col - 1;
return $"{fn}({sl},{sc})-({el},{ec})";
}

public string OriginalString() {
return Range?.PrintOriginal();
}
}

// Represents the portion of a Dafny program corresponding to a proof
// obligation. This is particularly important to track because if a particular
// assertion batch can be proved without proving one of the assertions that is
// a proof obligation within it, that assertion must have been proved vacuously.
public class ProofObligationDependency : ProofDependency {
public override RangeToken Range { get; }

public PODesc.ProofObligationDescription ProofObligation { get; }

public override string Description =>
$"{ProofObligation.SuccessDescription}";

public ProofObligationDependency(IToken tok, PODesc.ProofObligationDescription proofObligation) {
Range = tok as RangeToken ?? new RangeToken(tok, tok);
ProofObligation = proofObligation;
}
}

// Represents the assumption of a requires clause in the process of
// proving a Dafny definition.
public class RequiresDependency : ProofDependency {
private Expression requires;

public override RangeToken Range =>
requires.RangeToken;

public override string Description =>
$"requires clause";

public RequiresDependency(Expression requires) {
this.requires = requires;
}
}

// Represents the goal of proving an ensures clause of a Dafny definition.
public class EnsuresDependency : ProofDependency {
private Expression ensures;

public override RangeToken Range =>
ensures.RangeToken;

public override string Description =>
"ensures clause";

public EnsuresDependency(Expression ensures) {
this.ensures = ensures;
}
}

// Represents the goal of proving a specific requires clause of a specific
// call.
public class CallRequiresDependency : ProofDependency {
private CallDependency call;
private RequiresDependency requires;

public override RangeToken Range =>
call.Range;

public override string Description =>
$"requires clause at {requires.RangeString()} from call";

public CallRequiresDependency(CallDependency call, RequiresDependency requires) {
this.call = call;
this.requires = requires;
}
}

// Represents the assumption of a specific ensures clause of a specific
// call.
public class CallEnsuresDependency : ProofDependency {
private CallDependency call;
private EnsuresDependency ensures;

public override RangeToken Range =>
call.Range;

public override string Description =>
$"ensures clause at {ensures.RangeString()} from call";

public CallEnsuresDependency(CallDependency call, EnsuresDependency ensures) {
this.call = call;
this.ensures = ensures;
}
}

// Represents the fact that a particular call occurred.
public class CallDependency : ProofDependency {
private CallStmt call;

public override RangeToken Range =>
call.RangeToken;

public override string Description =>
$"call";

public CallDependency(CallStmt call) {
this.call = call;
}
}

// Represents the assumption of a predicate in an `assume` statement.
public class AssumptionDependency : ProofDependency {
private Expression expr;

public override RangeToken Range =>
expr.RangeToken;

public override string Description =>
comment ?? $"assume {OriginalString()}";

private string comment;

public AssumptionDependency(string comment, Expression expr) {
this.comment = comment;
this.expr = expr;
}
}

// Represents the invariant of a loop.
public class InvariantDependency : ProofDependency {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these classes are only used in a single location, then I suggest you place them there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one, for invariant dependencies, is used in only one place (at the moment -- that could change). But most of the rest of the ProofDependency implementations are used in multiple locations. It feels more comprehensible to me to have them all in the same place.

private Expression invariant;

public override RangeToken Range =>
invariant.RangeToken;

public override string Description =>
$"loop invariant";

public InvariantDependency(Expression invariant) {
this.invariant = invariant;
}
}

// Represents an assignment statement. This includes the assignment to an
// out parameter implicit in a return statement.
public class AssignmentDependency : ProofDependency {
public override RangeToken Range { get; }

public override string Description =>
"assignment (or return)";

public AssignmentDependency(RangeToken rangeToken) {
this.Range = rangeToken;
}
}

// Represents dependency of a proof on the definition of a specific function.
public class FunctionDefinitionDependency : ProofDependency {
public override RangeToken Range => function.RangeToken;

public override string Description =>
$"function definition for {function.Name}";

private Function function;

public FunctionDefinitionDependency(Function f) {
function = f;
}
}
Loading
Loading