summaryrefslogtreecommitdiff
path: root/Test/dafny0/LhsDuplicates.dfy
diff options
context:
space:
mode:
authorGravatar leino <unknown>2014-10-30 15:12:31 -0700
committerGravatar leino <unknown>2014-10-30 15:12:31 -0700
commit9f41b35b514eba87a037cbada83f0c294eafb936 (patch)
tree06b875a433e0ca8ca80dc41cc7ed34bbef5514b8 /Test/dafny0/LhsDuplicates.dfy
parentc612305e78f057b9d1e91a0d154989cb866a7906 (diff)
Allow assignment LHSs in a forall statement to be the same, so long as the they are assigned the same RHS value.
Don't include havoc assignments in LHS-duplicate checks.
Diffstat (limited to 'Test/dafny0/LhsDuplicates.dfy')
-rw-r--r--Test/dafny0/LhsDuplicates.dfy70
1 files changed, 70 insertions, 0 deletions
diff --git a/Test/dafny0/LhsDuplicates.dfy b/Test/dafny0/LhsDuplicates.dfy
new file mode 100644
index 00000000..6a84c5a5
--- /dev/null
+++ b/Test/dafny0/LhsDuplicates.dfy
@@ -0,0 +1,70 @@
+// RUN: %dafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t"
+// RUN: %diff "%s.expect" "%t"
+
+class MyClass<T> {
+ var f: T;
+}
+
+method M<T>()
+{
+ var a, b := new T[100], new T[100];
+ forall i | 0 <= i < 100 {
+ a[3] := *; // RHS is * -- this is okay
+ }
+ forall i | 0 <= i < 100 {
+ a[0] := b[0]; // RHSs are the same -- this is okay
+ }
+ forall i | 0 <= i < 100 {
+ a[0] := b[i]; // error: LHS's may be the same (while RHSs are different)
+ }
+}
+
+method N<T>(a: MyClass<T>, b: MyClass<T>)
+ requires a != null && b != null;
+ modifies a, b;
+{
+ var q := [a, b];
+ forall i | 0 <= i < 2 {
+ q[0].f := *; // RHS is * -- this is okay
+ }
+ forall i | 0 <= i < 2 {
+ q[0].f := q[0].f; // RHSs are the same -- this is okay
+ }
+ forall i | 0 <= i < 2 {
+ q[0].f := q[i].f; // error: LHS's may be the same (while RHSs are different)
+ }
+}
+
+method P<T>(t0: T, t1: T, t2: T) {
+ var a: T, b: T;
+ a, a, a := *, t0, *; // only one non-* RHS per variable -- this is okay
+ a, a, b, a, b := *, t1, t2, *, *; // only one non-* RHS per variable -- this is okay
+ a, a, b, a, b := *, t1, t2, t0, *; // error: duplicate LHS -- t0 and t1 may be different
+}
+
+method Q<T>(c0: MyClass<T>, c1: MyClass<T>)
+ requires c0 != null && c1 != null;
+ modifies c0, c1;
+{
+ c0.f, c1.f := c0.f, c0.f; // okay -- RHSs are the same
+ c0.f, c0.f, c0.f, c0.f := *, *, c1.f, *; // okay -- only one RHS is non-*
+ c0.f, c0.f, c0.f, c0.f := c0.f, *, c1.f, *; // error -- duplicate LHR
+}
+
+method R<T>(i: nat, j: nat)
+ requires i < 10 && j < 10;
+{
+ var a := new T[10];
+ a[i], a[j] := a[5], a[5]; // okay -- RHSs are the same
+ a[i], a[i], a[i], a[i] := *, *, a[5], *; // okay -- only one RHS is non-*
+ a[i], a[i], a[i], a[j] := *, a[i], a[j], a[i]; // error -- possible duplicate LHS
+}
+
+method S<T>(i: nat, j: nat)
+ requires i < 10 && j < 20;
+{
+ var a := new T[10,20];
+ a[i,j], a[i,i] := a[5,7], a[5,7]; // okay -- RHSs are the same
+ a[i,j], a[i,j], a[i,j], a[i,j] := *, *, a[5,7], *; // okay -- only one RHS is non-*
+ a[i,j], a[i,j], a[i,j], a[i,i] := *, a[i,i], a[i,j], a[i,i]; // error -- possible duplicate LHS
+}