summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Dafny/Resolver.ssc8
-rw-r--r--Source/Dafny/Translator.ssc7
-rw-r--r--Test/dafny0/Answer2
-rw-r--r--Test/dafny0/Refinement.dfy78
4 files changed, 89 insertions, 6 deletions
diff --git a/Source/Dafny/Resolver.ssc b/Source/Dafny/Resolver.ssc
index 3c206066..96ae33c6 100644
--- a/Source/Dafny/Resolver.ssc
+++ b/Source/Dafny/Resolver.ssc
@@ -173,7 +173,6 @@ namespace Microsoft.Dafny {
}
decl.Refined = (ClassDecl!) a;
// TODO: copy over remaining members of a
- // TODO: extend with type parameters for refinements
}
}
@@ -469,6 +468,13 @@ namespace Microsoft.Dafny {
}
void ResolveTypeParameters(List<TypeParameter!>! tparams, bool emitErrors, TypeParameter.ParentType! parent) {
+ // push type arguments of the refined class
+ if (parent is ClassRefinementDecl) {
+ ClassDecl refined = ((ClassRefinementDecl)parent).Refined;
+ assert refined != null;
+ ResolveTypeParameters(refined.TypeArgs, false, refined);
+ }
+
// push non-duplicated type parameter names
foreach (TypeParameter tp in tparams) {
if (emitErrors) {
diff --git a/Source/Dafny/Translator.ssc b/Source/Dafny/Translator.ssc
index f6fc5142..ff88c67f 100644
--- a/Source/Dafny/Translator.ssc
+++ b/Source/Dafny/Translator.ssc
@@ -1797,12 +1797,13 @@ namespace Microsoft.Dafny {
// assume I($Heap, $Heap)
builder.Add(new Bpl.AssumeCmd(m.tok, TrCouplingInvariant(m, heap, "this", heap, that)));
- // assign input formals of m
+ // assign input formals of m (except "this")
for (int i = 0; i < m.Ins.Count; i++) {
Bpl.LocalVariable arg = new Bpl.LocalVariable(m.tok, new Bpl.TypedIdent(m.tok, m.Ins[i].UniqueName, TrType(m.Ins[i].Type)));
localVariables.Add(arg);
- assert inParams[i+1] != null;
- builder.Add(Bpl.Cmd.SimpleAssign(m.tok, new Bpl.IdentifierExpr(m.tok, arg), new Bpl.IdentifierExpr(m.tok, inParams[i+1])));
+ Bpl.Variable var = inParams[i+1];
+ assert var != null;
+ builder.Add(Bpl.Cmd.SimpleAssign(m.tok, new Bpl.IdentifierExpr(m.tok, arg), new Bpl.IdentifierExpr(m.tok, var)));
}
// call inlined m;
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
index c56c2aeb..3de8e9e9 100644
--- a/Test/dafny0/Answer
+++ b/Test/dafny0/Answer
@@ -450,4 +450,4 @@ Dafny program verifier finished with 5 verified, 0 errors
-------------------- Refinement.dfy --------------------
-Dafny program verifier finished with 39 verified, 0 errors
+Dafny program verifier finished with 54 verified, 0 errors
diff --git a/Test/dafny0/Refinement.dfy b/Test/dafny0/Refinement.dfy
index c70df916..205f3b6c 100644
--- a/Test/dafny0/Refinement.dfy
+++ b/Test/dafny0/Refinement.dfy
@@ -1,5 +1,5 @@
// Concrete language syntax for a Dafny extension with refinement.
-// Counter example.
+// IntegerCounter example.
// 6/28/2010
class A {
@@ -112,6 +112,82 @@ class CCalc refines ACalc {
}
}
+// Sequence refined to a singly linked list
+// 6/22/2010: Kuat Yessenov
+
+class List<T> {
+ var rep: seq<T>;
+ method Clear()
+ modifies this;
+ {
+ rep := [];
+ }
+
+ method Append(x: T)
+ modifies this;
+ {
+ rep := rep + [x];
+ }
+
+ method Prepend(x: T)
+ modifies this;
+ {
+ rep := [x] + rep;
+ }
+
+ method Insert(i: int, x: T)
+ requires 0 <= i && i < |rep|;
+ modifies this;
+ {
+ rep := rep[i:=x];
+ }
+}
+
+class Node<T> {
+ var data: T;
+ var next: Node<T>;
+}
+
+class LinkedList refines List {
+ var first: Node<T>;
+ ghost var nodes: set<Node<T>>;
+
+ function Abstraction(n: Node<T>, nodes: set<Node<T>>, rep: seq<T>) : bool
+ decreases nodes;
+ reads n, nodes;
+ {
+ if (n == null) then
+ rep == [] &&
+ nodes == {}
+ else
+ |rep| >= 1 &&
+ n.data == rep[0] &&
+ n in nodes &&
+ n.next in nodes + {null} &&
+ Abstraction(n.next, nodes - {n}, rep[1..])
+ }
+
+ replaces rep by Abstraction(first, nodes, rep);
+
+ refines Clear()
+ modifies this;
+ {
+ first := null;
+ nodes := {};
+ }
+
+ refines Prepend(x: T)
+ modifies this;
+ {
+ var n := new Node<T>;
+ n.data := x;
+ n.next := first;
+ first := n;
+ nodes := {n} + nodes;
+ assert nodes - {n} == old(nodes); //set extensionality
+ }
+}
+