summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Core/Absy.cs21
-rw-r--r--Source/Core/LambdaHelper.cs2
-rw-r--r--Source/ExecutionEngine/ExecutionEngine.cs2
-rw-r--r--Source/ExecutionEngine/VerificationResultCache.cs56
-rw-r--r--Test/snapshots/Snapshots16.v0.bpl15
-rw-r--r--Test/snapshots/Snapshots16.v1.bpl15
-rw-r--r--Test/snapshots/runtest.snapshot2
-rw-r--r--Test/snapshots/runtest.snapshot.expect7
8 files changed, 118 insertions, 2 deletions
diff --git a/Source/Core/Absy.cs b/Source/Core/Absy.cs
index 649b4930..9a871e93 100644
--- a/Source/Core/Absy.cs
+++ b/Source/Core/Absy.cs
@@ -2013,6 +2013,27 @@ namespace Microsoft.Boogie {
// the body is only set if the function is declared with {:inline}
public Expr Body;
public Axiom DefinitionAxiom;
+
+ public IList<Axiom> otherDefinitionAxioms;
+ public IEnumerable<Axiom> OtherDefinitionAxioms
+ {
+ get
+ {
+ return otherDefinitionAxioms;
+ }
+ }
+
+ public void AddOtherDefinitionAxiom(Axiom axiom)
+ {
+ Contract.Requires(axiom != null);
+
+ if (otherDefinitionAxioms == null)
+ {
+ otherDefinitionAxioms = new List<Axiom>();
+ }
+ otherDefinitionAxioms.Add(axiom);
+ }
+
public bool doingExpansion;
private bool neverTrigger;
diff --git a/Source/Core/LambdaHelper.cs b/Source/Core/LambdaHelper.cs
index 6b435836..81da2cce 100644
--- a/Source/Core/LambdaHelper.cs
+++ b/Source/Core/LambdaHelper.cs
@@ -96,7 +96,7 @@ namespace Microsoft.Boogie {
if (0 < CommandLineOptions.Clo.VerifySnapshots && QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null)
{
// Attach a dummy checksum to avoid issues in the dependency analysis.
- var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> { "dummy" }, null);
+ var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> { "stable" }, null);
if (lambdaAttrs == null)
{
lambdaAttrs = checksumAttr;
diff --git a/Source/ExecutionEngine/ExecutionEngine.cs b/Source/ExecutionEngine/ExecutionEngine.cs
index 74d299d1..f1f18667 100644
--- a/Source/ExecutionEngine/ExecutionEngine.cs
+++ b/Source/ExecutionEngine/ExecutionEngine.cs
@@ -871,6 +871,8 @@ namespace Microsoft.Boogie
Implementation[] stablePrioritizedImpls = null;
if (0 < CommandLineOptions.Clo.VerifySnapshots)
{
+ // TODO(wuestholz): Maybe we should speed up this lookup.
+ OtherDefinitionAxiomsCollector.Collect(program.TopLevelDeclarations.OfType<Axiom>());
impls.Iter(impl => { DependencyCollector.DependenciesChecksum(impl); });
stablePrioritizedImpls = impls.OrderByDescending(
impl => impl.Priority != 1 ? impl.Priority : Cache.VerificationPriority(impl)).ToArray();
diff --git a/Source/ExecutionEngine/VerificationResultCache.cs b/Source/ExecutionEngine/VerificationResultCache.cs
index 60a6555a..9d1eea24 100644
--- a/Source/ExecutionEngine/VerificationResultCache.cs
+++ b/Source/ExecutionEngine/VerificationResultCache.cs
@@ -197,6 +197,52 @@ namespace Microsoft.Boogie
}
+ public class OtherDefinitionAxiomsCollector : ReadOnlyVisitor
+ {
+ Axiom currentAxiom;
+ Trigger currentTrigger;
+
+ public static void Collect(IEnumerable<Axiom> axioms)
+ {
+ var v = new OtherDefinitionAxiomsCollector();
+ foreach (var a in axioms)
+ {
+ v.currentAxiom = a;
+ v.VisitExpr(a.Expr);
+ v.currentAxiom = null;
+ }
+ }
+
+ public override QuantifierExpr VisitQuantifierExpr(QuantifierExpr node)
+ {
+ currentTrigger = node.Triggers;
+ while (currentTrigger != null)
+ {
+ foreach (var e in currentTrigger.Tr)
+ {
+ VisitExpr(e);
+ }
+ currentTrigger = currentTrigger.Next;
+ }
+ return base.VisitQuantifierExpr(node);
+ }
+
+ public override Expr VisitNAryExpr(NAryExpr node)
+ {
+ if (currentTrigger != null)
+ {
+ // We found a function call within a trigger of a quantifier expression.
+ var funCall = node.Fun as FunctionCall;
+ if (funCall != null && funCall.Func != null && funCall.Func.Checksum != null && funCall.Func.Checksum != "stable")
+ {
+ funCall.Func.AddOtherDefinitionAxiom(currentAxiom);
+ }
+ }
+ return base.VisitNAryExpr(node);
+ }
+ }
+
+
class DependencyCollector : ReadOnlyVisitor
{
private HashSet<Procedure> procedureDependencies;
@@ -301,6 +347,16 @@ namespace Microsoft.Boogie
{
VisitAxiom(node.DefinitionAxiom);
}
+ if (node.OtherDefinitionAxioms != null)
+ {
+ foreach (var a in node.OtherDefinitionAxioms)
+ {
+ if (a != node.DefinitionAxiom)
+ {
+ VisitAxiom(a);
+ }
+ }
+ }
return base.VisitFunction(node);
}
diff --git a/Test/snapshots/Snapshots16.v0.bpl b/Test/snapshots/Snapshots16.v0.bpl
new file mode 100644
index 00000000..45cb4a76
--- /dev/null
+++ b/Test/snapshots/Snapshots16.v0.bpl
@@ -0,0 +1,15 @@
+function {:checksum "1"} PlusOne(n: int) : int
+{
+ n + 1
+}
+
+function {:checksum "0"} F(n: int) : int;
+
+axiom (forall n: int :: { F(n) } F(n) == PlusOne(n));
+
+procedure {:checksum "2"} M();
+
+implementation {:id "M"} {:checksum "3"} M()
+{
+ assert F(0) == 1;
+}
diff --git a/Test/snapshots/Snapshots16.v1.bpl b/Test/snapshots/Snapshots16.v1.bpl
new file mode 100644
index 00000000..4d7cc354
--- /dev/null
+++ b/Test/snapshots/Snapshots16.v1.bpl
@@ -0,0 +1,15 @@
+function {:checksum "4"} PlusOne(n: int) : int
+{
+ n + 2
+}
+
+function {:checksum "0"} F(n: int) : int;
+
+axiom (forall n: int :: { F(n) } F(n) == PlusOne(n));
+
+procedure {:checksum "2"} M();
+
+implementation {:id "M"} {:checksum "3"} M()
+{
+ assert F(0) == 1; // error
+}
diff --git a/Test/snapshots/runtest.snapshot b/Test/snapshots/runtest.snapshot
index 9d456440..ffa54a53 100644
--- a/Test/snapshots/runtest.snapshot
+++ b/Test/snapshots/runtest.snapshot
@@ -1,2 +1,2 @@
-// RUN: %boogie -verifySnapshots:2 -verifySeparately Snapshots0.bpl Snapshots1.bpl Snapshots2.bpl Snapshots3.bpl Snapshots4.bpl Snapshots5.bpl Snapshots6.bpl Snapshots7.bpl Snapshots8.bpl Snapshots9.bpl Snapshots10.bpl Snapshots11.bpl Snapshots12.bpl Snapshots13.bpl Snapshots14.bpl Snapshots15.bpl > "%t"
+// RUN: %boogie -verifySnapshots:2 -verifySeparately Snapshots0.bpl Snapshots1.bpl Snapshots2.bpl Snapshots3.bpl Snapshots4.bpl Snapshots5.bpl Snapshots6.bpl Snapshots7.bpl Snapshots8.bpl Snapshots9.bpl Snapshots10.bpl Snapshots11.bpl Snapshots12.bpl Snapshots13.bpl Snapshots14.bpl Snapshots15.bpl Snapshots16.bpl > "%t"
// RUN: %diff "%s.expect" "%t"
diff --git a/Test/snapshots/runtest.snapshot.expect b/Test/snapshots/runtest.snapshot.expect
index 853c5a80..41193348 100644
--- a/Test/snapshots/runtest.snapshot.expect
+++ b/Test/snapshots/runtest.snapshot.expect
@@ -142,3 +142,10 @@ Execution trace:
Snapshots15.v1.bpl(5,5): anon0
Boogie program verifier finished with 0 verified, 1 error
+
+Boogie program verifier finished with 1 verified, 0 errors
+Snapshots16.v1.bpl(14,5): Error BP5001: This assertion might not hold.
+Execution trace:
+ Snapshots16.v1.bpl(14,5): anon0
+
+Boogie program verifier finished with 0 verified, 1 error