summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Nadia Polikarpova <nadia.polikarpova@gmail.com>2013-03-05 20:25:47 +0100
committerGravatar Nadia Polikarpova <nadia.polikarpova@gmail.com>2013-03-05 20:25:47 +0100
commitd584ab2b4240b58cd4ef59e53b970a05d8d13f79 (patch)
tree126f65115762afdf1f7469c32dd71a391038d616
parentcd750d09580f78b709b118efa5ac585b90a37bfe (diff)
New well-formedness checks for calculations (no cascading).
-rw-r--r--Source/Dafny/DafnyAst.cs8
-rw-r--r--Source/Dafny/Translator.cs27
-rw-r--r--Test/dafny0/Answer4
-rw-r--r--Test/dafny0/Calculations.dfy10
4 files changed, 28 insertions, 21 deletions
diff --git a/Source/Dafny/DafnyAst.cs b/Source/Dafny/DafnyAst.cs
index 1b9408a8..e1b1ed15 100644
--- a/Source/Dafny/DafnyAst.cs
+++ b/Source/Dafny/DafnyAst.cs
@@ -3151,14 +3151,6 @@ namespace Microsoft.Dafny {
}
return null;
}
-
- /// <summary>
- /// Should line i be used as a well-formedness context for the following lines and hints?
- /// (The line must be boolean).
- /// </summary>
- public bool IsContextLine(int i) {
- return Steps[i].ResolvedOp == BinaryExpr.ResolvedOpcode.Imp;
- }
}
public class MatchStmt : Statement
diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs
index 21e60d33..9252cde5 100644
--- a/Source/Dafny/Translator.cs
+++ b/Source/Dafny/Translator.cs
@@ -1853,6 +1853,7 @@ namespace Microsoft.Dafny {
ModuleDefinition currentModule = null; // the name of the module whose members are currently being translated
ICodeContext codeContext = null; // the method/iterator whose implementation is currently being translated
LocalVariable yieldCountVariable = null; // non-null when an iterator body is being translated
+ bool assertAsAssume = false; // generate assume statements instead of assert statements
int loopHeapVarCount = 0;
int otherTmpVarCount = 0;
Dictionary<string, Bpl.IdentifierExpr> _tmpIEs = new Dictionary<string, Bpl.IdentifierExpr>();
@@ -4406,7 +4407,7 @@ namespace Microsoft.Dafny {
Contract.Requires(errorMessage != null);
Contract.Ensures(Contract.Result<Bpl.PredicateCmd>() != null);
- if (RefinementToken.IsInherited(refinesToken, currentModule) && (codeContext == null || !codeContext.MustReverify)) {
+ if (assertAsAssume || (RefinementToken.IsInherited(refinesToken, currentModule) && (codeContext == null || !codeContext.MustReverify))) {
// produce an assume instead
return new Bpl.AssumeCmd(tok, condition);
} else {
@@ -4445,7 +4446,7 @@ namespace Microsoft.Dafny {
Contract.Requires(condition != null);
Contract.Ensures(Contract.Result<Bpl.PredicateCmd>() != null);
- if (RefinementToken.IsInherited(tok, currentModule) && (codeContext == null || !codeContext.MustReverify)) {
+ if (assertAsAssume || (RefinementToken.IsInherited(tok, currentModule) && (codeContext == null || !codeContext.MustReverify))) {
// produce an assume instead
return new Bpl.AssumeCmd(tok, condition, kv);
} else {
@@ -4826,12 +4827,16 @@ namespace Microsoft.Dafny {
if (*) {
assert wf(line0);
} else if (*) {
+ assume wf(line0);
+ // if op is ==>: assume line0;
hint0;
assert wf(line1);
assert line0 op line1;
assume false;
} else if (*) { ...
} else if (*) {
+ assume wf(line<n-1>);
+ // if op is ==>: assume line<n-1>;
hint<n-1>;
assert wf(line<n>);
assert line<n-1> op line<n>;
@@ -4848,19 +4853,26 @@ namespace Microsoft.Dafny {
// check steps:
for (int i = s.Steps.Count; 0 <= --i; ) {
b = new Bpl.StmtListBuilder();
- // assume all previous context lines:
- for (int j = 0; j <= i; j++) {
- if (s.IsContextLine(j)) {
- b.Add(new Bpl.AssumeCmd(s.Tok, etran.TrExpr(s.Lines[j])));
- }
+ // assume wf[line<i>]:
+ AddComment(b, stmt, "assume wf[line" + i.ToString() + "]");
+ assertAsAssume = true;
+ TrStmt_CheckWellformed(s.Lines[i], b, locals, etran, false);
+ assertAsAssume = false;
+ if (s.Steps[i].ResolvedOp == BinaryExpr.ResolvedOpcode.Imp) {
+ // assume line<i>:
+ AddComment(b, stmt, "assume line" + i.ToString());
+ b.Add(new Bpl.AssumeCmd(s.Tok, etran.TrExpr(s.Lines[i])));
}
// hint:
+ AddComment(b, stmt, "Hint" + i.ToString());
TrStmt(s.Hints[i], b, locals, etran);
// check well formedness of the goal line:
+ AddComment(b, stmt, "assert wf[line" + (i + 1).ToString() + "]");
TrStmt_CheckWellformed(s.Lines[i + 1], b, locals, etran, false);
bool splitHappened;
var ss = TrSplitExpr(s.Steps[i], etran, out splitHappened);
// assert step:
+ AddComment(b, stmt, "assert line" + i.ToString() + " " + s.Steps[i].ResolvedOp.ToString() + " line" + (i + 1).ToString());
if (!splitHappened) {
b.Add(AssertNS(s.Lines[i + 1].tok, etran.TrExpr(s.Steps[i]), "the calculation step between the previous line and this line might not hold"));
} else {
@@ -4875,6 +4887,7 @@ namespace Microsoft.Dafny {
}
// check well formedness of the first line:
b = new Bpl.StmtListBuilder();
+ AddComment(b, stmt, "assume wf[line0]");
TrStmt_CheckWellformed(s.Lines.First(), b, locals, etran, false);
b.Add(new Bpl.AssumeCmd(s.Tok, Bpl.Expr.False));
ifCmd = new Bpl.IfCmd(s.Tok, null, b.Collect(s.Tok), ifCmd, null);
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
index 6e775b43..e31ef49c 100644
--- a/Test/dafny0/Answer
+++ b/Test/dafny0/Answer
@@ -1796,10 +1796,10 @@ Calculations.dfy(8,17): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon19_Then
-Calculations.dfy(42,11): Error: assertion violation
+Calculations.dfy(44,11): Error: assertion violation
Execution trace:
(0,0): anon0
- Calculations.dfy(37,2): anon5_Else
+ Calculations.dfy(39,2): anon5_Else
Dafny program verifier finished with 5 verified, 4 errors
diff --git a/Test/dafny0/Calculations.dfy b/Test/dafny0/Calculations.dfy
index aa447d9f..8ef36139 100644
--- a/Test/dafny0/Calculations.dfy
+++ b/Test/dafny0/Calculations.dfy
@@ -17,10 +17,12 @@ method CalcTest0(s: seq<int>) {
}
}
assume forall x :: x in s ==> x >= 0;
- calc ==> {
+ calc {
0 < |s|;
- { assert s[0] >= 0; } // OK: well-formed after previous line
- s[0] >= 0; // OK: well-formed after previous line
+ ==> { assert s[0] >= 0; } // OK: well-formed after previous line
+ s[0] >= 0; // OK: well-formed after previous line
+ <==> { assert s[0] >= 0; } // OK: well-formed when the previous line is well-formed
+ s[0] > 0 || s[0] == 0; // OK: well-formed when the previous line is well-formed
}
}
@@ -43,7 +45,7 @@ method CalcTest2(x: int, y: int) {
}
// calc expression:
-function CalcTest(s: seq<int>): int {
+function CalcTest3(s: seq<int>): int {
calc < {
0;
{ assume |s| == 5; }