summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar rustanleino <unknown>2010-06-05 02:00:33 +0000
committerGravatar rustanleino <unknown>2010-06-05 02:00:33 +0000
commit22e67dc18705c19b617678358c8e859349938ac3 (patch)
tree7ee7efbcb76f209c97420dbd78b049d26c2e389c
parent93ac0e1e3eb6e18895087d2420b98bd8ba06443b (diff)
Dafny:
* Fixed bug in translation of well-formedness conditions * Added Test/dafny0/Celebrity.dfy * Added a harness to Test/vacid0/Composite.dfy
-rw-r--r--Dafny/Translator.ssc3
-rw-r--r--Test/dafny0/Answer6
-rw-r--r--Test/dafny0/Celebrity.dfy95
-rw-r--r--Test/dafny0/TypeParameters.dfy16
-rw-r--r--Test/dafny0/runtest.bat2
-rw-r--r--Test/vacid0/Answer2
-rw-r--r--Test/vacid0/Composite.dfy17
7 files changed, 137 insertions, 4 deletions
diff --git a/Dafny/Translator.ssc b/Dafny/Translator.ssc
index eea9d91b..092ee146 100644
--- a/Dafny/Translator.ssc
+++ b/Dafny/Translator.ssc
@@ -1303,7 +1303,8 @@ namespace Microsoft.Dafny {
substMap.Add(p, ie);
locals.Add(new Bpl.LocalVariable(local.Tok, new Bpl.TypedIdent(local.Tok, local.UniqueName, TrType(local.Type))));
Bpl.IdentifierExpr lhs = (Bpl.IdentifierExpr)etran.TrExpr(ie); // TODO: is this cast always justified?
- Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(p.tok, lhs, etran.TrExpr(e.Args[i]));
+ Expression ee = e.Args[i];
+ Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(p.tok, lhs, etran.CondApplyBox(p.tok, etran.TrExpr(ee), (!)ee.Type, p.Type));
builder.Add(cmd);
}
// check that the preconditions for the call hold
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
index 59582de8..e1b83c87 100644
--- a/Test/dafny0/Answer
+++ b/Test/dafny0/Answer
@@ -418,7 +418,7 @@ TypeParameters.dfy(63,27): Error: assertion violation
Execution trace:
(0,0): anon0
-Dafny program verifier finished with 20 verified, 2 errors
+Dafny program verifier finished with 24 verified, 2 errors
-------------------- Datatypes.dfy --------------------
@@ -443,3 +443,7 @@ Dafny program verifier finished with 12 verified, 0 errors
-------------------- Tree.dfy --------------------
Dafny program verifier finished with 6 verified, 0 errors
+
+-------------------- Celebrity.dfy --------------------
+
+Dafny program verifier finished with 11 verified, 0 errors
diff --git a/Test/dafny0/Celebrity.dfy b/Test/dafny0/Celebrity.dfy
new file mode 100644
index 00000000..fd267c71
--- /dev/null
+++ b/Test/dafny0/Celebrity.dfy
@@ -0,0 +1,95 @@
+// Celebrity example, inspired by the Rodin tutorial
+
+method Pick<T>(S: set<T>) returns (t: T);
+ requires S != {};
+ ensures t in S;
+
+static function Knows<Person>(a: Person, b: Person): bool;
+ requires a != b; // forbid asking about the reflexive case
+
+static function IsCelebrity<Person>(c: Person, people: set<Person>): bool
+{
+ c in people &&
+ (forall p :: p in people && p != c ==> Knows(p, c) && !Knows(c, p))
+}
+
+method FindCelebrity0<Person>(people: set<Person>, ghost c: Person) returns (r: Person)
+ requires (exists c :: IsCelebrity(c, people));
+ ensures r == c;
+{
+ var cc; assume cc == c; // this line essentially converts ghost c to non-ghost cc
+ r := cc;
+}
+
+method FindCelebrity1<Person>(people: set<Person>, ghost c: Person) returns (r: Person)
+ requires IsCelebrity(c, people);
+ ensures r == c;
+{
+ var Q := people;
+ call x := Pick(Q);
+ while (Q != {x})
+ //invariant Q <= people; // inv1 in Rodin's Celebrity_1, but it's not needed here
+ invariant IsCelebrity(c, Q); // inv2
+ invariant x in Q;
+ decreases Q;
+ {
+ call y := Pick(Q - {x});
+ if (Knows(x, y)) {
+ Q := Q - {x}; // remove_1
+ } else {
+ Q := Q - {y}; assert x in Q; // remove_2
+ }
+ call x := Pick(Q);
+ }
+ r := x;
+}
+
+method FindCelebrity2<Person>(people: set<Person>, ghost c: Person) returns (r: Person)
+ requires IsCelebrity(c, people);
+ ensures r == c;
+{
+ call b := Pick(people);
+ var R := people - {b};
+ while (R != {})
+ invariant R <= people; // inv1
+ invariant b in people; // inv2
+ invariant b !in R; // inv3
+ invariant IsCelebrity(c, R + {b}); // my non-refinement way of saying inv4
+
+ decreases R;
+ {
+ call x := Pick(R);
+ if (Knows(x, b)) {
+ R := R - {x};
+ } else {
+ b := x;
+ R := R - {x};
+ }
+ }
+ r := b;
+}
+
+method FindCelebrity3(n: int, people: set<int>, ghost c: int) returns (r: int)
+ requires 0 < n;
+ requires (forall p :: p in people <==> 0 <= p && p < n);
+ // requires IsCelebrity(c, people); // see next line:
+ requires c in people && (forall p :: p in people && p != c ==> Knows(p, c) && !Knows(c, p)); // hack to work around bug in Dafny-to-Boogie translator
+ ensures r == c;
+{
+ r := 0;
+ var a := 1;
+ var b := 0;
+ while (a < n)
+ invariant a <= n;
+ invariant b < a; // Celebrity_2/inv3 and Celebrity_3/inv2
+ invariant c == b || (a <= c && c < n);
+ {
+ if (Knows(a, b)) {
+ a := a + 1;
+ } else {
+ b := a;
+ a := a + 1;
+ }
+ }
+ r := b;
+}
diff --git a/Test/dafny0/TypeParameters.dfy b/Test/dafny0/TypeParameters.dfy
index 614c2185..e199a386 100644
--- a/Test/dafny0/TypeParameters.dfy
+++ b/Test/dafny0/TypeParameters.dfy
@@ -96,3 +96,19 @@ class CClient {
assert z == c.x;
}
}
+
+// -------------------------
+
+static function IsCelebrity<Person>(c: Person, people: set<Person>): bool;
+ requires c == c || c in people;
+
+method FindCelebrity3(people: set<int>, ghost c: int)
+ requires IsCelebrity(c, people);
+{
+ ghost var b: bool;
+ b := IsCelebrity(c, people);
+ b := F(c, people);
+}
+
+static function F(c: int, people: set<int>): bool;
+ requires IsCelebrity(c, people);
diff --git a/Test/dafny0/runtest.bat b/Test/dafny0/runtest.bat
index c43ea782..eb7ea4f7 100644
--- a/Test/dafny0/runtest.bat
+++ b/Test/dafny0/runtest.bat
@@ -23,7 +23,7 @@ for %%f in (TypeTests.dfy SmallTests.dfy Definedness.dfy Array.dfy
SchorrWaite.dfy Termination.dfy Use.dfy DTypes.dfy
TypeParameters.dfy Datatypes.dfy UnboundedStack.dfy
SumOfCubes.dfy TerminationDemos.dfy Substitution.dfy
- Tree.dfy) do (
+ Tree.dfy Celebrity.dfy) do (
echo.
echo -------------------- %%f --------------------
%DAFNY_EXE% /compile:0 %* %%f
diff --git a/Test/vacid0/Answer b/Test/vacid0/Answer
index 6f270f92..90bbcc78 100644
--- a/Test/vacid0/Answer
+++ b/Test/vacid0/Answer
@@ -9,4 +9,4 @@ Dafny program verifier finished with 9 verified, 0 errors
-------------------- Composite.dfy --------------------
-Dafny program verifier finished with 14 verified, 0 errors
+Dafny program verifier finished with 16 verified, 0 errors
diff --git a/Test/vacid0/Composite.dfy b/Test/vacid0/Composite.dfy
index 28074c7b..ca5f206b 100644
--- a/Test/vacid0/Composite.dfy
+++ b/Test/vacid0/Composite.dfy
@@ -83,6 +83,7 @@ class Composite {
ensures (forall c :: c in S ==> c.Valid(S));
ensures (forall c :: c in S ==> c.val == old(c.val));
ensures (forall c :: c in S && c != this ==> c.parent == old(c.parent));
+ ensures parent == null;
ensures (forall c :: c in S ==> c.left == old(c.left) || (old(c.left) == this && c.left == null));
ensures (forall c :: c in S ==> c.right == old(c.right) || (old(c.right) == this && c.right == null));
ensures Acyclic({this});
@@ -158,3 +159,19 @@ method Main()
call c2.Update(496, S);
call c0.Update(0, S);
}
+
+method Harness() {
+ var a := new Composite; call a.Init(5);
+ var b := new Composite; call b.Init(7);
+ call a.Add({a}, b, {b});
+ assert a.sum == 12;
+
+ call b.Update(17, {a,b});
+ assert a.sum == 22;
+
+ var c := new Composite; call c.Init(10);
+ call b.Add({a,b}, c, {c});
+ call b.Dislodge({a,b,c});
+ assert b.sum == 27;
+}
+