summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Rustan Leino <unknown>2013-03-05 17:01:25 -0800
committerGravatar Rustan Leino <unknown>2013-03-05 17:01:25 -0800
commit9f7c11c0a12a9b802f23d613abeee91a2fb47743 (patch)
treeff0c5ffd982094c5d03828f1332be03a4d66b4ea
parentc819fabbb8da669952cb7e2e5937c73ff6dcfabe (diff)
Removed Dafny, Jennisys, Chalice, and BCT, which now live in different Codeplex repositories.
-rw-r--r--Binaries/DafnyPrelude.bpl649
-rw-r--r--Binaries/DafnyRuntime.cs574
-rw-r--r--Test/VSComp2010/Answer20
-rw-r--r--Test/VSComp2010/Problem1-SumMax.dfy43
-rw-r--r--Test/VSComp2010/Problem2-Invert.dfy80
-rw-r--r--Test/VSComp2010/Problem3-FindZero.dfy92
-rw-r--r--Test/VSComp2010/Problem4-Queens.dfy154
-rw-r--r--Test/VSComp2010/Problem5-DoubleEndedQueue.dfy163
-rw-r--r--Test/VSComp2010/runtest.bat13
-rw-r--r--Test/VSI-Benchmarks/Answer32
-rw-r--r--Test/VSI-Benchmarks/b1.dfy71
-rw-r--r--Test/VSI-Benchmarks/b2.dfy57
-rw-r--r--Test/VSI-Benchmarks/b3.dfy136
-rw-r--r--Test/VSI-Benchmarks/b4.dfy158
-rw-r--r--Test/VSI-Benchmarks/b5.dfy199
-rw-r--r--Test/VSI-Benchmarks/b6.dfy135
-rw-r--r--Test/VSI-Benchmarks/b7.dfy152
-rw-r--r--Test/VSI-Benchmarks/b8.dfy352
-rw-r--r--Test/VSI-Benchmarks/runtest.bat11
-rw-r--r--Test/dafny0/AdvancedLHS.dfy58
-rw-r--r--Test/dafny0/Answer2098
-rw-r--r--Test/dafny0/Array.dfy255
-rw-r--r--Test/dafny0/BadFunction.dfy13
-rw-r--r--Test/dafny0/Basics.dfy242
-rw-r--r--Test/dafny0/Calculations.dfy37
-rw-r--r--Test/dafny0/CallStmtTests.dfy21
-rw-r--r--Test/dafny0/ChainingDisjointTests.dfy33
-rw-r--r--Test/dafny0/CoPredicates.dfy59
-rw-r--r--Test/dafny0/Coinductive.dfy106
-rw-r--r--Test/dafny0/Compilation.dfy111
-rw-r--r--Test/dafny0/Comprehensions.dfy43
-rw-r--r--Test/dafny0/ControlStructures.dfy239
-rw-r--r--Test/dafny0/Corecursion.dfy52
-rw-r--r--Test/dafny0/DTypes.dfy156
-rw-r--r--Test/dafny0/Datatypes.dfy249
-rw-r--r--Test/dafny0/Definedness.dfy240
-rw-r--r--Test/dafny0/EqualityTypes.dfy89
-rw-r--r--Test/dafny0/FunctionSpecifications.dfy60
-rw-r--r--Test/dafny0/IteratorResolution.dfy138
-rw-r--r--Test/dafny0/Iterators.dfy235
-rw-r--r--Test/dafny0/LetExpr.dfy149
-rw-r--r--Test/dafny0/LiberalEquality.dfy55
-rw-r--r--Test/dafny0/LoopModifies.dfy318
-rw-r--r--Test/dafny0/Maps.dfy192
-rw-r--r--Test/dafny0/Modules0.dfy322
-rw-r--r--Test/dafny0/Modules1.dfy114
-rw-r--r--Test/dafny0/Modules2.dfy57
-rw-r--r--Test/dafny0/ModulesCycle.dfy12
-rw-r--r--Test/dafny0/MultiDimArray.dfy91
-rw-r--r--Test/dafny0/MultiSets.dfy103
-rw-r--r--Test/dafny0/NatTypes.dfy137
-rw-r--r--Test/dafny0/NoTypeArgs.dfy82
-rw-r--r--Test/dafny0/NonGhostQuantifiers.dfy191
-rw-r--r--Test/dafny0/Parallel.dfy308
-rw-r--r--Test/dafny0/ParallelResolveErrors.dfy108
-rw-r--r--Test/dafny0/ParseErrors.dfy78
-rw-r--r--Test/dafny0/PredExpr.dfy79
-rw-r--r--Test/dafny0/Predicates.dfy182
-rw-r--r--Test/dafny0/Refinement.dfy193
-rw-r--r--Test/dafny0/RefinementErrors.dfy58
-rw-r--r--Test/dafny0/RefinementModificationChecking.dfy23
-rw-r--r--Test/dafny0/ResolutionErrors.dfy385
-rw-r--r--Test/dafny0/ReturnErrors.dfy42
-rw-r--r--Test/dafny0/ReturnTests.dfy59
-rw-r--r--Test/dafny0/Simple.dfy52
-rw-r--r--Test/dafny0/Skeletons.dfy63
-rw-r--r--Test/dafny0/SmallTests.dfy589
-rw-r--r--Test/dafny0/SplitExpr.dfy56
-rw-r--r--Test/dafny0/Superposition.dfy56
-rw-r--r--Test/dafny0/TailCalls.dfy74
-rw-r--r--Test/dafny0/Termination.dfy331
-rw-r--r--Test/dafny0/TypeAntecedents.dfy97
-rw-r--r--Test/dafny0/TypeParameters.dfy191
-rw-r--r--Test/dafny0/TypeTests.dfy120
-rw-r--r--Test/dafny0/runtest.bat46
-rw-r--r--Test/dafny1/Answer124
-rw-r--r--Test/dafny1/BDD.dfy60
-rw-r--r--Test/dafny1/BinaryTree.dfy243
-rw-r--r--Test/dafny1/Celebrity.dfy90
-rw-r--r--Test/dafny1/Cubes.dfy23
-rw-r--r--Test/dafny1/ExtensibleArray.dfy126
-rw-r--r--Test/dafny1/ExtensibleArrayAuto.dfy113
-rw-r--r--Test/dafny1/FindZero.dfy76
-rw-r--r--Test/dafny1/Induction.dfy202
-rw-r--r--Test/dafny1/KatzManna.dfy76
-rw-r--r--Test/dafny1/ListContents.dfy91
-rw-r--r--Test/dafny1/ListCopy.dfy53
-rw-r--r--Test/dafny1/ListReverse.dfy27
-rw-r--r--Test/dafny1/MatrixFun.dfy98
-rw-r--r--Test/dafny1/MoreInduction.dfy97
-rw-r--r--Test/dafny1/PriorityQueue.dfy221
-rw-r--r--Test/dafny1/Queue.dfy199
-rw-r--r--Test/dafny1/Rippling.dfy617
-rw-r--r--Test/dafny1/SchorrWaite-stages.dfy267
-rw-r--r--Test/dafny1/SchorrWaite.dfy270
-rw-r--r--Test/dafny1/SeparationLogicList.dfy169
-rw-r--r--Test/dafny1/Substitution.dfy107
-rw-r--r--Test/dafny1/SumOfCubes.dfy104
-rw-r--r--Test/dafny1/TerminationDemos.dfy111
-rw-r--r--Test/dafny1/TreeDatatype.dfy90
-rw-r--r--Test/dafny1/UltraFilter.dfy108
-rw-r--r--Test/dafny1/UnboundedStack.dfy96
-rw-r--r--Test/dafny1/pow2.dfy54
-rw-r--r--Test/dafny1/runtest.bat23
-rw-r--r--Test/dafny2/Answer60
-rw-r--r--Test/dafny2/COST-verif-comp-2011-1-MaxArray.dfy79
-rw-r--r--Test/dafny2/COST-verif-comp-2011-2-MaxTree-class.dfy133
-rw-r--r--Test/dafny2/COST-verif-comp-2011-2-MaxTree-datatype.dfy65
-rw-r--r--Test/dafny2/COST-verif-comp-2011-3-TwoDuplicates.dfy118
-rw-r--r--Test/dafny2/COST-verif-comp-2011-4-FloydCycleDetect.dfy404
-rw-r--r--Test/dafny2/Calculations.dfy209
-rw-r--r--Test/dafny2/Classics.dfy103
-rw-r--r--Test/dafny2/Intervals.dfy63
-rw-r--r--Test/dafny2/MajorityVote.dfy175
-rw-r--r--Test/dafny2/MonotonicHeapstate.dfy143
-rw-r--r--Test/dafny2/SegmentSum.dfy29
-rw-r--r--Test/dafny2/SnapshotableTrees.dfy480
-rw-r--r--Test/dafny2/StoreAndRetrieve.dfy76
-rw-r--r--Test/dafny2/TreeBarrier.dfy143
-rw-r--r--Test/dafny2/TreeFill.dfy27
-rw-r--r--Test/dafny2/TuringFactorial.dfy26
-rw-r--r--Test/dafny2/runtest.bat24
-rw-r--r--Test/dafnytests.txt7
-rw-r--r--Test/jennisys0/Answer90
-rw-r--r--Test/jennisys0/ExtensibleArray.jen40
-rw-r--r--Test/jennisys0/Prog0.jen35
-rw-r--r--Test/jennisys0/runtest.bat10
-rw-r--r--Test/runtestdafny.bat8
-rw-r--r--Test/vacid0/Answer12
-rw-r--r--Test/vacid0/AnswerRuntimeChecking0
-rw-r--r--Test/vacid0/Composite.dfy172
-rw-r--r--Test/vacid0/LazyInitArray.dfy105
-rw-r--r--Test/vacid0/SparseArray.dfy116
-rw-r--r--Test/vacid0/runtest.bat11
-rw-r--r--Test/vstte2012/Answer24
-rw-r--r--Test/vstte2012/BreadthFirstSearch.dfy276
-rw-r--r--Test/vstte2012/Combinators.dfy459
-rw-r--r--Test/vstte2012/RingBuffer.dfy93
-rw-r--r--Test/vstte2012/RingBufferAuto.dfy75
-rw-r--r--Test/vstte2012/Tree.dfy172
-rw-r--r--Test/vstte2012/Two-Way-Sort.dfy58
-rw-r--r--Test/vstte2012/runtest.bat17
142 files changed, 0 insertions, 20710 deletions
diff --git a/Binaries/DafnyPrelude.bpl b/Binaries/DafnyPrelude.bpl
deleted file mode 100644
index 342b72c1..00000000
--- a/Binaries/DafnyPrelude.bpl
+++ /dev/null
@@ -1,649 +0,0 @@
-// Dafny prelude
-// Created 9 February 2008 by Rustan Leino.
-// Converted to Boogie 2 on 28 June 2008.
-// Edited sequence axioms 20 October 2009 by Alex Summers.
-// Copyright (c) 2008-2010, Microsoft.
-
-const $$Language$Dafny: bool; // To be recognizable to the ModelViewer as
-axiom $$Language$Dafny; // coming from a Dafny program.
-
-// ---------------------------------------------------------------
-// -- References -------------------------------------------------
-// ---------------------------------------------------------------
-
-type ref;
-const null: ref;
-
-// ---------------------------------------------------------------
-// -- Axiomatization of sets -------------------------------------
-// ---------------------------------------------------------------
-
-type Set T = [T]bool;
-
-function Set#Empty<T>(): Set T;
-axiom (forall<T> o: T :: { Set#Empty()[o] } !Set#Empty()[o]);
-
-function Set#Singleton<T>(T): Set T;
-axiom (forall<T> r: T :: { Set#Singleton(r) } Set#Singleton(r)[r]);
-axiom (forall<T> r: T, o: T :: { Set#Singleton(r)[o] } Set#Singleton(r)[o] <==> r == o);
-
-function Set#UnionOne<T>(Set T, T): Set T;
-axiom (forall<T> a: Set T, x: T, o: T :: { Set#UnionOne(a,x)[o] }
- Set#UnionOne(a,x)[o] <==> o == x || a[o]);
-axiom (forall<T> a: Set T, x: T :: { Set#UnionOne(a, x) }
- Set#UnionOne(a, x)[x]);
-axiom (forall<T> a: Set T, x: T, y: T :: { Set#UnionOne(a, x), a[y] }
- a[y] ==> Set#UnionOne(a, x)[y]);
-
-function Set#Union<T>(Set T, Set T): Set T;
-axiom (forall<T> a: Set T, b: Set T, o: T :: { Set#Union(a,b)[o] }
- Set#Union(a,b)[o] <==> a[o] || b[o]);
-axiom (forall<T> a, b: Set T, y: T :: { Set#Union(a, b), a[y] }
- a[y] ==> Set#Union(a, b)[y]);
-axiom (forall<T> a, b: Set T, y: T :: { Set#Union(a, b), b[y] }
- b[y] ==> Set#Union(a, b)[y]);
-axiom (forall<T> a, b: Set T :: { Set#Union(a, b) }
- Set#Disjoint(a, b) ==>
- Set#Difference(Set#Union(a, b), a) == b &&
- Set#Difference(Set#Union(a, b), b) == a);
-
-function Set#Intersection<T>(Set T, Set T): Set T;
-axiom (forall<T> a: Set T, b: Set T, o: T :: { Set#Intersection(a,b)[o] }
- Set#Intersection(a,b)[o] <==> a[o] && b[o]);
-
-axiom (forall<T> a, b: Set T :: { Set#Union(Set#Union(a, b), b) }
- Set#Union(Set#Union(a, b), b) == Set#Union(a, b));
-axiom (forall<T> a, b: Set T :: { Set#Union(a, Set#Union(a, b)) }
- Set#Union(a, Set#Union(a, b)) == Set#Union(a, b));
-axiom (forall<T> a, b: Set T :: { Set#Intersection(Set#Intersection(a, b), b) }
- Set#Intersection(Set#Intersection(a, b), b) == Set#Intersection(a, b));
-axiom (forall<T> a, b: Set T :: { Set#Intersection(a, Set#Intersection(a, b)) }
- Set#Intersection(a, Set#Intersection(a, b)) == Set#Intersection(a, b));
-
-function Set#Difference<T>(Set T, Set T): Set T;
-axiom (forall<T> a: Set T, b: Set T, o: T :: { Set#Difference(a,b)[o] }
- Set#Difference(a,b)[o] <==> a[o] && !b[o]);
-axiom (forall<T> a, b: Set T, y: T :: { Set#Difference(a, b), b[y] }
- b[y] ==> !Set#Difference(a, b)[y] );
-
-function Set#Subset<T>(Set T, Set T): bool;
-axiom(forall<T> a: Set T, b: Set T :: { Set#Subset(a,b) }
- Set#Subset(a,b) <==> (forall o: T :: {a[o]} {b[o]} a[o] ==> b[o]));
-
-function Set#Equal<T>(Set T, Set T): bool;
-axiom(forall<T> a: Set T, b: Set T :: { Set#Equal(a,b) }
- Set#Equal(a,b) <==> (forall o: T :: {a[o]} {b[o]} a[o] <==> b[o]));
-axiom(forall<T> a: Set T, b: Set T :: { Set#Equal(a,b) } // extensionality axiom for sets
- Set#Equal(a,b) ==> a == b);
-
-function Set#Disjoint<T>(Set T, Set T): bool;
-axiom (forall<T> a: Set T, b: Set T :: { Set#Disjoint(a,b) }
- Set#Disjoint(a,b) <==> (forall o: T :: {a[o]} {b[o]} !a[o] || !b[o]));
-
-function Set#Choose<T>(Set T, TickType): T;
-axiom (forall<T> a: Set T, tick: TickType :: { Set#Choose(a, tick) }
- a != Set#Empty() ==> a[Set#Choose(a, tick)]);
-
-
-// ---------------------------------------------------------------
-// -- Axiomatization of multisets --------------------------------
-// ---------------------------------------------------------------
-
-function Math#min(a: int, b: int): int;
-axiom (forall a: int, b: int :: { Math#min(a, b) } a <= b <==> Math#min(a, b) == a);
-axiom (forall a: int, b: int :: { Math#min(a, b) } b <= a <==> Math#min(a, b) == b);
-axiom (forall a: int, b: int :: { Math#min(a, b) } Math#min(a, b) == a || Math#min(a, b) == b);
-
-function Math#clip(a: int): int;
-axiom (forall a: int :: { Math#clip(a) } 0 <= a ==> Math#clip(a) == a);
-axiom (forall a: int :: { Math#clip(a) } a < 0 ==> Math#clip(a) == 0);
-
-type MultiSet T = [T]int;
-
-function $IsGoodMultiSet<T>(ms: MultiSet T): bool;
-// ints are non-negative, used after havocing, and for conversion from sequences to multisets.
-axiom (forall<T> ms: MultiSet T :: { $IsGoodMultiSet(ms) }
- $IsGoodMultiSet(ms) <==> (forall o: T :: { ms[o] } 0 <= ms[o]));
-
-function MultiSet#Empty<T>(): MultiSet T;
-axiom (forall<T> o: T :: { MultiSet#Empty()[o] } MultiSet#Empty()[o] == 0);
-
-function MultiSet#Singleton<T>(T): MultiSet T;
-axiom (forall<T> r: T, o: T :: { MultiSet#Singleton(r)[o] } (MultiSet#Singleton(r)[o] == 1 <==> r == o) &&
- (MultiSet#Singleton(r)[o] == 0 <==> r != o));
-axiom (forall<T> r: T :: { MultiSet#Singleton(r) } MultiSet#Singleton(r) == MultiSet#UnionOne(MultiSet#Empty(), r));
-
-function MultiSet#UnionOne<T>(MultiSet T, T): MultiSet T;
-// pure containment axiom (in the original multiset or is the added element)
-axiom (forall<T> a: MultiSet T, x: T, o: T :: { MultiSet#UnionOne(a,x)[o] }
- 0 < MultiSet#UnionOne(a,x)[o] <==> o == x || 0 < a[o]);
-// union-ing increases count by one
-axiom (forall<T> a: MultiSet T, x: T :: { MultiSet#UnionOne(a, x) }
- MultiSet#UnionOne(a, x)[x] == a[x] + 1);
-// non-decreasing
-axiom (forall<T> a: MultiSet T, x: T, y: T :: { MultiSet#UnionOne(a, x), a[y] }
- 0 < a[y] ==> 0 < MultiSet#UnionOne(a, x)[y]);
-// other elements unchanged
-axiom (forall<T> a: MultiSet T, x: T, y: T :: { MultiSet#UnionOne(a, x), a[y] }
- x != y ==> a[y] == MultiSet#UnionOne(a, x)[y]);
-
-function MultiSet#Union<T>(MultiSet T, MultiSet T): MultiSet T;
-// union-ing is the sum of the contents
-axiom (forall<T> a: MultiSet T, b: MultiSet T, o: T :: { MultiSet#Union(a,b)[o] }
- MultiSet#Union(a,b)[o] == a[o] + b[o]);
-
-// two containment axioms
-axiom (forall<T> a, b: MultiSet T, y: T :: { MultiSet#Union(a, b), a[y] }
- 0 < a[y] ==> 0 < MultiSet#Union(a, b)[y]);
-axiom (forall<T> a, b: MultiSet T, y: T :: { MultiSet#Union(a, b), b[y] }
- 0 < b[y] ==> 0 < MultiSet#Union(a, b)[y]);
-
-// symmetry axiom
-axiom (forall<T> a, b: MultiSet T :: { MultiSet#Union(a, b) }
- MultiSet#Difference(MultiSet#Union(a, b), a) == b &&
- MultiSet#Difference(MultiSet#Union(a, b), b) == a);
-
-function MultiSet#Intersection<T>(MultiSet T, MultiSet T): MultiSet T;
-axiom (forall<T> a: MultiSet T, b: MultiSet T, o: T :: { MultiSet#Intersection(a,b)[o] }
- MultiSet#Intersection(a,b)[o] == Math#min(a[o], b[o]));
-
-// left and right pseudo-idempotence
-axiom (forall<T> a, b: MultiSet T :: { MultiSet#Intersection(MultiSet#Intersection(a, b), b) }
- MultiSet#Intersection(MultiSet#Intersection(a, b), b) == MultiSet#Intersection(a, b));
-axiom (forall<T> a, b: MultiSet T :: { MultiSet#Intersection(a, MultiSet#Intersection(a, b)) }
- MultiSet#Intersection(a, MultiSet#Intersection(a, b)) == MultiSet#Intersection(a, b));
-
-// multiset difference, a - b. clip() makes it positive.
-function MultiSet#Difference<T>(MultiSet T, MultiSet T): MultiSet T;
-axiom (forall<T> a: MultiSet T, b: MultiSet T, o: T :: { MultiSet#Difference(a,b)[o] }
- MultiSet#Difference(a,b)[o] == Math#clip(a[o] - b[o]));
-axiom (forall<T> a, b: MultiSet T, y: T :: { MultiSet#Difference(a, b), b[y], a[y] }
- a[y] <= b[y] ==> MultiSet#Difference(a, b)[y] == 0 );
-
-// multiset subset means a must have at most as many of each element as b
-function MultiSet#Subset<T>(MultiSet T, MultiSet T): bool;
-axiom(forall<T> a: MultiSet T, b: MultiSet T :: { MultiSet#Subset(a,b) }
- MultiSet#Subset(a,b) <==> (forall o: T :: {a[o]} {b[o]} a[o] <= b[o]));
-
-function MultiSet#Equal<T>(MultiSet T, MultiSet T): bool;
-axiom(forall<T> a: MultiSet T, b: MultiSet T :: { MultiSet#Equal(a,b) }
- MultiSet#Equal(a,b) <==> (forall o: T :: {a[o]} {b[o]} a[o] == b[o]));
-// extensionality axiom for multisets
-axiom(forall<T> a: MultiSet T, b: MultiSet T :: { MultiSet#Equal(a,b) }
- MultiSet#Equal(a,b) ==> a == b);
-
-function MultiSet#Disjoint<T>(MultiSet T, MultiSet T): bool;
-axiom (forall<T> a: MultiSet T, b: MultiSet T :: { MultiSet#Disjoint(a,b) }
- MultiSet#Disjoint(a,b) <==> (forall o: T :: {a[o]} {b[o]} a[o] == 0 || b[o] == 0));
-
-// conversion to a multiset. each element in the original set has duplicity 1.
-function MultiSet#FromSet<T>(Set T): MultiSet T;
-axiom (forall<T> s: Set T, a: T :: { MultiSet#FromSet(s)[a] }
- (MultiSet#FromSet(s)[a] == 0 <==> !s[a]) &&
- (MultiSet#FromSet(s)[a] == 1 <==> s[a]));
-
-// conversion to a multiset, from a sequence.
-function MultiSet#FromSeq<T>(Seq T): MultiSet T;
-// conversion produces a good map.
-axiom (forall<T> s: Seq T :: { MultiSet#FromSeq(s) } $IsGoodMultiSet(MultiSet#FromSeq(s)) );
-// building axiom
-axiom (forall<T> s: Seq T, v: T ::
- { MultiSet#FromSeq(Seq#Build(s, v)) }
- MultiSet#FromSeq(Seq#Build(s, v)) == MultiSet#UnionOne(MultiSet#FromSeq(s), v)
- );
-axiom (forall<T> :: MultiSet#FromSeq(Seq#Empty(): Seq T) == MultiSet#Empty(): MultiSet T);
-
-// concatenation axiom
-axiom (forall<T> a: Seq T, b: Seq T ::
- { MultiSet#FromSeq(Seq#Append(a, b)) }
- MultiSet#FromSeq(Seq#Append(a, b)) == MultiSet#Union(MultiSet#FromSeq(a), MultiSet#FromSeq(b)) );
-
-// update axiom
-axiom (forall<T> s: Seq T, i: int, v: T, x: T ::
- { MultiSet#FromSeq(Seq#Update(s, i, v))[x] }
- 0 <= i && i < Seq#Length(s) ==>
- MultiSet#FromSeq(Seq#Update(s, i, v))[x] ==
- MultiSet#Union(MultiSet#Difference(MultiSet#FromSeq(s), MultiSet#Singleton(Seq#Index(s,i))), MultiSet#Singleton(v))[x] );
- // i.e. MS(Update(s, i, v)) == MS(s) - {{s[i]}} + {{v}}
-axiom (forall<T> s: Seq T, x: T :: { MultiSet#FromSeq(s)[x] }
- (exists i : int :: { Seq#Index(s,i) } 0 <= i && i < Seq#Length(s) && x == Seq#Index(s,i)) <==> 0 < MultiSet#FromSeq(s)[x] );
-
-// ---------------------------------------------------------------
-// -- Axiomatization of sequences --------------------------------
-// ---------------------------------------------------------------
-
-type Seq T;
-
-function Seq#Length<T>(Seq T): int;
-axiom (forall<T> s: Seq T :: { Seq#Length(s) } 0 <= Seq#Length(s));
-
-function Seq#Empty<T>(): Seq T;
-axiom (forall<T> :: Seq#Length(Seq#Empty(): Seq T) == 0);
-axiom (forall<T> s: Seq T :: { Seq#Length(s) } Seq#Length(s) == 0 ==> s == Seq#Empty());
-
-function Seq#Singleton<T>(T): Seq T;
-axiom (forall<T> t: T :: { Seq#Length(Seq#Singleton(t)) } Seq#Length(Seq#Singleton(t)) == 1);
-
-function Seq#Build<T>(s: Seq T, val: T): Seq T;
-axiom (forall<T> s: Seq T, v: T :: { Seq#Length(Seq#Build(s,v)) }
- Seq#Length(Seq#Build(s,v)) == 1 + Seq#Length(s));
-axiom (forall<T> s: Seq T, i: int, v: T :: { Seq#Index(Seq#Build(s,v), i) }
- (i == Seq#Length(s) ==> Seq#Index(Seq#Build(s,v), i) == v) &&
- (i != Seq#Length(s) ==> Seq#Index(Seq#Build(s,v), i) == Seq#Index(s, i)));
-
-function Seq#Append<T>(Seq T, Seq T): Seq T;
-axiom (forall<T> s0: Seq T, s1: Seq T :: { Seq#Length(Seq#Append(s0,s1)) }
- Seq#Length(Seq#Append(s0,s1)) == Seq#Length(s0) + Seq#Length(s1));
-
-function Seq#Index<T>(Seq T, int): T;
-axiom (forall<T> t: T :: { Seq#Index(Seq#Singleton(t), 0) } Seq#Index(Seq#Singleton(t), 0) == t);
-axiom (forall<T> s0: Seq T, s1: Seq T, n: int :: { Seq#Index(Seq#Append(s0,s1), n) }
- (n < Seq#Length(s0) ==> Seq#Index(Seq#Append(s0,s1), n) == Seq#Index(s0, n)) &&
- (Seq#Length(s0) <= n ==> Seq#Index(Seq#Append(s0,s1), n) == Seq#Index(s1, n - Seq#Length(s0))));
-
-function Seq#Update<T>(Seq T, int, T): Seq T;
-axiom (forall<T> s: Seq T, i: int, v: T :: { Seq#Length(Seq#Update(s,i,v)) }
- 0 <= i && i < Seq#Length(s) ==> Seq#Length(Seq#Update(s,i,v)) == Seq#Length(s));
-axiom (forall<T> s: Seq T, i: int, v: T, n: int :: { Seq#Index(Seq#Update(s,i,v),n) }
- 0 <= n && n < Seq#Length(s) ==>
- (i == n ==> Seq#Index(Seq#Update(s,i,v),n) == v) &&
- (i != n ==> Seq#Index(Seq#Update(s,i,v),n) == Seq#Index(s,n)));
-
-function Seq#Contains<T>(Seq T, T): bool;
-axiom (forall<T> s: Seq T, x: T :: { Seq#Contains(s,x) }
- Seq#Contains(s,x) <==>
- (exists i: int :: { Seq#Index(s,i) } 0 <= i && i < Seq#Length(s) && Seq#Index(s,i) == x));
-axiom (forall x: ref ::
- { Seq#Contains(Seq#Empty(), x) }
- !Seq#Contains(Seq#Empty(), x));
-axiom (forall<T> s0: Seq T, s1: Seq T, x: T ::
- { Seq#Contains(Seq#Append(s0, s1), x) }
- Seq#Contains(Seq#Append(s0, s1), x) <==>
- Seq#Contains(s0, x) || Seq#Contains(s1, x));
-
-axiom (forall<T> s: Seq T, v: T, x: T ::
- { Seq#Contains(Seq#Build(s, v), x) }
- Seq#Contains(Seq#Build(s, v), x) <==> (v == x || Seq#Contains(s, x)));
-
-axiom (forall<T> s: Seq T, n: int, x: T ::
- { Seq#Contains(Seq#Take(s, n), x) }
- Seq#Contains(Seq#Take(s, n), x) <==>
- (exists i: int :: { Seq#Index(s, i) }
- 0 <= i && i < n && i < Seq#Length(s) && Seq#Index(s, i) == x));
-axiom (forall<T> s: Seq T, n: int, x: T ::
- { Seq#Contains(Seq#Drop(s, n), x) }
- Seq#Contains(Seq#Drop(s, n), x) <==>
- (exists i: int :: { Seq#Index(s, i) }
- 0 <= n && n <= i && i < Seq#Length(s) && Seq#Index(s, i) == x));
-
-function Seq#Equal<T>(Seq T, Seq T): bool;
-axiom (forall<T> s0: Seq T, s1: Seq T :: { Seq#Equal(s0,s1) }
- Seq#Equal(s0,s1) <==>
- Seq#Length(s0) == Seq#Length(s1) &&
- (forall j: int :: { Seq#Index(s0,j) } { Seq#Index(s1,j) }
- 0 <= j && j < Seq#Length(s0) ==> Seq#Index(s0,j) == Seq#Index(s1,j)));
-axiom (forall<T> a: Seq T, b: Seq T :: { Seq#Equal(a,b) } // extensionality axiom for sequences
- Seq#Equal(a,b) ==> a == b);
-
-function Seq#SameUntil<T>(Seq T, Seq T, int): bool;
-axiom (forall<T> s0: Seq T, s1: Seq T, n: int :: { Seq#SameUntil(s0,s1,n) }
- Seq#SameUntil(s0,s1,n) <==>
- (forall j: int :: { Seq#Index(s0,j) } { Seq#Index(s1,j) }
- 0 <= j && j < n ==> Seq#Index(s0,j) == Seq#Index(s1,j)));
-
-function Seq#Take<T>(s: Seq T, howMany: int): Seq T;
-axiom (forall<T> s: Seq T, n: int :: { Seq#Length(Seq#Take(s,n)) }
- 0 <= n ==>
- (n <= Seq#Length(s) ==> Seq#Length(Seq#Take(s,n)) == n) &&
- (Seq#Length(s) < n ==> Seq#Length(Seq#Take(s,n)) == Seq#Length(s)));
-axiom (forall<T> s: Seq T, n: int, j: int :: { Seq#Index(Seq#Take(s,n), j) } {:weight 25}
- 0 <= j && j < n && j < Seq#Length(s) ==>
- Seq#Index(Seq#Take(s,n), j) == Seq#Index(s, j));
-
-function Seq#Drop<T>(s: Seq T, howMany: int): Seq T;
-axiom (forall<T> s: Seq T, n: int :: { Seq#Length(Seq#Drop(s,n)) }
- 0 <= n ==>
- (n <= Seq#Length(s) ==> Seq#Length(Seq#Drop(s,n)) == Seq#Length(s) - n) &&
- (Seq#Length(s) < n ==> Seq#Length(Seq#Drop(s,n)) == 0));
-axiom (forall<T> s: Seq T, n: int, j: int :: { Seq#Index(Seq#Drop(s,n), j) } {:weight 25}
- 0 <= n && 0 <= j && j < Seq#Length(s)-n ==>
- Seq#Index(Seq#Drop(s,n), j) == Seq#Index(s, j+n));
-
-axiom (forall<T> s, t: Seq T ::
- { Seq#Append(s, t) }
- Seq#Take(Seq#Append(s, t), Seq#Length(s)) == s &&
- Seq#Drop(Seq#Append(s, t), Seq#Length(s)) == t);
-
-function Seq#FromArray(h: HeapType, a: ref): Seq BoxType;
-axiom (forall h: HeapType, a: ref ::
- { Seq#Length(Seq#FromArray(h,a)) }
- Seq#Length(Seq#FromArray(h, a)) == _System.array.Length(a));
-axiom (forall h: HeapType, a: ref :: { Seq#FromArray(h,a): Seq BoxType }
- (forall i: int :: 0 <= i && i < Seq#Length(Seq#FromArray(h, a)) ==> Seq#Index(Seq#FromArray(h, a), i) == read(h, a, IndexField(i))));
-axiom (forall<alpha> h: HeapType, o: ref, f: Field alpha, v: alpha, a: ref ::
- { Seq#FromArray(update(h, o, f, v), a) }
- o != a ==> Seq#FromArray(update(h, o, f, v), a) == Seq#FromArray(h, a) );
-axiom (forall h: HeapType, i: int, v: BoxType, a: ref ::
- { Seq#FromArray(update(h, a, IndexField(i), v), a) }
- 0 <= i && i < _System.array.Length(a) ==> Seq#FromArray(update(h, a, IndexField(i), v), a) == Seq#Update(Seq#FromArray(h, a), i, v) );
-/**** Someday:
-axiom (forall h: HeapType, a: ref :: { Seq#FromArray(h, a) }
- $IsGoodHeap(h) &&
- a != null && read(h, a, alloc) && dtype(a) == class._System.array && TypeParams(a, 0) == class._System.bool
- ==>
- (forall i: int :: { Seq#Index(Seq#FromArray(h, a), i) }
- 0 <= i && i < Seq#Length(Seq#FromArray(h, a)) ==> $IsCanonicalBoolBox(Seq#Index(Seq#FromArray(h, a), i))));
-****/
-
-// Commutability of Take and Drop with Update.
-axiom (forall<T> s: Seq T, i: int, v: T, n: int ::
- { Seq#Take(Seq#Update(s, i, v), n) }
- 0 <= i && i < n && n <= Seq#Length(s) ==> Seq#Take(Seq#Update(s, i, v), n) == Seq#Update(Seq#Take(s, n), i, v) );
-axiom (forall<T> s: Seq T, i: int, v: T, n: int ::
- { Seq#Take(Seq#Update(s, i, v), n) }
- n <= i && i < Seq#Length(s) ==> Seq#Take(Seq#Update(s, i, v), n) == Seq#Take(s, n));
-axiom (forall<T> s: Seq T, i: int, v: T, n: int ::
- { Seq#Drop(Seq#Update(s, i, v), n) }
- 0 <= n && n <= i && i < Seq#Length(s) ==> Seq#Drop(Seq#Update(s, i, v), n) == Seq#Update(Seq#Drop(s, n), i-n, v) );
-axiom (forall<T> s: Seq T, i: int, v: T, n: int ::
- { Seq#Drop(Seq#Update(s, i, v), n) }
- 0 <= i && i < n && n < Seq#Length(s) ==> Seq#Drop(Seq#Update(s, i, v), n) == Seq#Drop(s, n));
-// Extension axiom, triggers only on Takes from arrays.
-axiom (forall h: HeapType, a: ref, n0, n1: int ::
- { Seq#Take(Seq#FromArray(h, a), n0), Seq#Take(Seq#FromArray(h, a), n1) }
- n0 + 1 == n1 && 0 <= n0 && n1 <= _System.array.Length(a) ==> Seq#Take(Seq#FromArray(h, a), n1) == Seq#Build(Seq#Take(Seq#FromArray(h, a), n0), read(h, a, IndexField(n0): Field BoxType)) );
-// drop commutes with build.
-axiom (forall<T> s: Seq T, v: T, n: int ::
- { Seq#Drop(Seq#Build(s, v), n) }
- 0 <= n && n <= Seq#Length(s) ==> Seq#Drop(Seq#Build(s, v), n) == Seq#Build(Seq#Drop(s, n), v) );
-
-// Additional axioms about common things
-axiom Seq#Take(Seq#Empty(): Seq BoxType, 0) == Seq#Empty(); // [][..0] == []
-axiom Seq#Drop(Seq#Empty(): Seq BoxType, 0) == Seq#Empty(); // [][0..] == []
-
-// ---------------------------------------------------------------
-// -- Axiomatization of Maps -------------------------------------
-// ---------------------------------------------------------------
-
-type Map U V;
-
-function Map#Domain<U, V>(Map U V): [U] bool;
-function Map#Elements<U, V>(Map U V): [U]V;
-
-function Map#Empty<U, V>(): Map U V;
-axiom (forall<U, V> u: U ::
- { Map#Domain(Map#Empty(): Map U V)[u] }
- !Map#Domain(Map#Empty(): Map U V)[u]);
-
-function Map#Glue<U, V>([U] bool, [U]V): Map U V;
-axiom (forall<U, V> a: [U] bool, b:[U]V ::
- { Map#Domain(Map#Glue(a, b)) }
- Map#Domain(Map#Glue(a, b)) == a);
-axiom (forall<U, V> a: [U] bool, b:[U]V ::
- { Map#Elements(Map#Glue(a, b)) }
- Map#Elements(Map#Glue(a, b)) == b);
-
-
-//Build is used in displays, and for map updates
-function Map#Build<U, V>(Map U V, U, V): Map U V;
-/*axiom (forall<U, V> m: Map U V, u: U, v: V ::
- { Map#Domain(Map#Build(m, u, v))[u] } { Map#Elements(Map#Build(m, u, v))[u] }
- Map#Domain(Map#Build(m, u, v))[u] && Map#Elements(Map#Build(m, u, v))[u] == v);*/
-
-axiom (forall<U, V> m: Map U V, u: U, u': U, v: V ::
- { Map#Domain(Map#Build(m, u, v))[u'] } { Map#Elements(Map#Build(m, u, v))[u'] }
- (u' == u ==> Map#Domain(Map#Build(m, u, v))[u'] &&
- Map#Elements(Map#Build(m, u, v))[u'] == v) &&
- (u' != u ==> Map#Domain(Map#Build(m, u, v))[u'] == Map#Domain(m)[u'] &&
- Map#Elements(Map#Build(m, u, v))[u'] == Map#Elements(m)[u']));
-
-//equality for maps
-function Map#Equal<U, V>(Map U V, Map U V): bool;
-axiom (forall<U, V> m: Map U V, m': Map U V::
- { Map#Equal(m, m') }
- Map#Equal(m, m') <==> (forall u : U :: Map#Domain(m)[u] == Map#Domain(m')[u]) &&
- (forall u : U :: Map#Domain(m)[u] ==> Map#Elements(m)[u] == Map#Elements(m')[u]));
-// extensionality
-axiom (forall<U, V> m: Map U V, m': Map U V::
- { Map#Equal(m, m') }
- Map#Equal(m, m') ==> m == m');
-
-function Map#Disjoint<U, V>(Map U V, Map U V): bool;
-axiom (forall<U, V> m: Map U V, m': Map U V ::
- { Map#Disjoint(m, m') }
- Map#Disjoint(m, m') <==> (forall o: U :: {Map#Domain(m)[o]} {Map#Domain(m')[o]} !Map#Domain(m)[o] || !Map#Domain(m')[o]));
-
-// ---------------------------------------------------------------
-// -- Boxing and unboxing ----------------------------------------
-// ---------------------------------------------------------------
-
-type BoxType;
-
-function $Box<T>(T): BoxType;
-function $Unbox<T>(BoxType): T;
-
-axiom (forall<T> x: T :: { $Box(x) } $Unbox($Box(x)) == x);
-axiom (forall b: BoxType :: { $Unbox(b): int } $Box($Unbox(b): int) == b);
-axiom (forall b: BoxType :: { $Unbox(b): ref } $Box($Unbox(b): ref) == b);
-axiom (forall b: BoxType :: { $Unbox(b): Set BoxType } $Box($Unbox(b): Set BoxType) == b);
-axiom (forall b: BoxType :: { $Unbox(b): Seq BoxType } $Box($Unbox(b): Seq BoxType) == b);
-axiom (forall b: BoxType :: { $Unbox(b): Map BoxType BoxType } $Box($Unbox(b): Map BoxType BoxType) == b);
-axiom (forall b: BoxType :: { $Unbox(b): DatatypeType } $Box($Unbox(b): DatatypeType) == b);
-// Note: an axiom like this for bool would not be sound; instead, we do:
-function $IsCanonicalBoolBox(BoxType): bool;
-axiom $IsCanonicalBoolBox($Box(false)) && $IsCanonicalBoolBox($Box(true));
-axiom (forall b: BoxType :: { $Unbox(b): bool } $IsCanonicalBoolBox(b) ==> $Box($Unbox(b): bool) == b);
-
-// ---------------------------------------------------------------
-// -- Encoding of type names -------------------------------------
-// ---------------------------------------------------------------
-
-type ClassName;
-const unique class._System.int: ClassName;
-const unique class._System.bool: ClassName;
-const unique class._System.set: ClassName;
-const unique class._System.seq: ClassName;
-const unique class._System.multiset: ClassName;
-const unique class._System.array: ClassName;
-
-function /*{:never_pattern true}*/ dtype(ref): ClassName;
-function /*{:never_pattern true}*/ TypeParams(ref, int): ClassName;
-
-function TypeTuple(a: ClassName, b: ClassName): ClassName;
-function TypeTupleCar(ClassName): ClassName;
-function TypeTupleCdr(ClassName): ClassName;
-// TypeTuple is injective in both arguments:
-axiom (forall a: ClassName, b: ClassName :: { TypeTuple(a,b) }
- TypeTupleCar(TypeTuple(a,b)) == a &&
- TypeTupleCdr(TypeTuple(a,b)) == b);
-
-// ---------------------------------------------------------------
-// -- Datatypes --------------------------------------------------
-// ---------------------------------------------------------------
-
-type DatatypeType;
-
-function /*{:never_pattern true}*/ DtType(DatatypeType): ClassName; // the analog of dtype for datatype values
-function /*{:never_pattern true}*/ DtTypeParams(DatatypeType, int): ClassName; // the analog of TypeParams
-
-type DtCtorId;
-function DatatypeCtorId(DatatypeType): DtCtorId;
-
-function DtRank(DatatypeType): int;
-
-// ---------------------------------------------------------------
-// -- Axiom contexts ---------------------------------------------
-// ---------------------------------------------------------------
-
-// used to make sure function axioms are not used while their consistency is being checked
-const $ModuleContextHeight: int;
-const $FunctionContextHeight: int;
-const $InMethodContext: bool;
-
-// ---------------------------------------------------------------
-// -- Fields -----------------------------------------------------
-// ---------------------------------------------------------------
-
-type Field alpha;
-
-function FDim<T>(Field T): int;
-
-function IndexField(int): Field BoxType;
-axiom (forall i: int :: { IndexField(i) } FDim(IndexField(i)) == 1);
-function IndexField_Inverse<T>(Field T): int;
-axiom (forall i: int :: { IndexField(i) } IndexField_Inverse(IndexField(i)) == i);
-
-function MultiIndexField(Field BoxType, int): Field BoxType;
-axiom (forall f: Field BoxType, i: int :: { MultiIndexField(f,i) } FDim(MultiIndexField(f,i)) == FDim(f) + 1);
-function MultiIndexField_Inverse0<T>(Field T): Field T;
-function MultiIndexField_Inverse1<T>(Field T): int;
-axiom (forall f: Field BoxType, i: int :: { MultiIndexField(f,i) }
- MultiIndexField_Inverse0(MultiIndexField(f,i)) == f &&
- MultiIndexField_Inverse1(MultiIndexField(f,i)) == i);
-
-
-function DeclType<T>(Field T): ClassName;
-
-type NameFamily;
-function DeclName<T>(Field T): NameFamily;
-function FieldOfDecl<alpha>(ClassName, NameFamily): Field alpha;
-axiom (forall<T> cl : ClassName, nm: NameFamily ::
- {FieldOfDecl(cl, nm): Field T}
- DeclType(FieldOfDecl(cl, nm): Field T) == cl && DeclName(FieldOfDecl(cl, nm): Field T) == nm);
-
-// ---------------------------------------------------------------
-// -- Allocatedness ----------------------------------------------
-// ---------------------------------------------------------------
-
-const unique alloc: Field bool;
-axiom FDim(alloc) == 0;
-
-function DtAlloc(DatatypeType, HeapType): bool;
-axiom (forall h, k: HeapType, d: DatatypeType ::
- { $HeapSucc(h, k), DtAlloc(d, h) }
- { $HeapSucc(h, k), DtAlloc(d, k) }
- $HeapSucc(h, k) ==> DtAlloc(d, h) ==> DtAlloc(d, k));
-
-function GenericAlloc(BoxType, HeapType): bool;
-axiom (forall h: HeapType, k: HeapType, d: BoxType ::
- { $HeapSucc(h, k), GenericAlloc(d, h) }
- { $HeapSucc(h, k), GenericAlloc(d, k) }
- $HeapSucc(h, k) ==> GenericAlloc(d, h) ==> GenericAlloc(d, k));
-// GenericAlloc ==>
-axiom (forall b: BoxType, h: HeapType ::
- { GenericAlloc(b, h), h[$Unbox(b): ref, alloc] }
- GenericAlloc(b, h) ==>
- $Unbox(b): ref == null || h[$Unbox(b): ref, alloc]);
-//seqs
-axiom (forall b: BoxType, h: HeapType, i: int ::
- { GenericAlloc(b, h), Seq#Index($Unbox(b): Seq BoxType, i) }
- GenericAlloc(b, h) &&
- 0 <= i && i < Seq#Length($Unbox(b): Seq BoxType) ==>
- GenericAlloc( Seq#Index($Unbox(b): Seq BoxType, i), h ) );
-
-//maps
-//seq-like axiom, talking about the range elements
-axiom (forall b: BoxType, h: HeapType, i: BoxType ::
- { GenericAlloc(b, h), Map#Domain($Unbox(b): Map BoxType BoxType)[i] }
- GenericAlloc(b, h) && Map#Domain($Unbox(b): Map BoxType BoxType)[i] ==>
- GenericAlloc( Map#Elements($Unbox(b): Map BoxType BoxType)[i], h ) );
-//set-like axiom, talking about the domain elements
-axiom (forall b: BoxType, h: HeapType, t: BoxType ::
- { GenericAlloc(b, h), Map#Domain($Unbox(b): Map BoxType BoxType)[t] }
- GenericAlloc(b, h) && Map#Domain($Unbox(b): Map BoxType BoxType)[t] ==>
- GenericAlloc(t, h));
-
-//sets
-axiom (forall b: BoxType, h: HeapType, t: BoxType ::
- { GenericAlloc(b, h), ($Unbox(b): Set BoxType)[t] }
- GenericAlloc(b, h) && ($Unbox(b): Set BoxType)[t] ==>
- GenericAlloc(t, h));
-axiom (forall b: BoxType, h: HeapType ::
- { GenericAlloc(b, h), DtType($Unbox(b): DatatypeType) }
- GenericAlloc(b, h) ==> DtAlloc($Unbox(b): DatatypeType, h));
-// ==> GenericAlloc
-axiom (forall b: bool, h: HeapType ::
- $IsGoodHeap(h) ==> GenericAlloc($Box(b), h));
-axiom (forall x: int, h: HeapType ::
- $IsGoodHeap(h) ==> GenericAlloc($Box(x), h));
-axiom (forall r: ref, h: HeapType ::
- { GenericAlloc($Box(r), h) }
- $IsGoodHeap(h) && (r == null || h[r,alloc]) ==> GenericAlloc($Box(r), h));
-// boxes in the heap
-axiom (forall r: ref, f: Field BoxType, h: HeapType ::
- { GenericAlloc(read(h, r, f), h) }
- $IsGoodHeap(h) && r != null && read(h, r, alloc) ==>
- GenericAlloc(read(h, r, f), h));
-
-// ---------------------------------------------------------------
-// -- Arrays -----------------------------------------------------
-// ---------------------------------------------------------------
-
-function _System.array.Length(a: ref): int;
-axiom (forall o: ref :: 0 <= _System.array.Length(o));
-
-// ---------------------------------------------------------------
-// -- The heap ---------------------------------------------------
-// ---------------------------------------------------------------
-
-type HeapType = <alpha>[ref,Field alpha]alpha;
-function {:inline true} read<alpha>(H:HeapType, r:ref, f:Field alpha): alpha { H[r, f] }
-function {:inline true} update<alpha>(H:HeapType, r:ref, f:Field alpha, v:alpha): HeapType { H[r,f := v] }
-
-function $IsGoodHeap(HeapType): bool;
-var $Heap: HeapType where $IsGoodHeap($Heap);
-
-function $HeapSucc(HeapType, HeapType): bool;
-axiom (forall<alpha> h: HeapType, r: ref, f: Field alpha, x: alpha :: { update(h, r, f, x) }
- $IsGoodHeap(update(h, r, f, x)) ==>
- $HeapSucc(h, update(h, r, f, x)));
-axiom (forall a,b,c: HeapType :: { $HeapSucc(a,b), $HeapSucc(b,c) }
- $HeapSucc(a,b) && $HeapSucc(b,c) ==> $HeapSucc(a,c));
-axiom (forall h: HeapType, k: HeapType :: { $HeapSucc(h,k) }
- $HeapSucc(h,k) ==> (forall o: ref :: { read(k, o, alloc) } read(h, o, alloc) ==> read(k, o, alloc)));
-
-// ---------------------------------------------------------------
-// -- Useful macros ----------------------------------------------
-// ---------------------------------------------------------------
-
-// havoc everything in $Heap, except {this}+rds+nw
-procedure $YieldHavoc(this: ref, rds: Set BoxType, nw: Set BoxType);
- modifies $Heap;
- ensures (forall<alpha> $o: ref, $f: Field alpha :: { read($Heap, $o, $f) }
- $o != null && read(old($Heap), $o, alloc) ==>
- $o == this || rds[$Box($o)] || nw[$Box($o)] ==>
- read($Heap, $o, $f) == read(old($Heap), $o, $f));
- ensures $HeapSucc(old($Heap), $Heap);
-
-// havoc everything in $Heap, except rds-modi-{this}
-procedure $IterHavoc0(this: ref, rds: Set BoxType, modi: Set BoxType);
- modifies $Heap;
- ensures (forall<alpha> $o: ref, $f: Field alpha :: { read($Heap, $o, $f) }
- $o != null && read(old($Heap), $o, alloc) ==>
- rds[$Box($o)] && !modi[$Box($o)] && $o != this ==>
- read($Heap, $o, $f) == read(old($Heap), $o, $f));
- ensures $HeapSucc(old($Heap), $Heap);
-
-// havoc $Heap at {this}+modi+nw
-procedure $IterHavoc1(this: ref, modi: Set BoxType, nw: Set BoxType);
- modifies $Heap;
- ensures (forall<alpha> $o: ref, $f: Field alpha :: { read($Heap, $o, $f) }
- $o != null && read(old($Heap), $o, alloc) ==>
- read($Heap, $o, $f) == read(old($Heap), $o, $f) ||
- $o == this || modi[$Box($o)] || nw[$Box($o)]);
- ensures $HeapSucc(old($Heap), $Heap);
-
-procedure $IterCollectNewObjects(prevHeap: HeapType, newHeap: HeapType, this: ref, NW: Field (Set BoxType))
- returns (s: Set BoxType);
- ensures (forall bx: BoxType :: { s[bx] } s[bx] <==>
- read(newHeap, this, NW)[bx] ||
- ($Unbox(bx) != null && !read(prevHeap, $Unbox(bx):ref, alloc) && read(newHeap, $Unbox(bx):ref, alloc)));
-
-// ---------------------------------------------------------------
-// -- Non-determinism --------------------------------------------
-// ---------------------------------------------------------------
-
-type TickType;
-var $Tick: TickType;
-
-// ---------------------------------------------------------------
diff --git a/Binaries/DafnyRuntime.cs b/Binaries/DafnyRuntime.cs
deleted file mode 100644
index ac688143..00000000
--- a/Binaries/DafnyRuntime.cs
+++ /dev/null
@@ -1,574 +0,0 @@
-using System.Numerics;
-
-namespace Dafny
-{
- using System.Collections.Generic;
-
- public class Set<T>
- {
- Dictionary<T, bool> dict;
- public Set() { }
- Set(Dictionary<T, bool> d) {
- dict = d;
- }
- public static Set<T> Empty {
- get {
- return new Set<T>(new Dictionary<T, bool>(0));
- }
- }
- public static Set<T> FromElements(params T[] values) {
- Dictionary<T, bool> d = new Dictionary<T, bool>(values.Length);
- foreach (T t in values)
- d[t] = true;
- return new Set<T>(d);
- }
- public static Set<T> FromCollection(ICollection<T> values) {
- Dictionary<T, bool> d = new Dictionary<T, bool>();
- foreach (T t in values)
- d[t] = true;
- return new Set<T>(d);
- }
-
- public IEnumerable<T> Elements {
- get {
- return dict.Keys;
- }
- }
- public bool Equals(Set<T> other) {
- return dict.Count == other.dict.Count && IsSubsetOf(other);
- }
- public override bool Equals(object other) {
- return other is Set<T> && Equals((Set<T>)other);
- }
- public override int GetHashCode() {
- return dict.GetHashCode();
- }
- public bool IsProperSubsetOf(Set<T> other) {
- return dict.Count < other.dict.Count && IsSubsetOf(other);
- }
- public bool IsSubsetOf(Set<T> other) {
- if (other.dict.Count < dict.Count)
- return false;
- foreach (T t in dict.Keys) {
- if (!other.dict.ContainsKey(t))
- return false;
- }
- return true;
- }
- public bool IsSupersetOf(Set<T> other) {
- return other.IsSubsetOf(this);
- }
- public bool IsProperSupersetOf(Set<T> other) {
- return other.IsProperSubsetOf(this);
- }
- public bool IsDisjointFrom(Set<T> other) {
- Dictionary<T, bool> a, b;
- if (dict.Count < other.dict.Count) {
- a = dict; b = other.dict;
- } else {
- a = other.dict; b = dict;
- }
- foreach (T t in a.Keys) {
- if (b.ContainsKey(t))
- return false;
- }
- return true;
- }
- public bool Contains(T t) {
- return dict.ContainsKey(t);
- }
- public Set<T> Union(Set<T> other) {
- if (dict.Count == 0)
- return other;
- else if (other.dict.Count == 0)
- return this;
- Dictionary<T, bool> a, b;
- if (dict.Count < other.dict.Count) {
- a = dict; b = other.dict;
- } else {
- a = other.dict; b = dict;
- }
- Dictionary<T, bool> r = new Dictionary<T, bool>();
- foreach (T t in b.Keys)
- r[t] = true;
- foreach (T t in a.Keys)
- r[t] = true;
- return new Set<T>(r);
- }
- public Set<T> Intersect(Set<T> other) {
- if (dict.Count == 0)
- return this;
- else if (other.dict.Count == 0)
- return other;
- Dictionary<T, bool> a, b;
- if (dict.Count < other.dict.Count) {
- a = dict; b = other.dict;
- } else {
- a = other.dict; b = dict;
- }
- var r = new Dictionary<T, bool>();
- foreach (T t in a.Keys) {
- if (b.ContainsKey(t))
- r.Add(t, true);
- }
- return new Set<T>(r);
- }
- public Set<T> Difference(Set<T> other) {
- if (dict.Count == 0)
- return this;
- else if (other.dict.Count == 0)
- return this;
- var r = new Dictionary<T, bool>();
- foreach (T t in dict.Keys) {
- if (!other.dict.ContainsKey(t))
- r.Add(t, true);
- }
- return new Set<T>(r);
- }
- public T Choose() {
- foreach (T t in dict.Keys) {
- // return the first one
- return t;
- }
- return default(T);
- }
- }
- public class MultiSet<T>
- {
- Dictionary<T, int> dict;
- public MultiSet() { }
- MultiSet(Dictionary<T, int> d) {
- dict = d;
- }
- public static MultiSet<T> Empty {
- get {
- return new MultiSet<T>(new Dictionary<T, int>(0));
- }
- }
- public static MultiSet<T> FromElements(params T[] values) {
- Dictionary<T, int> d = new Dictionary<T, int>(values.Length);
- foreach (T t in values) {
- var i = 0;
- if (!d.TryGetValue(t, out i)) {
- i = 0;
- }
- d[t] = i + 1;
- }
- return new MultiSet<T>(d);
- }
- public static MultiSet<T> FromCollection(ICollection<T> values) {
- Dictionary<T, int> d = new Dictionary<T, int>();
- foreach (T t in values) {
- var i = 0;
- if (!d.TryGetValue(t, out i)) {
- i = 0;
- }
- d[t] = i + 1;
- }
- return new MultiSet<T>(d);
- }
- public static MultiSet<T> FromSeq(Sequence<T> values) {
- Dictionary<T, int> d = new Dictionary<T, int>();
- foreach (T t in values.Elements) {
- var i = 0;
- if (!d.TryGetValue(t, out i)) {
- i = 0;
- }
- d[t] = i + 1;
- }
- return new MultiSet<T>(d);
- }
- public static MultiSet<T> FromSet(Set<T> values) {
- Dictionary<T, int> d = new Dictionary<T, int>();
- foreach (T t in values.Elements) {
- d[t] = 1;
- }
- return new MultiSet<T>(d);
- }
-
- public bool Equals(MultiSet<T> other) {
- return other.IsSubsetOf(this) && this.IsSubsetOf(other);
- }
- public override bool Equals(object other) {
- return other is MultiSet<T> && Equals((MultiSet<T>)other);
- }
- public override int GetHashCode() {
- return dict.GetHashCode();
- }
- public bool IsProperSubsetOf(MultiSet<T> other) {
- return !Equals(other) && IsSubsetOf(other);
- }
- public bool IsSubsetOf(MultiSet<T> other) {
- foreach (T t in dict.Keys) {
- if (!other.dict.ContainsKey(t) || other.dict[t] < dict[t])
- return false;
- }
- return true;
- }
- public bool IsSupersetOf(MultiSet<T> other) {
- return other.IsSubsetOf(this);
- }
- public bool IsProperSupersetOf(MultiSet<T> other) {
- return other.IsProperSubsetOf(this);
- }
- public bool IsDisjointFrom(MultiSet<T> other) {
- foreach (T t in dict.Keys) {
- if (other.dict.ContainsKey(t))
- return false;
- }
- foreach (T t in other.dict.Keys) {
- if (dict.ContainsKey(t))
- return false;
- }
- return true;
- }
- public bool Contains(T t) {
- return dict.ContainsKey(t);
- }
- public MultiSet<T> Union(MultiSet<T> other) {
- if (dict.Count == 0)
- return other;
- else if (other.dict.Count == 0)
- return this;
- var r = new Dictionary<T, int>();
- foreach (T t in dict.Keys) {
- var i = 0;
- if (!r.TryGetValue(t, out i)) {
- i = 0;
- }
- r[t] = i + dict[t];
- }
- foreach (T t in other.dict.Keys) {
- var i = 0;
- if (!r.TryGetValue(t, out i)) {
- i = 0;
- }
- r[t] = i + other.dict[t];
- }
- return new MultiSet<T>(r);
- }
- public MultiSet<T> Intersect(MultiSet<T> other) {
- if (dict.Count == 0)
- return this;
- else if (other.dict.Count == 0)
- return other;
- var r = new Dictionary<T, int>();
- foreach (T t in dict.Keys) {
- if (other.dict.ContainsKey(t)) {
- r.Add(t, other.dict[t] < dict[t] ? other.dict[t] : dict[t]);
- }
- }
- return new MultiSet<T>(r);
- }
- public MultiSet<T> Difference(MultiSet<T> other) { // \result == this - other
- if (dict.Count == 0)
- return this;
- else if (other.dict.Count == 0)
- return this;
- var r = new Dictionary<T, int>();
- foreach (T t in dict.Keys) {
- if (!other.dict.ContainsKey(t)) {
- r.Add(t, dict[t]);
- } else if (other.dict[t] < dict[t]) {
- r.Add(t, dict[t] - other.dict[t]);
- }
- }
- return new MultiSet<T>(r);
- }
- public IEnumerable<T> Elements {
- get {
- List<T> l = new List<T>();
- foreach (T t in dict.Keys) {
- int n;
- dict.TryGetValue(t, out n);
- for (int i = 0; i < n; i ++) {
- l.Add(t);
- }
- }
- return l;
- }
- }
- }
-
- public class Map<U, V>
- {
- Dictionary<U, V> dict;
- public Map() { }
- Map(Dictionary<U, V> d) {
- dict = d;
- }
- public static Map<U, V> Empty {
- get {
- return new Map<U, V>(new Dictionary<U,V>());
- }
- }
- public static Map<U, V> FromElements(params Pair<U, V>[] values) {
- Dictionary<U, V> d = new Dictionary<U, V>(values.Length);
- foreach (Pair<U, V> p in values) {
- d[p.Car] = p.Cdr;
- }
- return new Map<U, V>(d);
- }
- public static Map<U, V> FromCollection(List<Pair<U, V>> values) {
- Dictionary<U, V> d = new Dictionary<U, V>(values.Count);
- foreach (Pair<U, V> p in values) {
- d[p.Car] = p.Cdr;
- }
- return new Map<U, V>(d);
- }
- public bool Equals(Map<U, V> other) {
- foreach (U u in dict.Keys) {
- V v1, v2;
- if (!dict.TryGetValue(u, out v1)) {
- return false; // this shouldn't happen
- }
- if (!other.dict.TryGetValue(u, out v2)) {
- return false; // other dictionary does not contain this element
- }
- if (!v1.Equals(v2)) {
- return false;
- }
- }
- foreach (U u in other.dict.Keys) {
- if (!dict.ContainsKey(u)) {
- return false; // this shouldn't happen
- }
- }
- return true;
- }
- public override bool Equals(object other) {
- return other is Map<U, V> && Equals((Map<U, V>)other);
- }
- public override int GetHashCode() {
- return dict.GetHashCode();
- }
- public bool IsDisjointFrom(Map<U, V> other) {
- foreach (U u in dict.Keys) {
- if (other.dict.ContainsKey(u))
- return false;
- }
- foreach (U u in other.dict.Keys) {
- if (dict.ContainsKey(u))
- return false;
- }
- return true;
- }
- public bool Contains(U u) {
- return dict.ContainsKey(u);
- }
- public V Select(U index) {
- return dict[index];
- }
- public Map<U, V> Update(U index, V val) {
- Dictionary<U, V> d = new Dictionary<U, V>(dict);
- d[index] = val;
- return new Map<U, V>(d);
- }
- public IEnumerable<U> Domain {
- get {
- return dict.Keys;
- }
- }
- }
- public class Sequence<T>
- {
- T[] elmts;
- public Sequence() { }
- public Sequence(T[] ee) {
- elmts = ee;
- }
- public static Sequence<T> Empty {
- get {
- return new Sequence<T>(new T[0]);
- }
- }
- public static Sequence<T> FromElements(params T[] values) {
- return new Sequence<T>(values);
- }
- public BigInteger Length {
- get { return new BigInteger(elmts.Length); }
- }
- public T[] Elements {
- get {
- return elmts;
- }
- }
- public IEnumerable<T> UniqueElements {
- get {
- var st = Set<T>.FromElements(elmts);
- return st.Elements;
- }
- }
- public T Select(BigInteger index) {
- return elmts[(int)index];
- }
- public Sequence<T> Update(BigInteger index, T t) {
- T[] a = (T[])elmts.Clone();
- a[(int)index] = t;
- return new Sequence<T>(a);
- }
- public bool Equals(Sequence<T> other) {
- int n = elmts.Length;
- return n == other.elmts.Length && EqualUntil(other, n);
- }
- public override bool Equals(object other) {
- return other is Sequence<T> && Equals((Sequence<T>)other);
- }
- public override int GetHashCode() {
- return elmts.GetHashCode();
- }
- bool EqualUntil(Sequence<T> other, int n) {
- for (int i = 0; i < n; i++) {
- if (!elmts[i].Equals(other.elmts[i]))
- return false;
- }
- return true;
- }
- public bool IsProperPrefixOf(Sequence<T> other) {
- int n = elmts.Length;
- return n < other.elmts.Length && EqualUntil(other, n);
- }
- public bool IsPrefixOf(Sequence<T> other) {
- int n = elmts.Length;
- return n <= other.elmts.Length && EqualUntil(other, n);
- }
- public Sequence<T> Concat(Sequence<T> other) {
- if (elmts.Length == 0)
- return other;
- else if (other.elmts.Length == 0)
- return this;
- T[] a = new T[elmts.Length + other.elmts.Length];
- System.Array.Copy(elmts, 0, a, 0, elmts.Length);
- System.Array.Copy(other.elmts, 0, a, elmts.Length, other.elmts.Length);
- return new Sequence<T>(a);
- }
- public bool Contains(T t) {
- int n = elmts.Length;
- for (int i = 0; i < n; i++) {
- if (t.Equals(elmts[i]))
- return true;
- }
- return false;
- }
- public Sequence<T> Take(BigInteger n) {
- int m = (int)n;
- if (elmts.Length == m)
- return this;
- T[] a = new T[m];
- System.Array.Copy(elmts, a, m);
- return new Sequence<T>(a);
- }
- public Sequence<T> Drop(BigInteger n) {
- if (n.IsZero)
- return this;
- int m = (int)n;
- T[] a = new T[elmts.Length - m];
- System.Array.Copy(elmts, m, a, 0, elmts.Length - m);
- return new Sequence<T>(a);
- }
- }
- public struct Pair<A, B>
- {
- public readonly A Car;
- public readonly B Cdr;
- public Pair(A a, B b) {
- this.Car = a;
- this.Cdr = b;
- }
- }
- public partial class Helpers {
- // Computing forall/exists quantifiers
- public static bool QuantBool(bool frall, System.Predicate<bool> pred) {
- if (frall) {
- return pred(false) && pred(true);
- } else {
- return pred(false) || pred(true);
- }
- }
- public static bool QuantInt(BigInteger lo, BigInteger hi, bool frall, System.Predicate<BigInteger> pred) {
- for (BigInteger i = lo; i < hi; i++) {
- if (pred(i) != frall) { return !frall; }
- }
- return frall;
- }
- public static bool QuantSet<U>(Dafny.Set<U> set, bool frall, System.Predicate<U> pred) {
- foreach (var u in set.Elements) {
- if (pred(u) != frall) { return !frall; }
- }
- return frall;
- }
- public static bool QuantMap<U,V>(Dafny.Map<U,V> map, bool frall, System.Predicate<U> pred) {
- foreach (var u in map.Domain) {
- if (pred(u) != frall) { return !frall; }
- }
- return frall;
- }
- public static bool QuantSeq<U>(Dafny.Sequence<U> seq, bool frall, System.Predicate<U> pred) {
- foreach (var u in seq.Elements) {
- if (pred(u) != frall) { return !frall; }
- }
- return frall;
- }
- public static bool QuantDatatype<U>(IEnumerable<U> set, bool frall, System.Predicate<U> pred) {
- foreach (var u in set) {
- if (pred(u) != frall) { return !frall; }
- }
- return frall;
- }
- // Enumerating other collections
- public delegate Dafny.Set<T> ComprehensionDelegate<T>();
- public delegate Dafny.Map<U, V> MapComprehensionDelegate<U, V>();
- public static IEnumerable<bool> AllBooleans {
- get {
- yield return false;
- yield return true;
- }
- }
- // pre: b != 0
- // post: result == a/b, as defined by Euclidean Division (http://en.wikipedia.org/wiki/Modulo_operation)
- public static BigInteger EuclideanDivision(BigInteger a, BigInteger b) {
- if (0 <= a.Sign) {
- if (0 <= b.Sign) {
- // +a +b: a/b
- return BigInteger.Divide(a, b);
- } else {
- // +a -b: -(a/(-b))
- return BigInteger.Negate(BigInteger.Divide(a, BigInteger.Negate(b)));
- }
- } else {
- if (0 <= b.Sign) {
- // -a +b: -((-a-1)/b) - 1
- return BigInteger.Negate(BigInteger.Divide(BigInteger.Negate(a) - 1, b)) - 1;
- } else {
- // -a -b: ((-a-1)/(-b)) + 1
- return BigInteger.Divide(BigInteger.Negate(a) - 1, BigInteger.Negate(b)) + 1;
- }
- }
- }
- // pre: b != 0
- // post: result == a%b, as defined by Euclidean Division (http://en.wikipedia.org/wiki/Modulo_operation)
- public static BigInteger EuclideanModulus(BigInteger a, BigInteger b) {
- var bp = BigInteger.Abs(b);
- if (0 <= a.Sign) {
- // +a: a % b'
- return BigInteger.Remainder(a, bp);
- } else {
- // c = ((-a) % b')
- // -a: b' - c if c > 0
- // -a: 0 if c == 0
- var c = BigInteger.Remainder(BigInteger.Negate(a), bp);
- return c.IsZero ? c : BigInteger.Subtract(bp, c);
- }
- }
- public static Sequence<T> SeqFromArray<T>(T[] array) {
- return new Sequence<T>(array);
- }
- // In .NET version 4.5, it it possible to mark a method with "AggressiveInlining", which says to inline the
- // method if possible. Method "ExpressionSequence" would be a good candidate for it:
- // [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public static U ExpressionSequence<T, U>(T t, U u)
- {
- return u;
- }
- }
-}
diff --git a/Test/VSComp2010/Answer b/Test/VSComp2010/Answer
deleted file mode 100644
index 9a083fa3..00000000
--- a/Test/VSComp2010/Answer
+++ /dev/null
@@ -1,20 +0,0 @@
-
--------------------- Problem1-SumMax.dfy --------------------
-
-Dafny program verifier finished with 4 verified, 0 errors
-
--------------------- Problem2-Invert.dfy --------------------
-
-Dafny program verifier finished with 7 verified, 0 errors
-
--------------------- Problem3-FindZero.dfy --------------------
-
-Dafny program verifier finished with 7 verified, 0 errors
-
--------------------- Problem4-Queens.dfy --------------------
-
-Dafny program verifier finished with 9 verified, 0 errors
-
--------------------- Problem5-DoubleEndedQueue.dfy --------------------
-
-Dafny program verifier finished with 21 verified, 0 errors
diff --git a/Test/VSComp2010/Problem1-SumMax.dfy b/Test/VSComp2010/Problem1-SumMax.dfy
deleted file mode 100644
index 3db9bf72..00000000
--- a/Test/VSComp2010/Problem1-SumMax.dfy
+++ /dev/null
@@ -1,43 +0,0 @@
-// VSComp 2010, problem 1, compute the sum and max of the elements of an array and prove
-// that 'sum <= N * max'.
-// Rustan Leino, 18 August 2010.
-//
-// The problem statement gave the pseudo-code for the method, but did not ask to prove
-// that 'sum' or 'max' return as the sum and max, respectively, of the array. The
-// given assumption that the array's elements are non-negative is not needed to establish
-// the requested postcondition.
-
-method M(N: int, a: array<int>) returns (sum: int, max: int)
- requires 0 <= N && a != null && a.Length == N && (forall k :: 0 <= k && k < N ==> 0 <= a[k]);
- ensures sum <= N * max;
-{
- sum := 0;
- max := 0;
- var i := 0;
- while (i < N)
- invariant i <= N && sum <= i * max;
- {
- if (max < a[i]) {
- max := a[i];
- }
- sum := sum + a[i];
- i := i + 1;
- }
-}
-
-method Main()
-{
- var a := new int[10];
- a[0] := 9;
- a[1] := 5;
- a[2] := 0;
- a[3] := 2;
- a[4] := 7;
- a[5] := 3;
- a[6] := 2;
- a[7] := 1;
- a[8] := 10;
- a[9] := 6;
- var s, m := M(10, a);
- print "N = ", a.Length, " sum = ", s, " max = ", m, "\n";
-}
diff --git a/Test/VSComp2010/Problem2-Invert.dfy b/Test/VSComp2010/Problem2-Invert.dfy
deleted file mode 100644
index 0f7c50c1..00000000
--- a/Test/VSComp2010/Problem2-Invert.dfy
+++ /dev/null
@@ -1,80 +0,0 @@
-// VSComp 2010, problem 2, compute the inverse 'B' of a permutation 'A' and prove that 'B' is
-// indeed an inverse of 'A' (or at least prove that 'B' is injective).
-// Rustan Leino, 31 August 2010.
-//
-// In the version of this program that I wrote during the week of VSTTE 2010, I had
-// used a lemma (stated as a ghost method) that I proved inductively (using a loop and
-// a loop invariant). Here, I have simplified that version by just including an
-// assertion of the crucial property, which follows from the surjectivity of 'A'.
-//
-// The difficulty in proving this program with an SMT solver stems from the fact that
-// the quantifier that states the surjectivity property has no good matching trigger
-// (because there are no function symbols mentioned in the antecedent of that quantifier,
-// only built-in predicates). Therefore, I introduced a dummy function 'inImage' and
-// defined it always to equal 'true'. I can then mention this function in the crucial
-// assertion, which causes the appropriate triggering to take place.
-//
-// A slight annoyance is that the loop's modifications of the heap, which is checked
-// to include only the elements of 'B'. Since 'A' and 'B' are arrays stored at different
-// locations in the heap, it then follows that the elements of 'A' are not modified.
-// However, the fact that the heap has changed at all makes the symbolic expressions
-// denoting the elements of 'A' look different before and after the heap. The
-// assertion after the loop (which, like all assertions, is proved) is needed to
-// connect the two.
-
-method M(N: int, A: array<int>, B: array<int>)
- requires 0 <= N && A != null && B != null && N == A.Length && N == B.Length && A != B;
- requires (forall k :: 0 <= k && k < N ==> 0 <= A[k] && A[k] < N);
- requires (forall j,k :: 0 <= j && j < k && k < N ==> A[j] != A[k]); // A is injective
- requires (forall m :: 0 <= m && m < N && inImage(m) ==> (exists k :: 0 <= k && k < N && A[k] == m)); // A is surjective
- modifies B;
- ensures (forall k :: 0 <= k && k < N ==> 0 <= B[k] && B[k] < N);
- ensures (forall k :: 0 <= k && k < N ==> B[A[k]] == k && A[B[k]] == k); // A and B are each other's inverses
- ensures (forall j,k :: 0 <= j && j < k && k < N ==> B[j] != B[k]); // (which means that) B is injective
-{
- var n := 0;
- while (n < N)
- invariant n <= N;
- invariant (forall k :: 0 <= k && k < n ==> B[A[k]] == k);
- {
- B[A[n]] := n;
- n := n + 1;
- }
- assert (forall i :: 0 <= i && i < N ==> A[i] == old(A[i])); // the elements of A were not changed by the loop
- // it now follows from the surjectivity of A that A is the inverse of B:
- assert (forall j :: 0 <= j && j < N && inImage(j) ==> 0 <= B[j] && B[j] < N && A[B[j]] == j);
- assert (forall j,k :: 0 <= j && j < k && k < N ==> B[j] != B[k]);
-}
-
-static function inImage(i: int): bool { true } // this function is used to trigger the surjective quantification
-
-method Main()
-{
- var a := new int[10];
- a[0] := 9;
- a[1] := 3;
- a[2] := 8;
- a[3] := 2;
- a[4] := 7;
- a[5] := 4;
- a[6] := 0;
- a[7] := 1;
- a[8] := 5;
- a[9] := 6;
- var b := new int[10];
- M(10, a, b);
- print "a:\n";
- PrintArray(a);
- print "b:\n";
- PrintArray(b);
-}
-
-method PrintArray(a: array<int>)
- requires a != null;
-{
- var i := 0;
- while (i < a.Length) {
- print a[i], "\n";
- i := i + 1;
- }
-}
diff --git a/Test/VSComp2010/Problem3-FindZero.dfy b/Test/VSComp2010/Problem3-FindZero.dfy
deleted file mode 100644
index 3d24255d..00000000
--- a/Test/VSComp2010/Problem3-FindZero.dfy
+++ /dev/null
@@ -1,92 +0,0 @@
-// VSComp 2010, problem 3, find a 0 in a linked list and return how many nodes were skipped
-// until the first 0 (or end-of-list) was found.
-// Rustan Leino, 18 August 2010.
-//
-// The difficulty in this problem lies in specifying what the return value 'r' denotes and in
-// proving that the program terminates. Both of these are addressed by declaring a ghost
-// field 'List' in each linked-list node, abstractly representing the linked-list elements
-// from the node to the end of the linked list. The specification can now talk about that
-// sequence of elements and can use 'r' as an index into the sequence, and termination can
-// be proved from the fact that all sequences in Dafny are finite.
-//
-// We only want to deal with linked lists whose 'List' field is properly filled in (which
-// can only happen in an acyclic list, for example). To that avail, the standard idiom in
-// Dafny is to declare a predicate 'Valid()' that is true of an object when the data structure
-// representing object's abstract value is properly formed. The definition of 'Valid()'
-// is what one intuitively would think of as the ''object invariant'', and it is mentioned
-// explicitly in method pre- and postconditions. As part of this standard idiom, one also
-// declared a ghost variable 'Repr' that is maintained as the set of objects that make up
-// the representation of the aggregate object--in this case, the Node itself and all its
-// successors.
-
-class Node {
- ghost var List: seq<int>;
- ghost var Repr: set<Node>;
- var head: int;
- var next: Node;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- 1 <= |List| && List[0] == head &&
- (next == null ==> |List| == 1) &&
- (next != null ==>
- next in Repr && next.Repr <= Repr && this !in next.Repr && next.Valid() && next.List == List[1..])
- }
-
- static method Cons(x: int, tail: Node) returns (n: Node)
- requires tail == null || tail.Valid();
- ensures n != null && n.Valid();
- ensures if tail == null then n.List == [x] else n.List == [x] + tail.List;
- {
- n := new Node;
- n.head := x;
- n.next := tail;
- if (tail == null) {
- n.List := [x];
- n.Repr := {n};
- } else {
- n.List := [x] + tail.List;
- n.Repr := {n} + tail.Repr;
- }
- }
-}
-
-static method Search(ll: Node) returns (r: int)
- requires ll == null || ll.Valid();
- ensures ll == null ==> r == 0;
- ensures ll != null ==>
- 0 <= r && r <= |ll.List| &&
- (r < |ll.List| ==> ll.List[r] == 0 && 0 !in ll.List[..r]) &&
- (r == |ll.List| ==> 0 !in ll.List);
-{
- if (ll == null) {
- r := 0;
- } else {
- var jj := ll;
- var i := 0;
- while (jj != null && jj.head != 0)
- invariant jj != null ==> jj.Valid() && i + |jj.List| == |ll.List| && ll.List[i..] == jj.List;
- invariant jj == null ==> i == |ll.List|;
- invariant 0 !in ll.List[..i];
- decreases |ll.List| - i;
- {
- jj := jj.next;
- i := i + 1;
- }
- r := i;
- }
-}
-
-method Main()
-{
- var list: Node := null;
- list := list.Cons(0, list);
- list := list.Cons(5, list);
- list := list.Cons(0, list);
- list := list.Cons(8, list);
- var r := Search(list);
- print "Search returns ", r, "\n";
- assert r == 1;
-}
diff --git a/Test/VSComp2010/Problem4-Queens.dfy b/Test/VSComp2010/Problem4-Queens.dfy
deleted file mode 100644
index 2f21b7a1..00000000
--- a/Test/VSComp2010/Problem4-Queens.dfy
+++ /dev/null
@@ -1,154 +0,0 @@
-// VSComp 2010, problem 4, N queens
-// Rustan Leino, 31 August 2010, updated 24 March 2011.
-//
-// In the version of this program that I wrote during the week of VSTTE 2010, I had
-// an unproved assumption. In this version, I simply changed the existential quantifier
-// in that assumption to specify a particular witness, which is enough of a hint for
-// Dafny to fully prove the correctness of the program.
-//
-// Oh, I also added some comments in this version of the program.
-//
-// The correctness of this program relies on some properties of Queens boards. These
-// are stated and proved as lemmas, which here are given in assert statements.
-//
-// There is an annoyance in this program. Dafny's proof-term representation of the function
-// 'IsConsistent' implicitly takes the heap as an argument, despite the fact that
-// 'IsConsistent' does not depend on any part of the heap. Dafny ought to be able
-// to figure that out from the fact that 'IsConsistent' has no 'reads' clause.
-// Maybe a future version of Dafny will do just that. But until then, some methods
-// below are specified with an (easy-to-prove) postcondition that 'IsConsistent(B,p)'
-// does not change for any 'B' and 'p', even if the method may change the heap in
-// some way.
-//
-// The March 2011 update of this program was to make use of Dafny's new heuristics for
-// compiling quantifiers. This makes it possible to call IsConsistent, whose body uses
-// a universal quantifier, from non-ghost code, which simplifies this program.
-
-
-// The Search method returns whether or not there exists an N-queens solution for the
-// given N. If 'success' returns as 'true', 'board' indicates a solution. If 'success'
-// returns as 'false', no solution exists, as stated in the second postcondition.
-method Search(N: int) returns (success: bool, board: seq<int>)
- requires 0 <= N;
- ensures success ==>
- |board| == N &&
- (forall p :: 0 <= p && p < N ==> IsConsistent(board, p));
- ensures !success ==>
- (forall B ::
- |B| == N && (forall i :: 0 <= i && i < N ==> 0 <= B[i] && B[i] < N)
- ==>
- (exists p :: 0 <= p && p < N && !IsConsistent(B, p)));
-{
- success, board := SearchAux(N, []);
-}
-
-// Given a board, this function says whether or not the queen placed in column 'pos'
-// is consistent with the queens placed in columns to its left.
-static function method IsConsistent(board: seq<int>, pos: int): bool
-{
- 0 <= pos && pos < |board| &&
- (forall q :: 0 <= q && q < pos ==>
- board[q] != board[pos] &&
- board[q] - board[pos] != pos - q &&
- board[pos] - board[q] != pos - q)
-}
-
-// Here comes the method where the real work is being done. With an ultimate board size of 'N'
-// in mind and given the consistent placement 'boardSoFar' of '|boardSoFar|' columns, this method
-// will search for a solution for the remaining columns. If 'success' returns as 'true',
-// then 'newBoard' is a consistent placement of 'N' queens. If 'success' returns as 'false',
-// then there is no way to extend 'boardSoFar' to get a solution for 'N' queens.
-method SearchAux(N: int, boardSoFar: seq<int>) returns (success: bool, newBoard: seq<int>)
- requires 0 <= N && |boardSoFar| <= N;
- // consistent so far:
- requires (forall k :: 0 <= k && k < |boardSoFar| ==> IsConsistent(boardSoFar, k));
- ensures success ==>
- |newBoard| == N &&
- (forall p :: 0 <= p && p < N ==> IsConsistent(newBoard, p));
- ensures !success ==>
- (forall B ::
- |B| == N && (forall i :: 0 <= i && i < N ==> 0 <= B[i] && B[i] < N) &&
- boardSoFar <= B
- ==>
- (exists p :: 0 <= p && p < N && !IsConsistent(B, p)));
- ensures (forall B, p :: IsConsistent(B, p) <==> old(IsConsistent(B, p)));
- decreases N - |boardSoFar|;
-{
- var pos := |boardSoFar|;
- if (pos == N) {
- // The given board already has the desired size.
- newBoard := boardSoFar;
- success := true;
- } else {
- // Exhaustively try all possibilities for the new column, 'pos'.
- var n := 0;
- while (n < N)
- invariant n <= N;
- invariant (forall B ::
- // For any board 'B' with 'N' queens, each placed in an existing row
- |B| == N && (forall i :: 0 <= i && i < N ==> 0 <= B[i] && B[i] < N) &&
- // ... where 'B' is an extension of 'boardSoFar'
- boardSoFar <= B &&
- // ... and the first column to extend 'boardSoFar' has a queen in one of
- // the first 'n' rows
- 0 <= B[pos] && B[pos] < n
- ==>
- // ... the board 'B' is not entirely consistent
- (exists p :: 0 <= p && p < N && !IsConsistent(B, p)));
- {
- // Let's try to extend the board-so-far with a queen in column 'n':
- var candidateBoard := boardSoFar + [n];
- if (IsConsistent(candidateBoard, pos)) {
- // The new queen is consistent. Thus, 'candidateBoard' is consistent in column 'pos'.
- // The consistency of the queens in columns left of 'pos' follows from the
- // consistency of those queens in 'boardSoFar' and the fact that 'candidateBoard' is
- // an extension of 'boardSoFar', as the following lemma tells us:
- assert (forall k ::
- 0 <= k && k < |boardSoFar| && IsConsistent(boardSoFar, k)
- ==>
- IsConsistent(candidateBoard, k));
-
- // Thus, we meet the precondition of 'SearchAux' on 'candidateBoard', so let's search
- // for a solution that extends 'candidateBoard'.
- var s, b := SearchAux(N, candidateBoard);
- if (s) {
- // The recursive call to 'SearchAux' found consistent positions for all remaining columns
- newBoard := b;
- success := true;
- return;
- }
- // The recursive call to 'SearchAux' determined that no consistent extensions to 'candidateBoard'
- // exist.
- } else {
- // Since 'n' is not a consistent placement for a queen in column 'pos', there is also
- // no extension of 'candidateBoard' that would make the entire board consistent.
- assert (forall B ::
- |B| == N && (forall i :: 0 <= i && i < N ==> 0 <= B[i] && B[i] < N) &&
- candidateBoard <= B
- ==>
- !IsConsistent(B, pos));
- }
- n := n + 1;
- }
-
- success := false;
- }
-}
-
-method Main()
-{
- var s, b := Search(2);
- print "N=2 returns ", s, "\n";
- s, b := Search(4);
- print "N=4 returns ", s, "\n";
- PrintSeq(b);
-}
-
-method PrintSeq(b: seq<int>)
-{
- var i := 0;
- while (i < |b|) {
- print " ", b[i], "\n";
- i := i + 1;
- }
-}
diff --git a/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy b/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy
deleted file mode 100644
index 0e141927..00000000
--- a/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy
+++ /dev/null
@@ -1,163 +0,0 @@
-// VSComp 2010, problem 5, double-ended queue.
-// Rustan Leino, 18 August 2010.
-//
-// This program employs the standard Valid()/Repr idiom used in the dynamic-frames
-// style of specifications, see for example the comment in Problem3-FindZero.dfy.
-// Within that idiom, the specification is straightforward (if verbose), and there
-// are no particular wrinkles or annoyances in getting the verifier to prove the
-// correctness.
-
-class AmortizedQueue<T> {
- // The front of the queue.
- var front: LinkedList<T>;
- // The rear of the queue (stored in reversed order).
- var rear: LinkedList<T>;
-
- ghost var Repr: set<object>;
- ghost var List: seq<T>;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- front != null && front in Repr && front.Repr <= Repr && front.Valid() &&
- rear != null && rear in Repr && rear.Repr <= Repr && rear.Valid() &&
- |rear.List| <= |front.List| &&
- List == front.List + rear.ReverseSeq(rear.List)
- }
-
- method Init()
- modifies this;
- ensures Valid() && List == [];
- {
- front := new LinkedList<T>.Init();
- rear := new LinkedList<T>.Init();
- Repr := {this};
- Repr := Repr + front.Repr + rear.Repr;
- List := [];
- }
-
- method InitFromPieces(f: LinkedList<T>, r: LinkedList<T>)
- requires f != null && f.Valid() && r != null && r.Valid();
- modifies this;
- ensures Valid() && List == f.List + r.ReverseSeq(r.List);
- {
- if (r.length <= f.length) {
- front := f;
- rear := r;
- } else {
- var rr := r.Reverse();
- var ff := f.Concat(rr);
- front := ff;
-
- rear := new LinkedList<T>.Init();
- }
- Repr := {this};
- Repr := Repr + front.Repr + rear.Repr;
- List := front.List + rear.ReverseSeq(rear.List);
- }
-
- method Front() returns (t: T)
- requires Valid() && List != [];
- ensures t == List[0];
- {
- t := front.head;
- }
-
- method Tail() returns (r: AmortizedQueue<T>)
- requires Valid() && List != [];
- ensures r != null && r.Valid() && r.List == List[1..];
- {
- r := new AmortizedQueue<T>.InitFromPieces(front.tail, rear);
- }
-
- method Enqueue(item: T) returns (r: AmortizedQueue<T>)
- requires Valid();
- ensures r != null && r.Valid() && r.List == List + [item];
- {
- var rr := rear.Cons(item);
- r := new AmortizedQueue<T>.InitFromPieces(front, rr);
- }
-}
-
-
-class LinkedList<T> {
- var head: T;
- var tail: LinkedList<T>;
- var length: int;
-
- ghost var List: seq<T>;
- ghost var Repr: set<LinkedList<T>>;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- 0 <= length && length == |List| &&
- (length == 0 ==> List == [] && tail == null) &&
- (length != 0 ==>
- tail != null && tail in Repr &&
- tail.Repr <= Repr && this !in tail.Repr &&
- tail.Valid() &&
- List == [head] + tail.List &&
- length == tail.length + 1)
- }
-
- method Init()
- modifies this;
- ensures Valid() && List == [];
- {
- tail := null;
- length := 0;
- List := [];
- Repr := {this};
- }
-
- method Cons(d: T) returns (r: LinkedList<T>)
- requires Valid();
- ensures r != null && r.Valid() && r.List == [d] + List;
- {
- r := new LinkedList<T>;
- r.head := d;
- r.tail := this;
- r.length := length + 1;
- r.List := [d] + List;
- r.Repr := {r} + Repr;
- }
-
- method Concat(end: LinkedList<T>) returns (r: LinkedList<T>)
- requires Valid() && end != null && end.Valid();
- ensures r != null && r.Valid() && r.List == List + end.List;
- decreases Repr;
- {
- if (length == 0) {
- r := end;
- } else {
- var c := tail.Concat(end);
- r := c.Cons(head);
- }
- }
-
- method Reverse() returns (r: LinkedList<T>)
- requires Valid();
- ensures r != null && r.Valid() && |List| == |r.List|;
- ensures (forall k :: 0 <= k && k < |List| ==> List[k] == r.List[|List|-1-k]);
- ensures r.List == ReverseSeq(List);
- decreases Repr;
- {
- if (length == 0) {
- r := this;
- } else {
- r := tail.Reverse();
- var e := new LinkedList<T>.Init();
- e := e.Cons(head);
- r := r.Concat(e);
- }
- }
-
- static function ReverseSeq(s: seq<T>): seq<T>
- {
- if s == [] then [] else
- ReverseSeq(s[1..]) + [s[0]]
- }
-}
diff --git a/Test/VSComp2010/runtest.bat b/Test/VSComp2010/runtest.bat
deleted file mode 100644
index 63f5df23..00000000
--- a/Test/VSComp2010/runtest.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-for %%f in (Problem1-SumMax.dfy Problem2-Invert.dfy
- Problem3-FindZero.dfy Problem4-Queens.dfy
- Problem5-DoubleEndedQueue.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 %* %%f
-)
diff --git a/Test/VSI-Benchmarks/Answer b/Test/VSI-Benchmarks/Answer
deleted file mode 100644
index 2a4587f4..00000000
--- a/Test/VSI-Benchmarks/Answer
+++ /dev/null
@@ -1,32 +0,0 @@
-
--------------------- b1.dfy --------------------
-
-Dafny program verifier finished with 10 verified, 0 errors
-
--------------------- b2.dfy --------------------
-
-Dafny program verifier finished with 6 verified, 0 errors
-
--------------------- b3.dfy --------------------
-
-Dafny program verifier finished with 10 verified, 0 errors
-
--------------------- b4.dfy --------------------
-
-Dafny program verifier finished with 11 verified, 0 errors
-
--------------------- b5.dfy --------------------
-
-Dafny program verifier finished with 22 verified, 0 errors
-
--------------------- b6.dfy --------------------
-
-Dafny program verifier finished with 21 verified, 0 errors
-
--------------------- b7.dfy --------------------
-
-Dafny program verifier finished with 23 verified, 0 errors
-
--------------------- b8.dfy --------------------
-
-Dafny program verifier finished with 42 verified, 0 errors
diff --git a/Test/VSI-Benchmarks/b1.dfy b/Test/VSI-Benchmarks/b1.dfy
deleted file mode 100644
index 3bd2bf43..00000000
--- a/Test/VSI-Benchmarks/b1.dfy
+++ /dev/null
@@ -1,71 +0,0 @@
-// Spec# and Boogie and Chalice: The program will be
-// the same, except that these languages do not check
-// for any kind of termination. Also, in Spec#, there
-// is an issue of potential overflows.
-
-// Benchmark1
-
-method Add(x: int, y: int) returns (r: int)
- ensures r == x+y;
-{
- r := x;
- if (y < 0) {
- var n := y;
- while (n != 0)
- invariant r == x+y-n && 0 <= -n;
- {
- r := r - 1;
- n := n + 1;
- }
- } else {
- var n := y;
- while (n != 0)
- invariant r == x+y-n && 0 <= n;
- {
- r := r + 1;
- n := n - 1;
- }
- }
-}
-
-method Mul(x: int, y: int) returns (r: int)
- ensures r == x*y;
- decreases x < 0, x;
-{
- if (x == 0) {
- r := 0;
- } else if (x < 0) {
- r := Mul(-x, y);
- r := -r;
- } else {
- r := Mul(x-1, y);
- r := Add(r, y);
- }
-}
-
-// ---------------------------
-
-method Main() {
- TestAdd(3, 180);
- TestAdd(3, -180);
- TestAdd(0, 1);
-
- TestMul(3, 180);
- TestMul(3, -180);
- TestMul(180, 3);
- TestMul(-180, 3);
- TestMul(0, 1);
- TestMul(1, 0);
-}
-
-method TestAdd(x: int, y: int) {
- print x, " + ", y, " = ";
- var z := Add(x, y);
- print z, "\n";
-}
-
-method TestMul(x: int, y: int) {
- print x, " * ", y, " = ";
- var z := Mul(x, y);
- print z, "\n";
-}
diff --git a/Test/VSI-Benchmarks/b2.dfy b/Test/VSI-Benchmarks/b2.dfy
deleted file mode 100644
index 3046621b..00000000
--- a/Test/VSI-Benchmarks/b2.dfy
+++ /dev/null
@@ -1,57 +0,0 @@
-
-class Benchmark2 {
- method BinarySearch(a: array<int>, key: int) returns (result: int)
- requires a != null;
- requires (forall i, j :: 0 <= i && i < j && j < a.Length ==> a[i] <= a[j]);
- ensures -1 <= result && result < a.Length;
- ensures 0 <= result ==> a[result] == key;
- ensures result == -1 ==> (forall i :: 0 <= i && i < a.Length ==> a[i] != key);
- {
- var low := 0;
- var high := a.Length;
-
- while (low < high)
- invariant 0 <= low && low <= high && high <= a.Length;
- invariant (forall i :: 0 <= i && i < low ==> a[i] < key);
- invariant (forall i :: high <= i && i < a.Length ==> key < a[i]);
- {
- var mid := low + (high - low) / 2;
- var midVal := a[mid];
-
- if (midVal < key) {
- low := mid + 1;
- } else if (key < midVal) {
- high := mid;
- } else {
- result := mid; // key found
- return;
- }
- }
- result := -1; // key not present
- }
-}
-
-method Main() {
- var a := new int[5];
- a[0] := -4;
- a[1] := -2;
- a[2] := -2;
- a[3] := 0;
- a[4] := 25;
- TestSearch(a, 4);
- TestSearch(a, -8);
- TestSearch(a, -2);
- TestSearch(a, 0);
- TestSearch(a, 23);
- TestSearch(a, 25);
- TestSearch(a, 27);
-}
-
-method TestSearch(a: array<int>, key: int)
- requires a != null;
- requires (forall i, j :: 0 <= i && i < j && j < a.Length ==> a[i] <= a[j]);
-{
- var b := new Benchmark2;
- var r := b.BinarySearch(a, key);
- print "Looking for key=", key, ", result=", r, "\n";
-}
diff --git a/Test/VSI-Benchmarks/b3.dfy b/Test/VSI-Benchmarks/b3.dfy
deleted file mode 100644
index 7cf3de07..00000000
--- a/Test/VSI-Benchmarks/b3.dfy
+++ /dev/null
@@ -1,136 +0,0 @@
-// Note: We used integers instead of a generic Comparable type, because
-// Dafny has no way of saying that the Comparable type's AtMost function
-// is total and transitive.
-
-// Note: We couldn't get things to work out if we used the Get method.
-// Instead, we used .contents.
-
-// Note: Due to infelicities of the Dafny sequence treatment, we
-// needed to supply two lemmas, do a complicated assignment of
-// pperm, had to write invariants over p and perm rather than pperm and we couldn't use
-// "x in p".
-
-class Queue<T> {
- var contents: seq<T>;
- method Init()
- modifies this;
- ensures |contents| == 0;
- method Enqueue(x: T)
- modifies this;
- ensures contents == old(contents) + [x];
- method Dequeue() returns (x: T)
- requires 0 < |contents|;
- modifies this;
- ensures contents == old(contents)[1..] && x == old(contents)[0];
- function method Head(): T
- requires 0 < |contents|;
- reads this;
- { contents[0] }
- function method Get(i: int): T
- requires 0 <= i && i < |contents|;
- reads this;
- { contents[i] }
-}
-
-class Comparable {
- function AtMost(c: Comparable): bool
- reads this, c;
-}
-
-
-class Benchmark3 {
-
- method Sort(q: Queue<int>) returns (r: Queue<int>, ghost perm: seq<int>)
- requires q != null;
- modifies q;
- ensures r != null && fresh(r);
- ensures |r.contents| == |old(q.contents)|;
- ensures (forall i, j :: 0 <= i && i < j && j < |r.contents| ==>
- r.Get(i) <= r.Get(j));
- //perm is a permutation
- ensures |perm| == |r.contents|; // ==|pperm|
- ensures (forall i :: 0 <= i && i < |perm|==> 0 <= perm[i] && perm[i] < |perm| );
- ensures (forall i, j :: 0 <= i && i < j && j < |perm| ==> perm[i] != perm[j]);
- // the final Queue is a permutation of the input Queue
- ensures (forall i :: 0 <= i && i < |perm| ==> r.contents[i] == old(q.contents)[perm[i]]);
- {
- r := new Queue<int>.Init();
- ghost var p := [];
-
- var n := 0;
- while (n < |q.contents|)
- invariant n <= |q.contents|;
- invariant n == |p|;
- invariant (forall i :: 0 <= i && i < n ==> p[i] == i);
- {
- p := p + [n];
- n := n + 1;
- }
- perm := [];
- ghost var pperm := p + perm;
-
- while (|q.contents| != 0)
- invariant |r.contents| == |old(q.contents)| - |q.contents|;
- invariant (forall i, j :: 0 <= i && i < j && j < |r.contents| ==>
- r.contents[i] <= r.contents[j]);
- invariant (forall i, j ::
- 0 <= i && i < |r.contents| &&
- 0 <= j && j < |q.contents|
- ==> r.contents[i] <= q.contents[j]);
-
- // pperm is a permutation
- invariant pperm == p + perm && |p| == |q.contents| && |perm| == |r.contents|;
- invariant (forall i :: 0 <= i && i < |perm| ==> 0 <= perm[i] && perm[i] < |pperm|);
- invariant (forall i :: 0 <= i && i < |p| ==> 0 <= p[i] && p[i] < |pperm|);
- invariant (forall i, j :: 0 <= i && i < j && j < |pperm| ==> pperm[i] != pperm[j]);
- // the current array is that permutation of the input array
- invariant (forall i :: 0 <= i && i < |perm| ==> r.contents[i] == old(q.contents)[perm[i]]);
- invariant (forall i :: 0 <= i && i < |p| ==> q.contents[i] == old(q.contents)[p[i]]);
- {
- var m,k := RemoveMin(q);
- perm := perm + [p[k]]; //adds index of min to perm
- p := p[k+1..] + p[..k]; //remove index of min from p
- r.Enqueue(m);
- pperm := pperm[k+1..|p|+1] + pperm[..k] + pperm[|p|+1..] + [pperm[k]];
- }
- }
-
-
- method RemoveMin(q: Queue<int>) returns (m: int, k: int) //m is the min, k is m's index in q
- requires q != null && |q.contents| != 0;
- modifies q;
- ensures |old(q.contents)| == |q.contents| + 1;
- ensures 0 <= k && k < |old(q.contents)| && old(q.contents[k]) == m;
- ensures (forall i :: 0 <= i && i < |q.contents| ==> m <= q.contents[i]);
- ensures q.contents == old(q.contents)[k+1..] + old(q.contents)[..k];
- {
- var n := |q.contents|;
- k := 0;
- m := q.Head();
- var j := 0;
-
- while (j < n)
- invariant j <= n;
- invariant q.contents == old(q.contents)[j..] + old(q.contents)[..j]; //i.e. rotated
- invariant 0 <= k && k < |old(q.contents)| && old(q.contents)[k] == m;
- invariant (forall i :: 0<= i && i < j ==> m <= old(q.contents)[i]); //m is min so far
- {
- var x := q.Dequeue();
- q.Enqueue(x);
- if (x < m) { k := j; m := x; }
- j := j+1;
- }
-
- j := 0;
- while (j < k)
- invariant j <= k;
- invariant q.contents == old(q.contents)[j..] + old(q.contents)[..j];
- {
- var x := q.Dequeue();
- q.Enqueue(x);
- j := j+1;
- }
-
- m := q.Dequeue();
- }
-}
diff --git a/Test/VSI-Benchmarks/b4.dfy b/Test/VSI-Benchmarks/b4.dfy
deleted file mode 100644
index d5a56df4..00000000
--- a/Test/VSI-Benchmarks/b4.dfy
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- This test works with Z3 3.2 and Z3 4.1 (on Win7 x64). Other versions ... who knows.
-*/
-
-// Note: We are using the built-in equality to compare keys.
-// Note: The abstract specifications would do well with a map from keys
-// to values. However, Dafny does not support maps. Instead, such a
-// map is modeled by two sequences, one for the keys and one for the values.
-// The indices in these sequences correspond, so the dictionary maps
-// Keys[i] to Values[i].
-// The implementation uses a linked list, which isn't the most efficient
-// representation of a dictionary. However, for the benchmark, it shows
-// that the specification can use mathematical sequences while the
-// implementation uses a linked list.
-
-class Map<Key(==),Value> {
- ghost var Keys: seq<Key>;
- ghost var Values: seq<Value>;
- ghost var Repr: set<object>;
-
- var head: Node<Key,Value>;
- ghost var nodes: seq<Node<Key,Value>>;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- |Keys| == |Values| && |nodes| == |Keys| + 1 &&
- head == nodes[0] &&
- (forall i :: 0 <= i && i < |Keys| ==>
- nodes[i] != null &&
- nodes[i] in Repr &&
- nodes[i].key == Keys[i] && nodes[i].key !in Keys[i+1..] &&
- nodes[i].val == Values[i] &&
- nodes[i].next == nodes[i+1]) &&
- nodes[|nodes|-1] == null
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- ensures |Keys| == 0;
- {
- Keys := [];
- Values := [];
- Repr := {this};
- head := null;
- nodes := [null];
- }
-
- method Find(key: Key) returns (present: bool, val: Value)
- requires Valid();
- ensures !present ==> key !in Keys;
- ensures present ==> (exists i :: 0 <= i && i < |Keys| && Keys[i] == key && Values[i] == val);
- {
- var p, n, prev := FindIndex(key);
- if (p == null) {
- present := false;
- } else {
- val := p.val;
- present := true;
- }
- }
-
- method Add(key: Key, val: Value)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures (forall i :: 0 <= i && i < |old(Keys)| && old(Keys)[i] == key ==>
- |Keys| == |old(Keys)| &&
- Keys[i] == key && Values[i] == val &&
- (forall j :: 0 <= j && j < |Values| && i != j ==>
- Keys[j] == old(Keys)[j] && Values[j] == old(Values)[j]));
- ensures key !in old(Keys) ==> Keys == [key] + old(Keys) && Values == [val] + old(Values);
- {
- var p, n, prev := FindIndex(key);
- if (p == null) {
- var h := new Node<Key,Value>;
- h.key := key; h.val := val; h.next := head;
- head := h;
- Keys := [key] + Keys; Values := [val] + Values;
- nodes := [h] + nodes;
- Repr := Repr + {h};
- } else {
- p.val := val;
- Values := Values[n := val];
- }
- }
-
- method Remove(key: Key)// returns (ghost h: int)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- // no key is introduced:
- ensures (forall k :: k in Keys ==> k in old(Keys));
- // at most one key is removed:
- ensures (forall k :: k in old(Keys) ==> k in Keys || k == key);
- // other values don't change:
- ensures key !in old(Keys) ==> Keys == old(Keys) && Values == old(Values);
- ensures key in old(Keys) ==>
- |Keys| == |old(Keys)| - 1 && key !in Keys &&
- (exists h ::
- 0 <= h && h < |old(Keys)| &&
- Keys[..h] == old(Keys)[..h] &&
- Values[..h] == old(Values)[..h] &&
- Keys[h..] == old(Keys)[h+1..] &&
- Values[h..] == old(Values)[h+1..]);
- {
- var p, n, prev := FindIndex(key);
- if (p != null) {
- Keys := Keys[..n] + Keys[n+1..];
- Values := Values[..n] + Values[n+1..];
-
- nodes := nodes[..n] + nodes[n+1..];
- if (prev == null) {
- head := head.next;
- } else {
- prev.next := p.next;
- }
- assert Keys[n..] == old(Keys)[n+1..];
- assert Values[n..] == old(Values)[n+1..];
- }
- }
-
- /*private*/ method FindIndex(key: Key) returns (p: Node<Key,Value>, ghost n: int, prev: Node<Key,Value>)
- requires Valid();
- ensures p == null ==> key !in Keys;
- ensures p != null ==>
- 0 <= n && n < |Keys| && Keys[n] == key &&
- key !in Keys[..n] && key !in Keys[n+1..] &&
- p == nodes[n] &&
- ((n == 0 && prev == null) || (0 < n && prev == nodes[n-1]));
- {
- n := 0;
- prev := null;
- p := head;
- while (p != null)
- invariant n <= |Keys| && p == nodes[n];
- invariant key !in Keys[..n];
- invariant (n == 0 && prev == null) || (0 < n && prev == nodes[n-1]);
- decreases |Keys| - n;
- {
- if (p.key == key) {
- return;
- } else {
- n := n + 1;
- prev := p;
- p := p.next;
- }
- }
- }
-}
-
-class Node<Key,Value> {
- var key: Key;
- var val: Value;
- var next: Node<Key,Value>;
-}
diff --git a/Test/VSI-Benchmarks/b5.dfy b/Test/VSI-Benchmarks/b5.dfy
deleted file mode 100644
index 612b96ba..00000000
--- a/Test/VSI-Benchmarks/b5.dfy
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-class Queue<T> {
- var head: Node<T>;
- var tail: Node<T>;
-
- ghost var contents: seq<T>;
- ghost var footprint: set<object>;
- ghost var spine: set<Node<T>>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in footprint && spine <= footprint &&
- head != null && head in spine &&
- tail != null && tail in spine &&
- tail.next == null &&
- (forall n ::
- n in spine ==>
- n != null && n.footprint <= footprint && this !in n.footprint &&
- n.Valid() &&
- (n.next == null ==> n == tail)) &&
- (forall n ::
- n in spine ==>
- n.next != null ==> n.next in spine) &&
- contents == head.tailContents
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- ensures |contents| == 0;
- {
- var n := new Node<T>.Init();
- head := n;
- tail := n;
- contents := n.tailContents;
- footprint := {this} + n.footprint;
- spine := {n};
- }
-
- method IsEmpty() returns (isEmpty: bool)
- requires Valid();
- ensures isEmpty <==> |contents| == 0;
- {
- isEmpty := head == tail;
- }
-
- method Enqueue(t: T)
- requires Valid();
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures contents == old(contents) + [t];
- {
- var n := new Node<T>.Init();
- n.data := t;
- tail.next := n;
- tail := n;
-
- parallel (m | m in spine) {
- m.tailContents := m.tailContents + [t];
- }
- contents := head.tailContents;
-
- parallel (m | m in spine) {
- m.footprint := m.footprint + n.footprint;
- }
- footprint := footprint + n.footprint;
-
- spine := spine + {n};
- }
-
- method Front() returns (t: T)
- requires Valid();
- requires 0 < |contents|;
- ensures t == contents[0];
- {
- t := head.next.data;
- }
-
- method Dequeue()
- requires Valid();
- requires 0 < |contents|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures contents == old(contents)[1..];
- {
- var n := head.next;
- head := n;
- contents := n.tailContents;
- }
-
-
- method Rotate()
- requires Valid();
- requires 0 < |contents|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures contents == old(contents)[1..] + old(contents)[..1];
- {
- var t := Front();
- Dequeue();
- Enqueue(t);
- }
-
- method RotateAny()
- requires Valid();
- requires 0 < |contents|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures |contents| == |old(contents)|;
- ensures (exists i :: 0 <= i && i <= |contents| &&
- contents == old(contents)[i..] + old(contents)[..i]);
- {
- var t := Front();
- Dequeue();
- Enqueue(t);
- }
-
-}
-
-class Node<T> {
- var data: T;
- var next: Node<T>;
-
- ghost var tailContents: seq<T>;
- ghost var footprint: set<object>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in footprint &&
- (next != null ==> next in footprint && next.footprint <= footprint) &&
- (next == null ==> tailContents == []) &&
- (next != null ==> tailContents == [next.data] + next.tailContents)
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- ensures next == null;
- {
- next := null;
- tailContents := [];
- footprint := {this};
- }
-}
-
-class Main<U> {
- method A<T>(t: T, u: T, v: T)
- {
- var q0 := new Queue<T>.Init();
- var q1 := new Queue<T>.Init();
-
- q0.Enqueue(t);
- q0.Enqueue(u);
-
- q1.Enqueue(v);
-
- assert |q0.contents| == 2;
-
- var w := q0.Front();
- assert w == t;
- q0.Dequeue();
-
- w := q0.Front();
- assert w == u;
-
- assert |q0.contents| == 1;
- assert |q1.contents| == 1;
- }
-
- method Main2(t: U, u: U, v: U, q0: Queue<U>, q1: Queue<U>)
- requires q0 != null && q0.Valid();
- requires q1 != null && q1.Valid();
- requires q0.footprint !! q1.footprint;
- requires |q0.contents| == 0;
- modifies q0.footprint, q1.footprint;
- ensures fresh(q0.footprint - old(q0.footprint));
- ensures fresh(q1.footprint - old(q1.footprint));
- {
- q0.Enqueue(t);
- q0.Enqueue(u);
-
- q1.Enqueue(v);
-
- assert |q0.contents| == 2;
-
- var w := q0.Front();
- assert w == t;
- q0.Dequeue();
-
- w := q0.Front();
- assert w == u;
-
- assert |q0.contents| == 1;
- assert |q1.contents| == old(|q1.contents|) + 1;
- }
-}
diff --git a/Test/VSI-Benchmarks/b6.dfy b/Test/VSI-Benchmarks/b6.dfy
deleted file mode 100644
index fda9ca74..00000000
--- a/Test/VSI-Benchmarks/b6.dfy
+++ /dev/null
@@ -1,135 +0,0 @@
-
-class Collection<T> {
- ghost var footprint:set<object>;
- var elements:seq<T>;
-
- function Valid():bool
- reads this, footprint;
- {
- this in footprint
- }
-
- method GetCount() returns (c:int)
- requires Valid();
- ensures 0<=c;
- {
- c:=|elements|;
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(footprint -{this});
- {
- elements := [];
- footprint := {this};
- }
-
- method GetItem(i:int ) returns (x:T)
- requires Valid();
- requires 0<=i && i<|elements|;
- ensures elements[i] ==x;
- {
- x:=elements[i];
- }
-
- method Add(x:T )
- requires Valid();
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures elements == old(elements) + [x];
- {
- elements:= elements + [x];
- }
-
- method GetIterator() returns (iter:Iterator<T>)
- requires Valid();
- ensures iter != null && iter.Valid();
- ensures fresh(iter.footprint) && iter.pos == -1;
- ensures iter.c == this;
- {
- iter:= new Iterator<T>.Init(this);
- }
-
-}
-
-class Iterator<T> {
-
- var c:Collection<T>;
- var pos:int;
-
- ghost var footprint:set<object>;
-
- function Valid():bool
- reads this, footprint;
- {
- this in footprint && c != null && -1 <= pos && null !in footprint
- }
-
- method Init(coll:Collection<T>)
- requires coll != null;
- modifies this;
- ensures Valid() && fresh(footprint - {this}) && pos == -1;
- ensures c == coll;
- {
- c := coll;
- pos := -1;
- footprint := {this};
- }
-
- method MoveNext() returns (b:bool)
- requires Valid();
- modifies footprint;
- ensures fresh(footprint - old(footprint)) && Valid() && pos == old(pos) + 1;
- ensures b == HasCurrent() && c == old(c);
- {
- pos := pos+1;
- b := pos < |c.elements|;
- }
-
- function HasCurrent():bool //???
- requires Valid();
- reads this, c;
- {
- 0 <= pos && pos < |c.elements|
- }
-
- method GetCurrent() returns (x:T)
- requires Valid() && HasCurrent();
- ensures c.elements[pos] == x;
- {
- x := c.elements[pos];
- }
-}
-
-class Client
-{
-
- method Main()
- {
- var c := new Collection<int>.Init();
- c.Add(33);
- c.Add(45);
- c.Add(78);
-
- var s := [];
-
- var iter := c.GetIterator();
- var b := iter.MoveNext();
-
- while (b)
- invariant iter.Valid() && b == iter.HasCurrent() && fresh(iter.footprint);
- invariant c.Valid() && fresh(c.footprint) && iter.footprint !! c.footprint; //disjoint footprints
- invariant 0 <= iter.pos && iter.pos <=|c.elements| && s == c.elements[..iter.pos] ;
- invariant iter.c == c;
- decreases |c.elements| - iter.pos;
- {
- var x := iter.GetCurrent();
- s := s + [x];
- b := iter.MoveNext();
- }
-
- assert s == c.elements; //verifies that the iterator returns the correct things
- c.Add(100);
- }
-
-}
diff --git a/Test/VSI-Benchmarks/b7.dfy b/Test/VSI-Benchmarks/b7.dfy
deleted file mode 100644
index d6759c5f..00000000
--- a/Test/VSI-Benchmarks/b7.dfy
+++ /dev/null
@@ -1,152 +0,0 @@
-// Edited B6 to include GetChar and PutChar
-
-//This is the Queue from Benchmark 3.
-
-//restriction:we assume streams are finite
-//what else can we specify?
-
-
-class Queue<T> {
- var contents: seq<T>;
- method Init()
- modifies this;
- ensures |contents| == 0;
- method Enqueue(x: T)
- modifies this;
- ensures contents == old(contents) + [x];
- method Dequeue() returns (x: T)
- requires 0 < |contents|;
- modifies this;
- ensures contents == old(contents)[1..] && x == old(contents)[0];
- function Head(): T
- requires 0 < |contents|;
- reads this;
- { contents[0] }
- function Get(i: int): T
- requires 0 <= i && i < |contents|;
- reads this;
- { contents[i] }
-}
-
-class Stream {
- ghost var footprint:set<object>;
- var stream:seq<int>;
- var isOpen:bool;
-
- function Valid():bool
- reads this, footprint;
- {
- null !in footprint && this in footprint && isOpen
- }
-
- method GetCount() returns (c:int)
- requires Valid();
- ensures 0 <= c;
- {
- c := |stream|;
- }
-
- method Create() //writing
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- ensures stream == [];
- {
- stream := [];
- footprint := {this};
- isOpen := true;
- }
-
- method Open() //reading
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- {
- footprint := {this};
- isOpen := true;
- }
-
- method PutChar(x:int )
- requires Valid();
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures stream == old(stream) + [x];
- {
- stream:= stream + [x];
- }
-
- method GetChar()returns(x:int)
- requires Valid() && 0 < |stream|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures x ==old(stream)[0];
- ensures stream == old(stream)[1..];
- {
- x := stream[0];
- stream := stream[1..];
- }
-
- method AtEndOfStream() returns(eos:bool)
- requires Valid();
- ensures eos <==> |stream| == 0;
- {
- eos := |stream| == 0;
- }
-
- method Close()
- requires Valid();
- modifies footprint;
- {
- isOpen := false;
- }
-}
-
-
-class Client {
- method Sort(q: Queue<int>) returns (r: Queue<int>, perm:seq<int>)
- requires q != null;
- modifies q;
- ensures r != null && fresh(r);
- ensures |r.contents| == |old(q.contents)|;
- ensures (forall i, j :: 0 <= i && i < j && j < |r.contents| ==>
- r.Get(i) <= r.Get(j));
- //perm is a permutation
- ensures |perm| == |r.contents|; // ==|pperm|
- ensures (forall i: int :: 0 <= i && i < |perm|==> 0 <= perm[i] && perm[i] < |perm| );
- ensures (forall i, j: int :: 0 <= i && i < j && j < |perm| ==> perm[i] != perm[j]);
- // the final Queue is a permutation of the input Queue
- ensures (forall i: int :: 0 <= i && i < |perm| ==> r.contents[i] == old(q.contents)[perm[i]]);
-
-
- method Main()
- {
- var rd := new Stream;
- rd.Open();
-
- var q := new Queue<int>;
- while (true)
- invariant rd.Valid() && fresh(rd.footprint) && fresh(q);
- decreases |rd.stream|;
- {
- var eos := rd.AtEndOfStream();
- if (eos) {
- break;
- }
-
- var ch := rd.GetChar();
- q.Enqueue(ch);
- }
-
- rd.Close();
- var perm;
- q,perm := Sort(q);
-
- var wr := new Stream;
- wr.Create();
- while (0 < |q.contents|)
- invariant wr.Valid() && fresh(wr.footprint) && fresh(q) && q !in wr.footprint;
- {
- var ch := q.Dequeue();
- wr.PutChar(ch);
- }
- wr.Close();
- }
-}
diff --git a/Test/VSI-Benchmarks/b8.dfy b/Test/VSI-Benchmarks/b8.dfy
deleted file mode 100644
index 2149df25..00000000
--- a/Test/VSI-Benchmarks/b8.dfy
+++ /dev/null
@@ -1,352 +0,0 @@
-// Benchmark 8
-
-// A dictionary is a mapping between words and sequences of words
-// to set up the dictionary in main we will read a stream of words and put them into the mapping - the first element of the stream is the term,
-// the following words (until we read null) form the terms definition. Then the stream provides the next term etc.
-
-class Queue<T> {
- var contents: seq<T>;
- method Init()
- modifies this;
- ensures |contents| == 0;
- method Enqueue(x: T)
- modifies this;
- ensures contents == old(contents) + [x];
- method Dequeue() returns (x: T)
- requires 0 < |contents|;
- modifies this;
- ensures contents == old(contents)[1..] && x == old(contents)[0];
- function Head(): T
- requires 0 < |contents|;
- reads this;
- { contents[0] }
- function Get(i: int): T
- requires 0 <= i && i < |contents|;
- reads this;
- { contents[i] }
-}
-
-
-class Glossary {
- method Sort(q: Queue<Word>) returns (r: Queue<Word>, perm:seq<int>)
- requires q != null;
- modifies q;
- ensures r != null && fresh(r);
- ensures |r.contents| == |old(q.contents)|;
- ensures (forall i, j :: 0 <= i && i < j && j < |r.contents| ==>
- r.Get(i) != null &&
- r.Get(i).AtMost(r.Get(j)));
- //perm is a permutation
- ensures |perm| == |r.contents|; // ==|pperm|
- ensures (forall i: int :: 0 <= i && i < |perm|==> 0 <= perm[i] && perm[i] < |perm| );
- ensures (forall i, j: int :: 0 <= i && i < j && j < |perm| ==> perm[i] != perm[j]);
- // the final Queue is a permutation of the input Queue
- ensures (forall i: int :: 0 <= i && i < |perm| ==> r.contents[i] == old(q.contents)[perm[i]]);
-
- method Main()
- {
- var rs:= new ReaderStream;
- rs.Open();
- var glossary := new Map<Word,seq<Word>>.Init();
- var q := new Queue<Word>.Init();
-
- while (true)
- invariant rs.Valid() && fresh(rs.footprint);
- invariant glossary.Valid();
- invariant glossary !in rs.footprint;
- invariant null !in glossary.keys;
- invariant (forall d :: d in glossary.values ==> null !in d);
- invariant q !in rs.footprint;
- invariant q.contents == glossary.keys;
- decreases *; // we leave out the decreases clause - unbounded stream
- {
- var term,definition := readDefinition(rs);
- if (term == null) {
- break;
- }
- var present, d := glossary.Find(term);
- if (!present) {
- glossary.Add(term,definition);
- q.Enqueue(term);
- }
- }
-
- rs.Close();
- var p;
- q,p := Sort(q);
- var wr := new WriterStream;
- wr.Create();
-
- while (0 < |q.contents|)
- invariant wr.Valid() && fresh(wr.footprint);
- invariant glossary.Valid();
- invariant glossary !in wr.footprint && null !in glossary.keys;
- invariant (forall d :: d in glossary.values ==> null !in d);
- invariant q !in wr.footprint;
- invariant (forall k :: k in q.contents ==> k in glossary.keys);
- {
- var term := q.Dequeue();
- var present,definition := glossary.Find(term);
- assert present;
-
- // write term with a html anchor
- wr.PutWordInsideTag(term, term);
- var i := 0;
-
- var qcon := q.contents;
- while (i < |definition|)
- invariant wr.Valid() && fresh(wr.footprint);
- invariant glossary.Valid();
- invariant glossary !in wr.footprint && null !in glossary.keys;
- invariant (forall d :: d in glossary.values ==> null !in d);
- invariant q !in wr.footprint;
- invariant qcon == q.contents;
- invariant (forall k :: k in q.contents ==> k in glossary.keys);
- {
- var w := definition[i];
- var d;
- present, d := glossary.Find(w);
- if (present)
- {
- wr. PutWordInsideHyperlink(w, w);
- }
- else
- {
- wr. PutWord(w);
- }
- i:= i +1;
- }
- }
- wr.Close();
- }
-
-
- method readDefinition(rs:ReaderStream) returns (term:Word, definition:seq<Word>)
- requires rs != null && rs.Valid();
- modifies rs.footprint;
- ensures rs.Valid() && fresh(rs.footprint - old(rs.footprint));
- ensures term != null ==> null !in definition;
- {
- term := rs.GetWord();
- if (term != null)
- {
- definition := [];
- while (true)
- invariant rs.Valid() && fresh(rs.footprint - old(rs.footprint));
- invariant null !in definition;
- decreases *; // we leave out the decreases clause - unbounded stream
- {
- var w := rs.GetWord();
- if (w == null)
- {
- break;
- }
- definition := definition + [w];
- }
- }
- }
-}
-
-class Word
-{
- function AtMost(w: Word): bool
-}
-
-class ReaderStream {
- ghost var footprint: set<object>;
- var isOpen: bool;
-
- function Valid(): bool
- reads this, footprint;
- {
- null !in footprint && this in footprint && isOpen
- }
-
- method Open() //reading
- modifies this;
- ensures Valid() && fresh(footprint -{this});
- {
- footprint := {this};
- isOpen :=true;
- }
-
- method GetWord() returns (x: Word)
- requires Valid();
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- {
- }
-
- method Close()
- requires Valid();
- modifies footprint;
- {
- isOpen := false;
- }
-}
-
-class WriterStream {
- ghost var footprint:set<object>;
- var stream:seq<int>;
- var isOpen:bool;
-
- function Valid(): bool
- reads this, footprint;
- {
- null !in footprint && this in footprint && isOpen
- }
-
- method Create() //writing
- modifies this;
- ensures Valid() && fresh(footprint -{this});
- ensures stream == [];
- {
- stream := [];
- footprint := {this};
- isOpen:= true;
- }
- method GetCount() returns (c:int)
- requires Valid();
- ensures 0<=c;
- {
- c:=|stream|;
- }
-
- method PutWord(w:Word )
- requires Valid();
- requires w != null;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures old(stream)<= stream;
- {
- }
-
- method PutWordInsideTag(tag:Word,w:Word )
- requires Valid();
- requires tag != null && w != null;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures old(stream)<= stream;
- {
- }
-
- method PutWordInsideHyperlink(tag:Word,w:Word )
- requires Valid();
- requires tag != null && w != null;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures old(stream)<= stream;
- {
- }
-
- method Close()
- requires Valid();
- modifies footprint;
- {
- isOpen := false;
- }
-}
-
-
-
-
-class Map<Key(==),Value> {
- var keys: seq<Key>;
- var values: seq<Value>;
-
- function Valid(): bool
- reads this;
- {
- |keys| == |values| &&
- (forall i, j :: 0 <= i && i < j && j < |keys| ==> keys[i] != keys[j])
- }
-
- method Init()
- modifies this;
- ensures Valid() && |keys| == 0;
- {
- keys := [];
- values := [];
- }
-
- method Find(key: Key) returns (present: bool, val: Value)
- requires Valid();
- ensures !present ==> key !in keys;
- ensures present ==> (exists i :: 0 <= i && i < |keys| &&
- keys[i] == key && values[i] == val);
- {
- var j := FindIndex(key);
- if (j == -1) {
- present := false;
- } else {
- present := true;
- val := values[j];
- }
- }
-
- method Add(key: Key, val: Value)
- requires Valid();
- modifies this;
- ensures Valid();
- ensures (forall i :: 0 <= i && i < |old(keys)| && old(keys)[i] == key ==>
- |keys| == |old(keys)| &&
- keys[i] == key && values[i] == val &&
- (forall j :: 0 <= j && j < |values| && i != j ==> keys[j] == old(keys)[j] && values[j] == old(values)[j]));
- ensures key !in old(keys) ==> keys == old(keys) + [key] && values == old(values) + [val];
- {
- var j := FindIndex(key);
- if (j == -1) {
- keys := keys + [key];
- values := values + [val];
- } else {
- values := values[j := val];
- }
- }
-
- method Remove(key: Key)
- requires Valid();
- modifies this;
- ensures Valid();
- // no key is introduced:
- ensures (forall k :: k in keys ==> k in old(keys));
- // at most one key is removed:
- ensures (forall k :: k in old(keys) ==> k in keys || k == key);
- // the given key is not there:
- // other values don't change:
- ensures key !in old(keys) ==> keys == old(keys) && values == old(values);
- ensures key in old(keys) ==>
- |keys| == |old(keys)| - 1 && key !in keys &&
- (exists h ::
- 0 <= h && h <= |keys| &&
- keys[..h] == old(keys)[..h] &&
- values[..h] == old(values)[..h] &&
- keys[h..] == old(keys)[h+1..] &&
- values[h..] == old(values)[h+1..]);
- {
- var j := FindIndex(key);
- if (0 <= j) {
- keys := keys[..j] + keys[j+1..];
- values := values[..j] + values[j+1..];
- }
- }
-
- method FindIndex(key: Key) returns (idx: int)
- requires Valid();
- ensures -1 <= idx && idx < |keys|;
- ensures idx == -1 ==> key !in keys;
- ensures 0 <= idx ==> keys[idx] == key;
- {
- var j := 0;
- while (j < |keys|)
- invariant j <= |keys|;
- invariant key !in keys[..j];
- {
- if (keys[j] == key) {
- idx := j;
- return;
- }
- j := j + 1;
- }
- idx := -1;
- }
-}
diff --git a/Test/VSI-Benchmarks/runtest.bat b/Test/VSI-Benchmarks/runtest.bat
deleted file mode 100644
index f5b9d1b9..00000000
--- a/Test/VSI-Benchmarks/runtest.bat
+++ /dev/null
@@ -1,11 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-for %%f in (b1.dfy b2.dfy b3.dfy b4.dfy b5.dfy b6.dfy b7.dfy b8.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 %* %%f
-)
diff --git a/Test/dafny0/AdvancedLHS.dfy b/Test/dafny0/AdvancedLHS.dfy
deleted file mode 100644
index f1fc7d48..00000000
--- a/Test/dafny0/AdvancedLHS.dfy
+++ /dev/null
@@ -1,58 +0,0 @@
-class C {
- var x: C;
-
- method M(S: set<C>, a: array<C>, b: array2<C>)
- requires S != {};
- modifies this, a, b;
- {
- x := new C;
- x := new C.Init();
- x := *;
- x := choose S;
-
- // test evaluation order
- var c := x;
- x := null;
- x := new C.InitOther(x); // since the parameter is evaluated before the LHS is set, the precondition is met
- assert x != c;
-
- // test evaluation order and modification
- if (*) {
- var k := this.x;
- var kx := this.x.x;
- this.x.x := new C.InitAndMutate(this);
- assert this.x == null;
- assert this.x != k;
- assert k.x != kx; // because it was set to a new object
- assert fresh(k.x);
- } else {
- var k := this.x;
- var kx := this.x.x;
- this.x.x := new C.InitAndMutate(this);
- var t := this.x.x; // error: null dereference (because InitAndMutate set this.x to null)
- }
-
- if (a != null && 10 <= a.Length) {
- a[2] := new C;
- a[3] := *;
- }
- if (b != null && 10 <= b.Length0 && 20 <= b.Length1) {
- b[2,14] := new C;
- b[3,11] := *;
- }
- }
-
- method Init() { }
- method InitOther(c: C)
- requires c == null;
- {
- var d := new int[if c == null then 10 else -3]; // run-time error if c were non-null, but it ain't
- }
- method InitAndMutate(c: C)
- requires c != null;
- modifies c;
- ensures c.x == null;
- {
- c.x := null;
- }
-}
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
deleted file mode 100644
index ee455e7b..00000000
--- a/Test/dafny0/Answer
+++ /dev/null
@@ -1,2098 +0,0 @@
-
--------------------- Simple.dfy --------------------
-// Simple.dfy
-
-class MyClass<T, U> {
- var x: int;
-
- method M(s: bool, lotsaObjects: set<object>)
- returns (t: object, u: set<int>, v: seq<MyClass<bool,U>>)
- requires s;
- modifies this, lotsaObjects;
- ensures t == t;
- ensures old(null) != this;
- {
- x := 12;
- while (x < 100)
- invariant x <= 100;
- {
- x := x + 17;
- if (x % 20 == 3) {
- x := this.x + 1;
- } else {
- this.x := x + 0;
- }
- t, u, v := M(true, lotsaObjects);
- var to: MyClass<T,U>;
- to, u, v := this.M(true, lotsaObjects);
- to, u, v := to.M(true, lotsaObjects);
- assert v[x] != null ==> null !in v[2 .. x][1..][5 := v[this.x]][..10];
- }
- }
-
- function F(x: int, y: int, h: WildData, k: WildData): WildData
- {
- if x < 0 then
- h
- else if x == 0 then
- if if h == k then true else false then
- h
- else if y == 0 then
- k
- else
- h
- else
- k
- }
-}
-
-datatype List<T> = Nil | Cons(T, List<T>);
-
-datatype WildData = Something | JustAboutAnything(bool, myName: set<int>, int, WildData) | More(List<int>);
-
-class C {
- var w: WildData;
- var list: List<bool>;
-}
-
-Dafny program verifier finished with 0 verified, 0 errors
-
--------------------- TypeTests.dfy --------------------
-TypeTests.dfy(4,13): Error: incorrect type of function argument 0 (expected C, got D)
-TypeTests.dfy(4,13): Error: incorrect type of function argument 1 (expected D, got C)
-TypeTests.dfy(5,13): Error: incorrect type of function argument 0 (expected C, got int)
-TypeTests.dfy(5,13): Error: incorrect type of function argument 1 (expected D, got int)
-TypeTests.dfy(11,15): Error: incorrect type of method in-parameter 0 (expected int, got bool)
-TypeTests.dfy(12,11): Error: incorrect type of method out-parameter 0 (expected int, got C)
-TypeTests.dfy(12,11): Error: incorrect type of method out-parameter 1 (expected C, got int)
-TypeTests.dfy(44,9): Error: Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
-TypeTests.dfy(53,6): Error: Duplicate local-variable name: z
-TypeTests.dfy(55,6): Error: Duplicate local-variable name: x
-TypeTests.dfy(58,8): Error: Duplicate local-variable name: x
-TypeTests.dfy(61,6): Error: Duplicate local-variable name: y
-TypeTests.dfy(68,17): Error: member F in type C does not refer to a method
-TypeTests.dfy(69,17): Error: a method called as an initialization method must not have any result arguments
-TypeTests.dfy(78,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(78,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(79,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(79,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(80,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(80,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(82,2): Error: LHS of array assignment must denote an array element (found seq<C>)
-TypeTests.dfy(82,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(82,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(83,2): Error: LHS of array assignment must denote an array element (found seq<C>)
-TypeTests.dfy(83,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(83,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(84,2): Error: LHS of array assignment must denote an array element (found seq<C>)
-TypeTests.dfy(84,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(84,10): Error: cannot assign to a range of array elements (try the 'parallel' statement)
-TypeTests.dfy(90,6): Error: sorry, cannot instantiate collection type with a subrange type
-TypeTests.dfy(91,9): Error: sorry, cannot instantiate type parameter with a subrange type
-TypeTests.dfy(92,8): Error: sorry, cannot instantiate 'array' type with a subrange type
-TypeTests.dfy(93,8): Error: sorry, cannot instantiate 'array' type with a subrange type
-TypeTests.dfy(117,4): Error: cannot assign to non-ghost variable in a ghost context
-TypeTests.dfy(118,7): Error: cannot assign to non-ghost variable in a ghost context
-TypeTests.dfy(18,9): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'NeverendingList' can be constructed
-36 resolution/type errors detected in TypeTests.dfy
-
--------------------- NatTypes.dfy --------------------
-NatTypes.dfy(7,5): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon0
-NatTypes.dfy(31,10): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon0
- NatTypes.dfy(19,3): anon10_LoopHead
- (0,0): anon10_LoopBody
- NatTypes.dfy(19,3): anon11_Else
- (0,0): anon3
- (0,0): anon12_Then
- (0,0): anon9
-NatTypes.dfy(38,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Then
-NatTypes.dfy(40,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Then
-NatTypes.dfy(57,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-NatTypes.dfy(71,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Else
- (0,0): anon6_Then
-NatTypes.dfy(89,19): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-NatTypes.dfy(104,45): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon6_Else
- (0,0): anon7_Else
- (0,0): anon8_Then
-NatTypes.dfy(127,21): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon3_Then
-
-Dafny program verifier finished with 15 verified, 9 errors
-
--------------------- SmallTests.dfy --------------------
-SmallTests.dfy(30,11): Error: index out of range
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(61,36): Error: possible division by zero
-Execution trace:
- (0,0): anon12_Then
-SmallTests.dfy(62,51): Error: possible division by zero
-Execution trace:
- (0,0): anon12_Else
- (0,0): anon3
- (0,0): anon13_Else
-SmallTests.dfy(63,22): Error: target object may be null
-Execution trace:
- (0,0): anon12_Then
- (0,0): anon3
- (0,0): anon13_Then
- (0,0): anon6
-SmallTests.dfy(82,24): Error: target object may be null
-Execution trace:
- (0,0): anon0
- SmallTests.dfy(81,5): anon9_LoopHead
- (0,0): anon9_LoopBody
- (0,0): anon10_Then
-SmallTests.dfy(116,5): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
-SmallTests.dfy(129,9): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-SmallTests.dfy(131,9): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Else
-SmallTests.dfy(171,9): Error: assignment may update an object field not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon22_Else
- (0,0): anon5
- (0,0): anon24_Else
- (0,0): anon11
- (0,0): anon26_Else
- (0,0): anon16
- (0,0): anon28_Then
- (0,0): anon29_Then
- (0,0): anon19
-SmallTests.dfy(195,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Then
-SmallTests.dfy(202,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon3
- (0,0): anon7_Then
-SmallTests.dfy(204,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon3
- (0,0): anon7_Else
-SmallTests.dfy(250,24): Error BP5002: A precondition for this call might not hold.
-SmallTests.dfy(228,30): Related location: This is the precondition that might not hold.
-Execution trace:
- (0,0): anon0
- SmallTests.dfy(245,19): anon3_Else
- (0,0): anon2
-SmallTests.dfy(355,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(365,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(375,6): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-SmallTests.dfy(285,3): Error BP5003: A postcondition might not hold on this return path.
-SmallTests.dfy(279,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon18_Else
- (0,0): anon11
- (0,0): anon23_Then
- (0,0): anon24_Then
- (0,0): anon15
- (0,0): anon25_Else
-SmallTests.dfy(326,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon8_Then
- (0,0): anon7
-SmallTests.dfy(333,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(343,4): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-SmallTests.dfy(387,10): Error BP5003: A postcondition might not hold on this return path.
-SmallTests.dfy(390,41): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon6_Else
-SmallTests.dfy(540,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
- (0,0): anon2
-SmallTests.dfy(554,20): Error: left-hand sides 0 and 1 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon27_Then
- (0,0): anon28_Then
- (0,0): anon4
- (0,0): anon29_Then
- (0,0): anon30_Then
- (0,0): anon9
- (0,0): anon31_Then
- (0,0): anon32_Then
- (0,0): anon12
-SmallTests.dfy(556,15): Error: left-hand sides 1 and 2 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon27_Then
- SmallTests.dfy(549,18): anon28_Else
- (0,0): anon4
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon30_Then
- (0,0): anon9
- (0,0): anon31_Else
- (0,0): anon35_Then
- (0,0): anon36_Then
- (0,0): anon37_Then
- (0,0): anon22
- (0,0): anon38_Then
-SmallTests.dfy(563,25): Error: target object may be null
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(576,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 70 verified, 26 errors
-
--------------------- Definedness.dfy --------------------
-Definedness.dfy(8,7): Error: possible division by zero
-Execution trace:
- (0,0): anon3_Else
-Definedness.dfy(15,16): Error: possible division by zero
-Execution trace:
- (0,0): anon0
-Definedness.dfy(24,16): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Definedness.dfy(25,21): Error: target object may be null
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-Definedness.dfy(26,17): Error: possible division by zero
-Execution trace:
- (0,0): anon0
-Definedness.dfy(33,16): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Definedness.dfy(50,18): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Definedness.dfy(51,3): Error BP5003: A postcondition might not hold on this return path.
-Definedness.dfy(50,22): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Definedness.dfy(57,18): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Definedness.dfy(58,3): Error BP5003: A postcondition might not hold on this return path.
-Definedness.dfy(57,22): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Definedness.dfy(65,3): Error BP5003: A postcondition might not hold on this return path.
-Definedness.dfy(64,22): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Definedness.dfy(85,7): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Definedness.dfy(86,5): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
-Definedness.dfy(86,10): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Definedness.dfy(86,10): Error: assignment may update an object not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
-Definedness.dfy(87,10): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
-Definedness.dfy(92,14): Error: possible division by zero
-Execution trace:
- (0,0): anon0
-Definedness.dfy(92,23): Error: possible division by zero
-Execution trace:
- (0,0): anon0
-Definedness.dfy(93,15): Error: possible division by zero
-Execution trace:
- (0,0): anon0
-Definedness.dfy(98,12): Error: possible division by zero
-Execution trace:
- (0,0): anon0
-Definedness.dfy(105,15): Error: possible division by zero
-Execution trace:
- Definedness.dfy(105,5): anon8_LoopHead
- (0,0): anon8_LoopBody
- Definedness.dfy(105,5): anon9_Else
- (0,0): anon3
-Definedness.dfy(114,23): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
- Definedness.dfy(113,5): anon13_LoopHead
- (0,0): anon13_LoopBody
- (0,0): anon14_Then
-Definedness.dfy(120,17): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
- Definedness.dfy(113,5): anon13_LoopHead
- (0,0): anon13_LoopBody
- Definedness.dfy(113,5): anon14_Else
- (0,0): anon3
- (0,0): anon15_Then
- (0,0): anon6
- Definedness.dfy(119,5): anon16_LoopHead
- (0,0): anon16_LoopBody
- (0,0): anon17_Then
-Definedness.dfy(130,17): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
- Definedness.dfy(129,5): anon7_LoopHead
- (0,0): anon7_LoopBody
- (0,0): anon8_Then
-Definedness.dfy(130,22): Error BP5004: This loop invariant might not hold on entry.
-Execution trace:
- (0,0): anon0
-Definedness.dfy(131,17): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
- Definedness.dfy(129,5): anon7_LoopHead
- (0,0): anon7_LoopBody
- (0,0): anon8_Then
-Definedness.dfy(140,15): Error: possible division by zero
-Execution trace:
- (0,0): anon0
- Definedness.dfy(140,5): anon9_LoopHead
- (0,0): anon9_LoopBody
- Definedness.dfy(140,5): anon10_Else
- (0,0): anon3
-Definedness.dfy(159,15): Error: possible division by zero
-Execution trace:
- (0,0): anon0
- Definedness.dfy(153,5): anon17_LoopHead
- (0,0): anon17_LoopBody
- Definedness.dfy(153,5): anon18_Else
- (0,0): anon3
- (0,0): anon19_Then
- (0,0): anon5
- (0,0): anon20_Then
- (0,0): anon8
- Definedness.dfy(159,5): anon21_LoopHead
- (0,0): anon21_LoopBody
- Definedness.dfy(159,5): anon22_Else
- (0,0): anon11
-Definedness.dfy(172,28): Error BP5004: This loop invariant might not hold on entry.
-Execution trace:
- (0,0): anon0
-Definedness.dfy(178,17): Error: possible violation of function precondition
-Execution trace:
- (0,0): anon0
- Definedness.dfy(170,5): anon19_LoopHead
- (0,0): anon19_LoopBody
- Definedness.dfy(170,5): anon20_Else
- (0,0): anon3
- (0,0): anon21_Then
- (0,0): anon6
- Definedness.dfy(177,5): anon22_LoopHead
- (0,0): anon22_LoopBody
- (0,0): anon23_Then
- (0,0): anon24_Then
- (0,0): anon11
-Definedness.dfy(193,19): Error: possible division by zero
-Execution trace:
- (0,0): anon0
- Definedness.dfy(191,5): anon7_LoopHead
- (0,0): anon7_LoopBody
- (0,0): anon8_Then
-Definedness.dfy(193,23): Error BP5004: This loop invariant might not hold on entry.
-Execution trace:
- (0,0): anon0
-Definedness.dfy(193,28): Error: possible division by zero
-Execution trace:
- (0,0): anon0
- Definedness.dfy(191,5): anon7_LoopHead
- (0,0): anon7_LoopBody
- (0,0): anon8_Then
-Definedness.dfy(212,10): Error BP5003: A postcondition might not hold on this return path.
-Definedness.dfy(214,46): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Else
-Definedness.dfy(221,22): Error: target object may be null
-Execution trace:
- (0,0): anon5_Then
- (0,0): anon2
- (0,0): anon6_Then
-Definedness.dfy(234,10): Error BP5003: A postcondition might not hold on this return path.
-Definedness.dfy(237,24): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon7_Then
- (0,0): anon2
- (0,0): anon8_Else
-
-Dafny program verifier finished with 22 verified, 36 errors
-
--------------------- FunctionSpecifications.dfy --------------------
-FunctionSpecifications.dfy(32,3): Error BP5003: A postcondition might not hold on this return path.
-FunctionSpecifications.dfy(28,13): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon9_Else
- (0,0): anon10_Else
- (0,0): anon11_Then
- (0,0): anon12_Else
- (0,0): anon7
-FunctionSpecifications.dfy(35,10): Error BP5003: A postcondition might not hold on this return path.
-FunctionSpecifications.dfy(37,24): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon12_Else
- (0,0): anon15_Else
- (0,0): anon16_Then
- (0,0): anon11
-FunctionSpecifications.dfy(50,11): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon0
- (0,0): anon9_Then
- (0,0): anon3
-FunctionSpecifications.dfy(56,10): Error BP5003: A postcondition might not hold on this return path.
-FunctionSpecifications.dfy(57,22): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon5_Else
-
-Dafny program verifier finished with 3 verified, 4 errors
-
--------------------- ResolutionErrors.dfy --------------------
-ResolutionErrors.dfy(48,13): Error: 'this' is not allowed in a 'static' context
-ResolutionErrors.dfy(109,9): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(110,9): Error: function calls are allowed only in specification contexts (consider declaring the function a 'function method')
-ResolutionErrors.dfy(114,11): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(115,9): Error: actual out-parameter 0 is required to be a ghost variable
-ResolutionErrors.dfy(122,15): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(126,23): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(133,4): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(137,21): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(138,35): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(147,9): Error: only ghost methods can be called from this context
-ResolutionErrors.dfy(153,16): Error: 'decreases *' is not allowed on ghost loops
-ResolutionErrors.dfy(194,27): Error: ghost-context break statement is not allowed to break out of non-ghost structure
-ResolutionErrors.dfy(217,12): Error: ghost-context break statement is not allowed to break out of non-ghost loop
-ResolutionErrors.dfy(229,12): Error: trying to break out of more loop levels than there are enclosing loops
-ResolutionErrors.dfy(233,12): Error: ghost-context break statement is not allowed to break out of non-ghost loop
-ResolutionErrors.dfy(238,8): Error: return statement is not allowed in this context (because it is guarded by a specification-only expression)
-ResolutionErrors.dfy(10,16): Error: 'decreases *' is not allowed on ghost loops
-ResolutionErrors.dfy(22,11): Error: array selection requires an array2 (got array3<T>)
-ResolutionErrors.dfy(23,12): Error: sequence/array/map selection requires a sequence, array or map (got array3<T>)
-ResolutionErrors.dfy(24,11): Error: array selection requires an array4 (got array<T>)
-ResolutionErrors.dfy(54,14): Error: a field must be selected via an object, not just a class name
-ResolutionErrors.dfy(55,7): Error: unresolved identifier: F
-ResolutionErrors.dfy(56,14): Error: an instance function must be selected via an object, not just a class name
-ResolutionErrors.dfy(56,7): Error: call to instance function requires an instance
-ResolutionErrors.dfy(57,7): Error: unresolved identifier: G
-ResolutionErrors.dfy(59,7): Error: unresolved identifier: M
-ResolutionErrors.dfy(60,7): Error: call to instance method requires an instance
-ResolutionErrors.dfy(61,7): Error: unresolved identifier: N
-ResolutionErrors.dfy(64,8): Error: non-function expression is called with parameters
-ResolutionErrors.dfy(65,14): Error: member z does not exist in class Global
-ResolutionErrors.dfy(84,12): Error: the name 'Benny' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.Benny')
-ResolutionErrors.dfy(89,12): Error: the name 'David' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.David')
-ResolutionErrors.dfy(90,12): Error: the name 'David' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.David')
-ResolutionErrors.dfy(92,12): Error: the name 'David' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.David')
-ResolutionErrors.dfy(94,12): Error: wrong number of arguments to datatype constructor Abc (found 2, expected 1)
-ResolutionErrors.dfy(256,4): Error: label shadows an enclosing label
-ResolutionErrors.dfy(261,2): Error: duplicate label
-ResolutionErrors.dfy(287,4): Error: when allocating an object of type 'ClassWithConstructor', one of its constructor methods must be called
-ResolutionErrors.dfy(288,4): Error: when allocating an object of type 'ClassWithConstructor', one of its constructor methods must be called
-ResolutionErrors.dfy(290,4): Error: a constructor is only allowed to be called when an object is being allocated
-ResolutionErrors.dfy(304,16): Error: arguments must have the same type (got int and DTD_List)
-ResolutionErrors.dfy(305,16): Error: arguments must have the same type (got DTD_List and int)
-ResolutionErrors.dfy(306,25): Error: arguments must have the same type (got bool and int)
-ResolutionErrors.dfy(309,18): Error: ghost fields are allowed only in specification contexts
-ResolutionErrors.dfy(318,15): Error: ghost variables are allowed only in specification contexts
-ResolutionErrors.dfy(343,2): Error: incorrect type of method in-parameter 1 (expected GenericClass<int>, got GenericClass<bool>)
-ResolutionErrors.dfy(355,18): Error: incorrect type of datatype constructor argument (found GList<_T0>, expected GList<int>)
-ResolutionErrors.dfy(363,4): Error: arguments to + must be int or a collection type (instead got bool)
-ResolutionErrors.dfy(368,4): Error: all lines in a calculation must have the same type (got int after bool)
-ResolutionErrors.dfy(371,4): Error: first argument to ==> must be of type bool (instead got int)
-ResolutionErrors.dfy(371,4): Error: second argument to ==> must be of type bool (instead got int)
-ResolutionErrors.dfy(372,8): Error: first argument to ==> must be of type bool (instead got int)
-ResolutionErrors.dfy(372,8): Error: second argument to ==> must be of type bool (instead got int)
-ResolutionErrors.dfy(377,8): Error: first argument to ==> must be of type bool (instead got int)
-ResolutionErrors.dfy(377,8): Error: second argument to ==> must be of type bool (instead got int)
-ResolutionErrors.dfy(382,4): Error: print statement is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
-57 resolution/type errors detected in ResolutionErrors.dfy
-
--------------------- ParseErrors.dfy --------------------
-ParseErrors.dfy(4,19): error: a chain cannot have more than one != operator
-ParseErrors.dfy(6,37): error: this operator chain cannot continue with a descending operator
-ParseErrors.dfy(7,38): error: this operator chain cannot continue with an ascending operator
-ParseErrors.dfy(12,24): error: this operator chain cannot continue with a descending operator
-ParseErrors.dfy(15,18): error: this operator cannot be part of a chain
-ParseErrors.dfy(16,19): error: this operator cannot be part of a chain
-ParseErrors.dfy(17,18): error: this operator cannot be part of a chain
-ParseErrors.dfy(18,18): error: chaining not allowed from the previous operator
-ParseErrors.dfy(46,8): error: the main operator of a calculation must be transitive
-ParseErrors.dfy(62,2): error: this operator cannot continue this calculation
-ParseErrors.dfy(63,2): error: this operator cannot continue this calculation
-ParseErrors.dfy(68,2): error: this operator cannot continue this calculation
-ParseErrors.dfy(69,2): error: this operator cannot continue this calculation
-ParseErrors.dfy(75,2): error: this operator cannot continue this calculation
-14 parse errors detected in ParseErrors.dfy
-
--------------------- Array.dfy --------------------
-Array.dfy(10,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon2
- (0,0): anon6_Then
-Array.dfy(17,16): Error: target object may be null
-Execution trace:
- (0,0): anon0
-Array.dfy(24,6): Error: index out of range
-Execution trace:
- (0,0): anon0
-Array.dfy(48,20): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Array.dfy(56,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon2
- (0,0): anon6_Then
-Array.dfy(63,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon2
- (0,0): anon6_Then
-Array.dfy(107,21): Error: upper bound below lower bound or above length of array
-Execution trace:
- (0,0): anon0
- (0,0): anon14_Else
- (0,0): anon18_Then
- (0,0): anon19_Then
- (0,0): anon20_Then
- (0,0): anon11
-Array.dfy(117,8): Error: insufficient reads clause to read the indicated range of array elements
-Execution trace:
- (0,0): anon9_Else
- (0,0): anon10_Then
- (0,0): anon11_Then
- (0,0): anon12_Then
-Array.dfy(119,8): Error: insufficient reads clause to read the indicated range of array elements
-Execution trace:
- (0,0): anon9_Else
- (0,0): anon10_Then
- (0,0): anon11_Then
- (0,0): anon12_Else
-Array.dfy(120,8): Error: insufficient reads clause to read the indicated range of array elements
-Execution trace:
- (0,0): anon9_Else
- (0,0): anon10_Then
- (0,0): anon11_Then
- (0,0): anon12_Else
-Array.dfy(121,8): Error: insufficient reads clause to read the indicated range of array elements
-Execution trace:
- (0,0): anon9_Else
- (0,0): anon10_Then
- (0,0): anon11_Then
- (0,0): anon12_Else
-Array.dfy(147,6): Error: insufficient reads clause to read array element
-Execution trace:
- (0,0): anon7_Else
- (0,0): anon8_Then
- (0,0): anon9_Then
-Array.dfy(155,6): Error: insufficient reads clause to read array element
-Execution trace:
- (0,0): anon7_Else
- (0,0): anon8_Then
- (0,0): anon9_Then
-Array.dfy(171,6): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
-Array.dfy(178,6): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
-Array.dfy(203,1): Error BP5003: A postcondition might not hold on this return path.
-Array.dfy(202,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Array.dfy(227,1): Error BP5003: A postcondition might not hold on this return path.
-Array.dfy(226,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Array.dfy(233,1): Error BP5003: A postcondition might not hold on this return path.
-Array.dfy(232,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Array.dfy(248,10): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon2
- (0,0): anon6_Then
-Array.dfy(249,5): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon2
- (0,0): anon6_Then
-
-Dafny program verifier finished with 34 verified, 20 errors
-
--------------------- MultiDimArray.dfy --------------------
-MultiDimArray.dfy(53,21): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
- (0,0): anon12_Then
-MultiDimArray.dfy(80,25): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon6_Then
-
-Dafny program verifier finished with 8 verified, 2 errors
-
--------------------- NonGhostQuantifiers.dfy --------------------
-NonGhostQuantifiers.dfy(146,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(150,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(155,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(160,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(164,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(168,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(173,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(178,4): Error: a quantifier involved in a function definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'c'
-NonGhostQuantifiers.dfy(183,13): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'c'
-NonGhostQuantifiers.dfy(13,5): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'n'
-NonGhostQuantifiers.dfy(42,4): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'n'
-NonGhostQuantifiers.dfy(46,4): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'd'
-NonGhostQuantifiers.dfy(50,4): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'n'
-NonGhostQuantifiers.dfy(74,5): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'i'
-NonGhostQuantifiers.dfy(78,5): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'j'
-NonGhostQuantifiers.dfy(88,5): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'j'
-NonGhostQuantifiers.dfy(103,5): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'j'
-NonGhostQuantifiers.dfy(111,10): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'y'
-NonGhostQuantifiers.dfy(120,8): Error: quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'x'
-NonGhostQuantifiers.dfy(137,8): Error: Assignment to non-ghost variable is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
-20 resolution/type errors detected in NonGhostQuantifiers.dfy
-
--------------------- AdvancedLHS.dfy --------------------
-AdvancedLHS.dfy(32,23): Error: target object may be null
-Execution trace:
- (0,0): anon0
- (0,0): anon15_Else
-
-Dafny program verifier finished with 7 verified, 1 error
-
--------------------- ModulesCycle.dfy --------------------
-ModulesCycle.dfy(3,9): Error: module T does not exist
-ModulesCycle.dfy(6,7): Error: module definition contains a cycle (note: parent modules implicitly depend on submodules): A -> D -> C -> B
-2 resolution/type errors detected in ModulesCycle.dfy
-
--------------------- Modules0.dfy --------------------
-Modules0.dfy(5,8): Error: Duplicate name of top-level declaration: WazzupA
-Modules0.dfy(6,11): Error: Duplicate name of top-level declaration: WazzupA
-Modules0.dfy(7,7): Error: Duplicate name of top-level declaration: WazzupA
-Modules0.dfy(10,7): Error: Duplicate name of top-level declaration: WazzupB
-Modules0.dfy(11,8): Error: Duplicate name of top-level declaration: WazzupB
-Modules0.dfy(12,11): Error: Duplicate name of top-level declaration: WazzupB
-Modules0.dfy(53,18): Error: Undeclared top-level type or type parameter: MyClass1 (did you forget to qualify a name?)
-Modules0.dfy(54,18): Error: Undeclared top-level type or type parameter: MyClass2 (did you forget to qualify a name?)
-Modules0.dfy(65,18): Error: Undeclared top-level type or type parameter: MyClass2 (did you forget to qualify a name?)
-Modules0.dfy(72,20): Error: Undeclared top-level type or type parameter: MyClass1 (did you forget to qualify a name?)
-Modules0.dfy(72,34): Error: Undeclared top-level type or type parameter: MyClass0 (did you forget to qualify a name?)
-Modules0.dfy(75,23): Error: Undeclared top-level type or type parameter: MyClass0 (did you forget to qualify a name?)
-Modules0.dfy(80,24): Error: Undeclared top-level type or type parameter: MyClassY (did you forget to qualify a name?)
-Modules0.dfy(89,16): Error: Undeclared top-level type or type parameter: ClassG (did you forget to qualify a name?)
-Modules0.dfy(221,15): Error: Undeclared top-level type or type parameter: X (did you forget to qualify a name?)
-Modules0.dfy(221,8): Error: new can be applied only to reference types (got X)
-Modules0.dfy(230,13): Error: Undeclared type X in module B
-Modules0.dfy(240,13): Error: unresolved identifier: X
-Modules0.dfy(241,15): Error: member DoesNotExist does not exist in class X
-Modules0.dfy(280,19): Error: Undeclared top-level type or type parameter: D (did you forget to qualify a name?)
-Modules0.dfy(280,12): Error: new can be applied only to reference types (got D)
-Modules0.dfy(283,25): Error: type of the receiver is not fully determined at this program point
-Modules0.dfy(284,16): Error: type of the receiver is not fully determined at this program point
-Modules0.dfy(284,6): Error: expected method call, found expression
-Modules0.dfy(285,16): Error: type of the receiver is not fully determined at this program point
-Modules0.dfy(285,6): Error: expected method call, found expression
-Modules0.dfy(307,24): Error: module Q_Imp does not exist
-Modules0.dfy(97,14): Error: Undeclared top-level type or type parameter: MyClassY (did you forget to qualify a name?)
-28 resolution/type errors detected in Modules0.dfy
-
--------------------- Modules1.dfy --------------------
-Modules1.dfy(75,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-Modules1.dfy(88,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-Modules1.dfy(90,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Else
-Modules1.dfy(53,3): Error: decreases expression must be bounded below by 0
-Execution trace:
- (0,0): anon0
-Modules1.dfy(59,3): Error: failure to decrease termination measure
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 22 verified, 5 errors
-
--------------------- Modules2.dfy --------------------
-Modules2.dfy(44,17): Error: The name C ambiguously refers to a type in one of the modules A, B (try qualifying the type name with the module name)
-Modules2.dfy(44,10): Error: new can be applied only to reference types (got C)
-Modules2.dfy(47,14): Error: the name 'E' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'D.E')
-Modules2.dfy(48,14): Error: The name D ambiguously refers to a type in one of the modules A, B
-Modules2.dfy(50,11): Error: The name f ambiguously refers to a static member in one of the modules A, B
-5 resolution/type errors detected in Modules2.dfy
-
--------------------- BadFunction.dfy --------------------
-BadFunction.dfy(6,3): Error: failure to decrease termination measure
-Execution trace:
- (0,0): anon3_Else
-
-Dafny program verifier finished with 2 verified, 1 error
-
--------------------- Comprehensions.dfy --------------------
-Comprehensions.dfy(9,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon9_Then
- (0,0): anon10_Then
- (0,0): anon4
- (0,0): anon11_Then
- (0,0): anon12_Then
- (0,0): anon8
-
-Dafny program verifier finished with 6 verified, 1 error
-
--------------------- Basics.dfy --------------------
-Basics.dfy(42,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Else
-Basics.dfy(66,42): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon13_Then
- (0,0): anon14_Then
- (0,0): anon15_Then
- Basics.dfy(66,72): anon16_Else
- (0,0): anon8
- Basics.dfy(66,82): anon17_Else
- (0,0): anon10
- Basics.dfy(66,95): anon18_Else
- (0,0): anon12
-Basics.dfy(100,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon10_Then
-Basics.dfy(119,10): Error: when left-hand sides 0 and 1 may refer to the same location, they must have the same value
-Execution trace:
- (0,0): anon0
- (0,0): anon10_Then
- (0,0): anon3
- (0,0): anon11_Then
- (0,0): anon6
- (0,0): anon12_Then
- (0,0): anon9
-Basics.dfy(133,10): Error: when left-hand sides 0 and 1 refer to the same location, they must have the same value
-Execution trace:
- (0,0): anon0
-Basics.dfy(145,19): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
-Basics.dfy(147,10): Error: target object may be null
-Execution trace:
- (0,0): anon0
- (0,0): anon3
-Basics.dfy(147,10): Error: assignment may update an object not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3
-Basics.dfy(152,12): Error: left-hand sides 0 and 1 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
- (0,0): anon3
- (0,0): anon12_Then
-Basics.dfy(163,15): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
- (0,0): anon3
- (0,0): anon12_Else
- (0,0): anon6
- (0,0): anon13_Then
- (0,0): anon8
- (0,0): anon14_Then
-Basics.dfy(226,10): Error: when left-hand sides 0 and 1 refer to the same location, they must have the same value
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 32 verified, 11 errors
-
--------------------- ControlStructures.dfy --------------------
-ControlStructures.dfy(5,3): Error: missing case in case statement: Purple
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon7_Else
- (0,0): anon8_Then
-ControlStructures.dfy(5,3): Error: missing case in case statement: Blue
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon7_Else
- (0,0): anon8_Else
- (0,0): anon9_Then
-ControlStructures.dfy(14,3): Error: missing case in case statement: Purple
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon7_Else
- (0,0): anon8_Then
-ControlStructures.dfy(43,5): Error: missing case in case statement: Red
-Execution trace:
- (0,0): anon0
- (0,0): anon8_Then
- (0,0): anon9_Else
- (0,0): anon10_Then
-ControlStructures.dfy(51,3): Error: missing case in case statement: Red
-Execution trace:
- (0,0): anon8_Else
- (0,0): anon9_Else
- (0,0): anon10_Else
- (0,0): anon11_Else
- (0,0): anon12_Then
-ControlStructures.dfy(72,3): Error: alternative cases fail to cover all possibilties
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Else
-ControlStructures.dfy(215,18): Error: assertion violation
-Execution trace:
- (0,0): anon0
- ControlStructures.dfy(194,3): anon62_LoopHead
- (0,0): anon62_LoopBody
- ControlStructures.dfy(194,3): anon63_Else
- (0,0): anon3
- ControlStructures.dfy(194,3): anon64_Else
- ControlStructures.dfy(198,5): anon65_LoopHead
- (0,0): anon65_LoopBody
- ControlStructures.dfy(198,5): anon66_Else
- (0,0): anon8
- ControlStructures.dfy(198,5): anon67_Else
- (0,0): anon71_Then
- ControlStructures.dfy(210,9): anon72_LoopHead
- (0,0): anon72_LoopBody
- ControlStructures.dfy(210,9): anon73_Else
- (0,0): anon20
- (0,0): anon74_Then
- (0,0): anon29
-ControlStructures.dfy(232,21): Error: assertion violation
-Execution trace:
- (0,0): anon0
- ControlStructures.dfy(194,3): anon62_LoopHead
- (0,0): anon62_LoopBody
- ControlStructures.dfy(194,3): anon63_Else
- (0,0): anon3
- ControlStructures.dfy(194,3): anon64_Else
- ControlStructures.dfy(198,5): anon65_LoopHead
- (0,0): anon65_LoopBody
- ControlStructures.dfy(198,5): anon66_Else
- (0,0): anon8
- ControlStructures.dfy(198,5): anon67_Else
- (0,0): anon71_Then
- ControlStructures.dfy(210,9): anon72_LoopHead
- (0,0): anon72_LoopBody
- ControlStructures.dfy(210,9): anon73_Else
- (0,0): anon20
- ControlStructures.dfy(210,9): anon74_Else
- (0,0): anon75_Then
- (0,0): after_4
- ControlStructures.dfy(221,7): anon77_LoopHead
- (0,0): anon77_LoopBody
- ControlStructures.dfy(221,7): anon78_Else
- (0,0): anon33
- ControlStructures.dfy(221,7): anon79_Else
- (0,0): anon81_Then
- (0,0): anon38
- (0,0): after_9
- (0,0): anon86_Then
- (0,0): anon53
-ControlStructures.dfy(235,30): Error: assertion violation
-Execution trace:
- (0,0): anon0
- ControlStructures.dfy(194,3): anon62_LoopHead
- (0,0): anon62_LoopBody
- ControlStructures.dfy(194,3): anon63_Else
- (0,0): anon3
- ControlStructures.dfy(194,3): anon64_Else
- ControlStructures.dfy(198,5): anon65_LoopHead
- (0,0): anon65_LoopBody
- ControlStructures.dfy(198,5): anon66_Else
- (0,0): anon8
- ControlStructures.dfy(198,5): anon67_Else
- (0,0): anon68_Then
- (0,0): after_5
- (0,0): anon87_Then
- (0,0): anon88_Then
- (0,0): anon58
-ControlStructures.dfy(238,17): Error: assertion violation
-Execution trace:
- (0,0): anon0
- ControlStructures.dfy(194,3): anon62_LoopHead
- (0,0): anon62_LoopBody
- ControlStructures.dfy(194,3): anon63_Else
- (0,0): anon3
- ControlStructures.dfy(194,3): anon64_Else
- ControlStructures.dfy(198,5): anon65_LoopHead
- (0,0): anon65_LoopBody
- ControlStructures.dfy(198,5): anon66_Else
- (0,0): anon8
- ControlStructures.dfy(198,5): anon67_Else
- (0,0): anon71_Then
- ControlStructures.dfy(210,9): anon72_LoopHead
- (0,0): anon72_LoopBody
- ControlStructures.dfy(210,9): anon73_Else
- (0,0): anon20
- ControlStructures.dfy(210,9): anon74_Else
- (0,0): anon75_Then
- (0,0): after_4
- ControlStructures.dfy(221,7): anon77_LoopHead
- (0,0): anon77_LoopBody
- ControlStructures.dfy(221,7): anon78_Else
- (0,0): anon33
- ControlStructures.dfy(221,7): anon79_Else
- (0,0): anon82_Then
- (0,0): anon85_Then
- (0,0): after_8
- (0,0): anon89_Then
- (0,0): anon61
-
-Dafny program verifier finished with 18 verified, 10 errors
-
--------------------- Termination.dfy --------------------
-Termination.dfy(105,3): Error: cannot prove termination; try supplying a decreases clause for the loop
-Execution trace:
- (0,0): anon0
- Termination.dfy(105,3): anon7_LoopHead
- (0,0): anon7_LoopBody
- Termination.dfy(105,3): anon8_Else
- (0,0): anon3
- Termination.dfy(105,3): anon9_Else
-Termination.dfy(113,3): Error: cannot prove termination; try supplying a decreases clause for the loop
-Execution trace:
- (0,0): anon0
- Termination.dfy(113,3): anon9_LoopHead
- (0,0): anon9_LoopBody
- Termination.dfy(113,3): anon10_Else
- (0,0): anon11_Then
- (0,0): anon5
- Termination.dfy(113,3): anon12_Else
-Termination.dfy(122,3): Error: decreases expression might not decrease
-Execution trace:
- (0,0): anon0
- Termination.dfy(122,3): anon9_LoopHead
- (0,0): anon9_LoopBody
- Termination.dfy(122,3): anon10_Else
- (0,0): anon11_Then
- (0,0): anon5
- Termination.dfy(122,3): anon12_Else
-Termination.dfy(123,17): Error: decreases expression must be bounded below by 0 at end of loop iteration
-Execution trace:
- (0,0): anon0
- Termination.dfy(122,3): anon9_LoopHead
- (0,0): anon9_LoopBody
- Termination.dfy(122,3): anon10_Else
- (0,0): anon11_Then
- (0,0): anon5
- Termination.dfy(122,3): anon12_Else
-Termination.dfy(251,35): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon6_Else
- (0,0): anon7_Else
- (0,0): anon8_Then
-Termination.dfy(291,3): Error: decreases expression might not decrease
-Execution trace:
- (0,0): anon0
- Termination.dfy(291,3): anon10_LoopHead
- (0,0): anon10_LoopBody
- Termination.dfy(291,3): anon11_Else
- Termination.dfy(291,3): anon12_Else
- (0,0): anon13_Else
-
-Dafny program verifier finished with 45 verified, 6 errors
-
--------------------- DTypes.dfy --------------------
-DTypes.dfy(15,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
-DTypes.dfy(53,18): Error: assertion violation
-Execution trace:
- (0,0): anon0
-DTypes.dfy(117,13): Error: assertion violation
-DTypes.dfy(89,30): Related location: Related location
-Execution trace:
- (0,0): anon0
-DTypes.dfy(123,13): Error: assertion violation
-DTypes.dfy(89,20): Related location: Related location
-Execution trace:
- (0,0): anon0
-DTypes.dfy(133,12): Error: assertion violation
-DTypes.dfy(128,6): Related location: Related location
-DTypes.dfy(89,20): Related location: Related location
-Execution trace:
- (0,0): anon0
-DTypes.dfy(154,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
- (0,0): anon6_Then
- (0,0): anon4
-
-Dafny program verifier finished with 27 verified, 6 errors
-
--------------------- ParallelResolveErrors.dfy --------------------
-ParallelResolveErrors.dfy(7,9): Error: Assignment to non-ghost field is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
-ParallelResolveErrors.dfy(17,6): Error: LHS of assignment must denote a mutable variable or field
-ParallelResolveErrors.dfy(22,6): Error: body of parallel statement is attempting to update a variable declared outside the parallel statement
-ParallelResolveErrors.dfy(40,6): Error: Assignment to non-ghost variable is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
-ParallelResolveErrors.dfy(52,13): Error: set choose operator not supported inside the enclosing parallel statement
-ParallelResolveErrors.dfy(57,13): Error: new allocation not supported in parallel statements
-ParallelResolveErrors.dfy(67,6): Error: the body of the enclosing parallel statement is not allowed to call non-ghost methods
-ParallelResolveErrors.dfy(74,19): Error: trying to break out of more loop levels than there are enclosing loops
-ParallelResolveErrors.dfy(78,18): Error: return statement is not allowed inside a parallel statement
-ParallelResolveErrors.dfy(85,21): Error: trying to break out of more loop levels than there are enclosing loops
-ParallelResolveErrors.dfy(86,20): Error: trying to break out of more loop levels than there are enclosing loops
-ParallelResolveErrors.dfy(87,20): Error: break label is undefined or not in scope: OutsideLoop
-ParallelResolveErrors.dfy(96,24): Error: trying to break out of more loop levels than there are enclosing loops
-ParallelResolveErrors.dfy(97,24): Error: break label is undefined or not in scope: OutsideLoop
-ParallelResolveErrors.dfy(105,2): Warning: the conclusion of the body of this parallel statement will not be known outside the parallel statement; consider using an 'ensures' clause
-ParallelResolveErrors.dfy(106,9): Error: the body of the enclosing parallel statement is not allowed to update heap locations
-15 resolution/type errors detected in ParallelResolveErrors.dfy
-
--------------------- Parallel.dfy --------------------
-Parallel.dfy(31,5): Error BP5002: A precondition for this call might not hold.
-Parallel.dfy(57,14): Related location: This is the precondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon32_Else
- (0,0): anon10
- (0,0): anon33_Then
- (0,0): anon34_Then
- (0,0): anon35_Then
- (0,0): anon14
-Parallel.dfy(35,5): Error: target object may be null
-Execution trace:
- (0,0): anon0
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon32_Else
- (0,0): anon10
- (0,0): anon33_Else
- (0,0): anon16
- (0,0): anon36_Then
- (0,0): anon37_Then
- (0,0): anon38_Then
- (0,0): anon20
-Parallel.dfy(39,18): Error: possible violation of postcondition of parallel statement
-Execution trace:
- (0,0): anon0
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon32_Else
- (0,0): anon10
- (0,0): anon33_Else
- (0,0): anon16
- (0,0): anon36_Else
- (0,0): anon22
- (0,0): anon39_Then
- (0,0): anon40_Then
- (0,0): anon26
-Parallel.dfy(44,19): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon32_Else
- (0,0): anon10
- (0,0): anon33_Else
- (0,0): anon16
- (0,0): anon36_Else
- (0,0): anon22
- (0,0): anon39_Then
- (0,0): anon40_Then
-Parallel.dfy(90,19): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon10_Else
- (0,0): anon3
- (0,0): anon11_Then
-Parallel.dfy(96,20): Error: possible violation of postcondition of parallel statement
-Execution trace:
- (0,0): anon0
- (0,0): anon10_Else
- (0,0): anon3
- (0,0): anon11_Then
- (0,0): anon12_Then
-Parallel.dfy(119,12): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Then
- (0,0): anon7_Then
- (0,0): anon3
-Parallel.dfy(182,12): Error: left-hand sides for different parallel-statement bound variables may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon19_Then
- (0,0): anon20_Then
- (0,0): anon5
-Parallel.dfy(214,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
-Parallel.dfy(226,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
-Parallel.dfy(254,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon5
-Parallel.dfy(270,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon5
-Parallel.dfy(307,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
-
-Dafny program verifier finished with 41 verified, 13 errors
-
--------------------- TypeParameters.dfy --------------------
-TypeParameters.dfy(44,22): Error: assertion violation
-Execution trace:
- (0,0): anon0
-TypeParameters.dfy(66,27): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
- (0,0): anon2
-TypeParameters.dfy(138,12): Error: assertion violation
-TypeParameters.dfy(138,28): Related location: Related location
-Execution trace:
- (0,0): anon0
- (0,0): anon14_Then
- TypeParameters.dfy(138,32): anon15_Else
- (0,0): anon5
-TypeParameters.dfy(140,12): Error: assertion violation
-TypeParameters.dfy(140,33): Related location: Related location
-Execution trace:
- (0,0): anon0
- (0,0): anon17_Then
- TypeParameters.dfy(140,37): anon18_Else
- (0,0): anon11
-TypeParameters.dfy(154,15): Error BP5005: This loop invariant might not be maintained by the loop.
-TypeParameters.dfy(154,38): Related location: Related location
-Execution trace:
- (0,0): anon0
- TypeParameters.dfy(147,3): anon17_LoopHead
- (0,0): anon17_LoopBody
- TypeParameters.dfy(147,3): anon18_Else
- (0,0): anon5
- (0,0): anon20_Then
- (0,0): anon8
- TypeParameters.dfy(153,3): anon21_LoopHead
- (0,0): anon21_LoopBody
- TypeParameters.dfy(153,3): anon22_Else
- (0,0): anon13
- TypeParameters.dfy(153,3): anon24_Else
-
-Dafny program verifier finished with 35 verified, 5 errors
-
--------------------- Datatypes.dfy --------------------
-Datatypes.dfy(79,20): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon20_Else
- (0,0): anon21_Then
- (0,0): anon4
- (0,0): anon22_Else
- (0,0): anon23_Then
- (0,0): anon24_Else
- (0,0): anon25_Then
-Datatypes.dfy(167,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Then
-Datatypes.dfy(169,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon5_Then
-Datatypes.dfy(198,13): Error: destructor 'Car' can only be applied to datatype values constructed by 'XCons'
-Execution trace:
- (0,0): anon0
-Datatypes.dfy(201,17): Error: destructor 'Car' can only be applied to datatype values constructed by 'XCons'
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Then
-Datatypes.dfy(222,17): Error: destructor 'c' can only be applied to datatype values constructed by 'T''
-Execution trace:
- (0,0): anon0
- (0,0): anon5_Then
-
-Dafny program verifier finished with 32 verified, 6 errors
-
--------------------- Coinductive.dfy --------------------
-Coinductive.dfy(10,11): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'Rec_Forever' can be constructed
-Coinductive.dfy(13,11): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'D' can be constructed
-Coinductive.dfy(35,11): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'K' can be constructed
-Coinductive.dfy(61,11): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'NotFiniteEnough_Dt' can be constructed
-Coinductive.dfy(90,8): Error: a recursive copredicate call can only be done in positive positions
-Coinductive.dfy(91,8): Error: a recursive copredicate call can only be done in positive positions
-Coinductive.dfy(92,8): Error: a recursive copredicate call can only be done in positive positions
-Coinductive.dfy(92,21): Error: a recursive copredicate call can only be done in positive positions
-8 resolution/type errors detected in Coinductive.dfy
-
--------------------- Corecursion.dfy --------------------
-Corecursion.dfy(15,13): Error: failure to decrease termination measure (note that only functions without side effects can called co-recursively)
-Execution trace:
- (0,0): anon3_Else
-Corecursion.dfy(50,5): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-
-Dafny program verifier finished with 5 verified, 2 errors
-
--------------------- CoPredicates.dfy --------------------
-CoPredicates.dfy(45,1): Error BP5003: A postcondition might not hold on this return path.
-CoPredicates.dfy(44,11): Related location: This is the postcondition that might not hold.
-CoPredicates.dfy(30,22): Related location: Related location
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 12 verified, 1 error
-
--------------------- TypeAntecedents.dfy --------------------
-TypeAntecedents.dfy(32,13): Error: assertion violation
-Execution trace:
- (0,0): anon0
-TypeAntecedents.dfy(55,1): Error BP5003: A postcondition might not hold on this return path.
-TypeAntecedents.dfy(54,15): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon25_Then
- (0,0): anon6
- (0,0): anon28_Then
- (0,0): anon8
- (0,0): anon29_Else
- (0,0): anon13
- (0,0): anon31_Else
- (0,0): anon18
- (0,0): anon33_Then
- (0,0): anon20
- (0,0): anon34_Then
- (0,0): anon35_Then
- (0,0): anon24
-TypeAntecedents.dfy(63,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon25_Else
- (0,0): anon26_Then
- (0,0): anon27_Else
-
-Dafny program verifier finished with 12 verified, 3 errors
-
--------------------- NoTypeArgs.dfy --------------------
-
-Dafny program verifier finished with 12 verified, 0 errors
-
--------------------- EqualityTypes.dfy --------------------
-EqualityTypes.dfy(31,13): Error: a type declaration that requires equality support cannot be replaced by a codatatype
-EqualityTypes.dfy(32,11): Error: datatype 'Y' is used to refine an arbitrary type with equality support, but 'Y' does not support equality
-EqualityTypes.dfy(37,11): Error: arbitrary type 'X' is not allowed to be replaced by a datatype that takes a different number of type parameters
-EqualityTypes.dfy(38,8): Error: arbitrary type 'Y' is not allowed to be replaced by a class that takes a different number of type parameters
-EqualityTypes.dfy(42,11): Error: datatype 'X' is used to refine an arbitrary type with equality support, but 'X' does not support equality
-EqualityTypes.dfy(43,11): Error: datatype 'Y' is used to refine an arbitrary type with equality support, but 'Y' does not support equality
-EqualityTypes.dfy(63,7): Error: == can only be applied to expressions of types that support equality (got Dt<T>)
-EqualityTypes.dfy(82,8): Error: type parameter 0 (T) passed to method M must support equality (got _T0)
-8 resolution/type errors detected in EqualityTypes.dfy
-
--------------------- SplitExpr.dfy --------------------
-
-Dafny program verifier finished with 5 verified, 0 errors
-
--------------------- LoopModifies.dfy --------------------
-LoopModifies.dfy(6,5): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
-LoopModifies.dfy(17,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(14,4): anon9_LoopHead
- (0,0): anon9_LoopBody
- LoopModifies.dfy(14,4): anon10_Else
- (0,0): anon5
- LoopModifies.dfy(14,4): anon12_Else
-LoopModifies.dfy(46,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(42,4): anon9_LoopHead
- (0,0): anon9_LoopBody
- LoopModifies.dfy(42,4): anon10_Else
- (0,0): anon5
- LoopModifies.dfy(42,4): anon12_Else
-LoopModifies.dfy(61,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(57,4): anon9_LoopHead
- (0,0): anon9_LoopBody
- LoopModifies.dfy(57,4): anon10_Else
- (0,0): anon5
- LoopModifies.dfy(57,4): anon12_Else
-LoopModifies.dfy(74,4): Error: loop modifies clause may violate context's modifies clause
-Execution trace:
- (0,0): anon0
-LoopModifies.dfy(98,8): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(90,4): anon9_LoopHead
- (0,0): anon9_LoopBody
- LoopModifies.dfy(90,4): anon10_Else
- (0,0): anon5
- LoopModifies.dfy(90,4): anon12_Else
-LoopModifies.dfy(146,11): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(134,4): anon17_LoopHead
- (0,0): anon17_LoopBody
- LoopModifies.dfy(134,4): anon18_Else
- (0,0): anon5
- LoopModifies.dfy(134,4): anon20_Else
- LoopModifies.dfy(139,7): anon21_LoopHead
- (0,0): anon21_LoopBody
- LoopModifies.dfy(139,7): anon22_Else
- (0,0): anon12
- LoopModifies.dfy(139,7): anon24_Else
-LoopModifies.dfy(197,10): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(193,4): anon9_LoopHead
- (0,0): anon9_LoopBody
- LoopModifies.dfy(193,4): anon10_Else
- (0,0): anon5
- LoopModifies.dfy(193,4): anon12_Else
-LoopModifies.dfy(285,13): Error: assignment may update an array element not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- LoopModifies.dfy(273,4): anon17_LoopHead
- (0,0): anon17_LoopBody
- LoopModifies.dfy(273,4): anon18_Else
- (0,0): anon5
- LoopModifies.dfy(273,4): anon20_Else
- LoopModifies.dfy(281,7): anon21_LoopHead
- (0,0): anon21_LoopBody
- LoopModifies.dfy(281,7): anon22_Else
- (0,0): anon12
- LoopModifies.dfy(281,7): anon24_Else
-
-Dafny program verifier finished with 23 verified, 9 errors
-
--------------------- Refinement.dfy --------------------
-Refinement.dfy(12,5): Error BP5003: A postcondition might not hold on this return path.
-Refinement.dfy(11,17): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Refinement.dfy[B](12,5): Error BP5003: A postcondition might not hold on this return path.
-Refinement.dfy(30,20): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Refinement.dfy(61,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Refinement.dfy(71,17): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Refinement.dfy(90,12): Error BP5003: A postcondition might not hold on this return path.
-Refinement.dfy(69,15): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon3_Else
-Refinement.dfy(93,3): Error BP5003: A postcondition might not hold on this return path.
-Refinement.dfy(74,15): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Refinement.dfy(180,5): Error BP5003: A postcondition might not hold on this return path.
-Refinement.dfy[IncorrectConcrete](112,15): Related location: This is the postcondition that might not hold.
-Refinement.dfy(177,9): Related location: Related location
-Execution trace:
- (0,0): anon0
-Refinement.dfy(184,5): Error BP5003: A postcondition might not hold on this return path.
-Refinement.dfy[IncorrectConcrete](120,15): Related location: This is the postcondition that might not hold.
-Refinement.dfy(177,9): Related location: Related location
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Then
- (0,0): anon3
-Refinement.dfy(190,7): Error: assertion violation
-Refinement.dfy[IncorrectConcrete](128,24): Related location: Related location
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 48 verified, 9 errors
-
--------------------- RefinementErrors.dfy --------------------
-RefinementErrors.dfy(27,17): Error: a refining method is not allowed to add preconditions
-RefinementErrors.dfy(28,15): Error: a refining method is not allowed to extend the modifies clause
-RefinementErrors.dfy(31,14): Error: a predicate declaration (abc) can only refine a predicate
-RefinementErrors.dfy(32,8): Error: a field re-declaration (xyz) must be to ghostify the field
-RefinementErrors.dfy(34,13): Error: a function method cannot be changed into a (ghost) function in a refining module: F
-RefinementErrors.dfy(35,9): Error: type parameters are not allowed to be renamed from the names given in the function in the module being refined (expected 'A', found 'C')
-RefinementErrors.dfy(35,11): Error: type parameters are not allowed to be renamed from the names given in the function in the module being refined (expected 'B', found 'A')
-RefinementErrors.dfy(35,13): Error: type parameters are not allowed to be renamed from the names given in the function in the module being refined (expected 'C', found 'B')
-RefinementErrors.dfy(36,23): Error: the type of parameter 'z' is different from the type of the same parameter in the corresponding function in the module it refines ('seq<C>' instead of 'set<C>')
-RefinementErrors.dfy(37,9): Error: there is a difference in name of parameter 3 ('k' versus 'b') of function F compared to corresponding function in the module it refines
-RefinementErrors.dfy(54,20): Error: a function can be changed into a function method in a refining module only if the function has not yet been given a body: G
-11 resolution/type errors detected in RefinementErrors.dfy
-
--------------------- ReturnErrors.dfy --------------------
-ReturnErrors.dfy(30,10): Error: cannot have method call in return statement.
-ReturnErrors.dfy(36,10): Error: cannot have effectful parameter in multi-return statement.
-ReturnErrors.dfy(41,10): Error: can only have initialization methods which modify at most 'this'.
-3 resolution/type errors detected in ReturnErrors.dfy
-
--------------------- ReturnTests.dfy --------------------
-
-Dafny program verifier finished with 16 verified, 0 errors
-
--------------------- ChainingDisjointTests.dfy --------------------
-
-Dafny program verifier finished with 6 verified, 0 errors
-
--------------------- CallStmtTests.dfy --------------------
-CallStmtTests.dfy(4,3): Error: LHS of assignment must denote a mutable variable
-CallStmtTests.dfy(15,8): Error: actual out-parameter 0 is required to be a ghost variable
-2 resolution/type errors detected in CallStmtTests.dfy
-
--------------------- MultiSets.dfy --------------------
-
-Dafny program verifier finished with 22 verified, 0 errors
-
--------------------- PredExpr.dfy --------------------
-PredExpr.dfy(4,12): Error: condition in assert expression might not hold
-Execution trace:
- (0,0): anon3_Else
-PredExpr.dfy(36,15): Error: value assigned to a nat must be non-negative
-Execution trace:
- (0,0): anon6_Else
- (0,0): anon7_Else
-PredExpr.dfy(49,17): Error: condition in assert expression might not hold
-Execution trace:
- (0,0): anon0
-PredExpr.dfy(74,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon8_Else
- (0,0): anon3
- PredExpr.dfy(73,20): anon10_Else
- (0,0): anon6
-
-Dafny program verifier finished with 11 verified, 4 errors
-
--------------------- LetExpr.dfy --------------------
-LetExpr.dfy(5,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-LetExpr.dfy(104,21): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
-
-Dafny program verifier finished with 19 verified, 2 errors
-
--------------------- Predicates.dfy --------------------
-Predicates.dfy[B](18,5): Error BP5003: A postcondition might not hold on this return path.
-Predicates.dfy[B](17,15): Related location: This is the postcondition that might not hold.
-Predicates.dfy(28,9): Related location: Related location
-Execution trace:
- (0,0): anon0
-Predicates.dfy(85,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Predicates.dfy(89,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Predicates.dfy[Tricky_Full](123,5): Error BP5003: A postcondition might not hold on this return path.
-Predicates.dfy[Tricky_Full](122,15): Related location: This is the postcondition that might not hold.
-Predicates.dfy(133,7): Related location: Related location
-Predicates.dfy[Tricky_Full](113,9): Related location: Related location
-Execution trace:
- (0,0): anon0
-Predicates.dfy(161,5): Error BP5003: A postcondition might not hold on this return path.
-Predicates.dfy(160,15): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-Predicates.dfy[Q1](151,5): Error BP5003: A postcondition might not hold on this return path.
-Predicates.dfy[Q1](150,15): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 52 verified, 6 errors
-
--------------------- Skeletons.dfy --------------------
-Skeletons.dfy(42,3): Error BP5003: A postcondition might not hold on this return path.
-Skeletons.dfy(41,15): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
- Skeletons.dfy[C0](29,5): anon12_LoopHead
- (0,0): anon12_LoopBody
- Skeletons.dfy[C0](29,5): anon13_Else
- (0,0): anon9
- Skeletons.dfy[C0](34,19): anon16_Else
- (0,0): anon11
-
-Dafny program verifier finished with 9 verified, 1 error
-
--------------------- Maps.dfy --------------------
-Maps.dfy(76,8): Error: element may not be in domain
-Execution trace:
- (0,0): anon0
-Maps.dfy(126,13): Error: assertion violation
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 32 verified, 2 errors
-
--------------------- LiberalEquality.dfy --------------------
-LiberalEquality.dfy(18,14): Error: arguments must have the same type (got T and U)
-LiberalEquality.dfy(37,14): Error: arguments must have the same type (got Weird<T,int,V> and Weird<T,bool,V>)
-LiberalEquality.dfy(52,14): Error: arguments must have the same type (got array<int> and array<bool>)
-3 resolution/type errors detected in LiberalEquality.dfy
-
--------------------- RefinementModificationChecking.dfy --------------------
-RefinementModificationChecking.dfy(17,4): Error: cannot assign to variable defined previously
-RefinementModificationChecking.dfy(18,4): Error: cannot assign to variable defined previously
-2 resolution/type errors detected in RefinementModificationChecking.dfy
-
--------------------- TailCalls.dfy --------------------
-TailCalls.dfy(18,15): Error: this recursive call is not recognized as being tail recursive, because it is followed by non-ghost code
-TailCalls.dfy(30,12): Error: 'decreases *' is allowed only on tail-recursive methods
-TailCalls.dfy(37,12): Error: 'decreases *' is allowed only on tail-recursive methods
-TailCalls.dfy(42,12): Error: 'decreases *' is allowed only on tail-recursive methods
-TailCalls.dfy(64,12): Error: 'decreases *' is allowed only on tail-recursive methods
-5 resolution/type errors detected in TailCalls.dfy
-
--------------------- Calculations.dfy --------------------
-Calculations.dfy(3,4): Error: index out of range
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
-Calculations.dfy(8,13): Error: index out of range
-Execution trace:
- (0,0): anon0
- (0,0): anon13_Then
-Calculations.dfy(8,17): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon13_Then
-Calculations.dfy(36,11): Error: assertion violation
-Execution trace:
- (0,0): anon0
- Calculations.dfy(31,2): anon5_Else
-
-Dafny program verifier finished with 4 verified, 4 errors
-
--------------------- IteratorResolution.dfy --------------------
-IteratorResolution.dfy(59,11): Error: LHS of assignment does not denote a mutable field
-IteratorResolution.dfy(64,18): Error: arguments must have the same type (got _T0 and int)
-IteratorResolution.dfy(76,19): Error: RHS (of type bool) not assignable to LHS (of type int)
-IteratorResolution.dfy(79,13): Error: when allocating an object of type 'GenericIteratorResult', one of its constructor methods must be called
-IteratorResolution.dfy(83,15): Error: logical negation expects a boolean argument (instead got int)
-IteratorResolution.dfy(17,11): Error: LHS of assignment does not denote a mutable field
-IteratorResolution.dfy(19,12): Error: LHS of assignment does not denote a mutable field
-IteratorResolution.dfy(123,9): Error: unresolved identifier: _decreases3
-IteratorResolution.dfy(124,21): Error: arguments must have the same type (got int and ?)
-IteratorResolution.dfy(125,14): Error: LHS of assignment does not denote a mutable field
-IteratorResolution.dfy(132,9): Error: unresolved identifier: _decreases1
-IteratorResolution.dfy(137,9): Error: unresolved identifier: _decreases0
-12 resolution/type errors detected in IteratorResolution.dfy
-
--------------------- Iterators.dfy --------------------
-Iterators.dfy(100,22): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Iterators.dfy(103,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Then
- (0,0): anon3
-Iterators.dfy(174,28): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon15_Then
-Iterators.dfy(205,7): Error: an assignment to _new is only allowed to shrink the set
-Execution trace:
- (0,0): anon0
- Iterators.dfy(194,3): anon17_LoopHead
- (0,0): anon17_LoopBody
- Iterators.dfy(194,3): anon18_Else
- (0,0): anon5
- Iterators.dfy(194,3): anon20_Else
- (0,0): anon21_Then
-Iterators.dfy(209,21): Error: assertion violation
-Execution trace:
- (0,0): anon0
- Iterators.dfy(194,3): anon17_LoopHead
- (0,0): anon17_LoopBody
- Iterators.dfy(194,3): anon18_Else
- (0,0): anon5
- Iterators.dfy(194,3): anon20_Else
- (0,0): anon22_Then
-Iterators.dfy(37,14): Error BP5002: A precondition for this call might not hold.
-Iterators.dfy(1,10): Related location: This is the precondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon37_Then
- (0,0): anon2
- (0,0): anon38_Then
- (0,0): anon5
- (0,0): anon39_Then
-Iterators.dfy(86,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Iterators.dfy(116,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Else
-Iterators.dfy(147,16): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
-Iterators.dfy(152,16): Error BP5002: A precondition for this call might not hold.
-Iterators.dfy(122,10): Related location: This is the precondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Then
- (0,0): anon3
-Iterators.dfy(231,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- Iterators.dfy(222,3): anon15_LoopHead
- (0,0): anon15_LoopBody
- Iterators.dfy(222,3): anon16_Else
- (0,0): anon8
- Iterators.dfy(222,3): anon19_Else
- (0,0): anon20_Else
-
-Dafny program verifier finished with 38 verified, 11 errors
-
--------------------- Superposition.dfy --------------------
-
-Verifying CheckWellformed$$_0_M0.C.M ...
- [0 proof obligations] verified
-
-Verifying _0_M0.C.M ...
- [4 proof obligations] verified
-
-Verifying CheckWellformed$$_0_M0.C.P ...
- [4 proof obligations] verified
-
-Verifying CheckWellformed$$_0_M0.C.Q ...
-Superposition.dfy(24,15): Error BP5003: A postcondition might not hold on this return path.
-Superposition.dfy(25,26): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon5_Else
- [3 proof obligations] error
-
-Verifying CheckWellformed$$_0_M0.C.R ...
-Superposition.dfy(30,15): Error BP5003: A postcondition might not hold on this return path.
-Superposition.dfy(31,26): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon5_Else
- [3 proof obligations] error
-
-Verifying CheckWellformed$$_1_M1.C.M ...
- [0 proof obligations] verified
-
-Verifying RefinementImpl_M1$$_1_M1.C.M ...
- [0 proof obligations] verified
-
-Verifying CheckWellformed$$_1_M1.C.P ...
-Superposition.dfy(47,15): Error BP5003: A postcondition might not hold on this return path.
-Superposition.dfy[M1](19,26): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon7_Else
- (0,0): anon9_Then
- (0,0): anon6
- [1 proof obligation] error
-
-Verifying CheckWellformed$$_1_M1.C.Q ...
- [0 proof obligations] verified
-
-Verifying CheckWellformed$$_1_M1.C.R ...
- [0 proof obligations] verified
-
-Dafny program verifier finished with 7 verified, 3 errors
-
--------------------- SmallTests.dfy --------------------
-SmallTests.dfy(30,11): Error: index out of range
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(61,36): Error: possible division by zero
-Execution trace:
- (0,0): anon12_Then
-SmallTests.dfy(62,51): Error: possible division by zero
-Execution trace:
- (0,0): anon12_Else
- (0,0): anon3
- (0,0): anon13_Else
-SmallTests.dfy(63,22): Error: target object may be null
-Execution trace:
- (0,0): anon12_Then
- (0,0): anon3
- (0,0): anon13_Then
- (0,0): anon6
-SmallTests.dfy(82,24): Error: target object may be null
-Execution trace:
- (0,0): anon0
- SmallTests.dfy(81,5): anon9_LoopHead
- (0,0): anon9_LoopBody
- (0,0): anon10_Then
-SmallTests.dfy(116,5): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
-SmallTests.dfy(129,9): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-SmallTests.dfy(131,9): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Else
-SmallTests.dfy(171,9): Error: assignment may update an object field not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon22_Else
- (0,0): anon5
- (0,0): anon24_Else
- (0,0): anon11
- (0,0): anon26_Else
- (0,0): anon16
- (0,0): anon28_Then
- (0,0): anon29_Then
- (0,0): anon19
-SmallTests.dfy(195,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Then
-SmallTests.dfy(202,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon3
- (0,0): anon7_Then
-SmallTests.dfy(204,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon3
- (0,0): anon7_Else
-SmallTests.dfy(250,24): Error BP5002: A precondition for this call might not hold.
-SmallTests.dfy(228,30): Related location: This is the precondition that might not hold.
-Execution trace:
- (0,0): anon0
- SmallTests.dfy(245,19): anon3_Else
- (0,0): anon2
-SmallTests.dfy(355,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(365,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(375,6): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-SmallTests.dfy(285,3): Error BP5003: A postcondition might not hold on this return path.
-SmallTests.dfy(279,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon18_Else
- (0,0): anon11
- (0,0): anon23_Then
- (0,0): anon24_Then
- (0,0): anon15
- (0,0): anon25_Else
-SmallTests.dfy(326,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon8_Then
- (0,0): anon7
-SmallTests.dfy(333,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(343,4): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-SmallTests.dfy(387,10): Error BP5003: A postcondition might not hold on this return path.
-SmallTests.dfy(390,41): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon6_Else
-SmallTests.dfy(540,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
- (0,0): anon2
-SmallTests.dfy(554,20): Error: left-hand sides 0 and 1 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon27_Then
- (0,0): anon28_Then
- (0,0): anon4
- (0,0): anon29_Then
- (0,0): anon30_Then
- (0,0): anon9
- (0,0): anon31_Then
- (0,0): anon32_Then
- (0,0): anon12
-SmallTests.dfy(556,15): Error: left-hand sides 1 and 2 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon27_Then
- SmallTests.dfy(549,18): anon28_Else
- (0,0): anon4
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon30_Then
- (0,0): anon9
- (0,0): anon31_Else
- (0,0): anon35_Then
- (0,0): anon36_Then
- (0,0): anon37_Then
- (0,0): anon22
- (0,0): anon38_Then
-SmallTests.dfy(563,25): Error: target object may be null
-Execution trace:
- (0,0): anon0
-SmallTests.dfy(576,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 70 verified, 26 errors
-out.tmp.dfy(33,11): Error: index out of range
-Execution trace:
- (0,0): anon0
-out.tmp.dfy(69,37): Error: possible division by zero
-Execution trace:
- (0,0): anon12_Then
-out.tmp.dfy(70,52): Error: possible division by zero
-Execution trace:
- (0,0): anon12_Else
- (0,0): anon3
- (0,0): anon13_Else
-out.tmp.dfy(71,22): Error: target object may be null
-Execution trace:
- (0,0): anon12_Then
- (0,0): anon3
- (0,0): anon13_Then
- (0,0): anon6
-out.tmp.dfy(88,24): Error: target object may be null
-Execution trace:
- (0,0): anon0
- out.tmp.dfy(87,5): anon9_LoopHead
- (0,0): anon9_LoopBody
- (0,0): anon10_Then
-out.tmp.dfy(122,5): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon4_Else
- (0,0): anon3
-out.tmp.dfy(135,9): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
-out.tmp.dfy(137,9): Error: call may violate context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Else
-out.tmp.dfy(177,9): Error: assignment may update an object field not in the enclosing context's modifies clause
-Execution trace:
- (0,0): anon0
- (0,0): anon22_Else
- (0,0): anon5
- (0,0): anon24_Else
- (0,0): anon11
- (0,0): anon26_Else
- (0,0): anon16
- (0,0): anon28_Then
- (0,0): anon29_Then
- (0,0): anon19
-out.tmp.dfy(199,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Then
-out.tmp.dfy(205,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon3
- (0,0): anon7_Then
-out.tmp.dfy(207,14): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon6_Else
- (0,0): anon3
- (0,0): anon7_Else
-out.tmp.dfy(245,24): Error BP5002: A precondition for this call might not hold.
-out.tmp.dfy(226,30): Related location: This is the precondition that might not hold.
-Execution trace:
- (0,0): anon0
- out.tmp.dfy(242,19): anon3_Else
- (0,0): anon2
-out.tmp.dfy(265,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-out.tmp.dfy(275,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-out.tmp.dfy(285,6): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-out.tmp.dfy(401,3): Error BP5003: A postcondition might not hold on this return path.
-out.tmp.dfy(395,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
- (0,0): anon18_Else
- (0,0): anon11
- (0,0): anon23_Then
- (0,0): anon24_Then
- (0,0): anon15
- (0,0): anon25_Else
-out.tmp.dfy(425,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon8_Then
- (0,0): anon7
-out.tmp.dfy(430,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
-out.tmp.dfy(440,4): Error: cannot prove termination; try supplying a decreases clause
-Execution trace:
- (0,0): anon3_Else
-out.tmp.dfy(448,10): Error BP5003: A postcondition might not hold on this return path.
-out.tmp.dfy(449,41): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon6_Else
-out.tmp.dfy(486,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon3_Then
- (0,0): anon2
-out.tmp.dfy(500,20): Error: left-hand sides 0 and 1 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon27_Then
- (0,0): anon28_Then
- (0,0): anon4
- (0,0): anon29_Then
- (0,0): anon30_Then
- (0,0): anon9
- (0,0): anon31_Then
- (0,0): anon32_Then
- (0,0): anon12
-out.tmp.dfy(502,15): Error: left-hand sides 1 and 2 may refer to the same location
-Execution trace:
- (0,0): anon0
- (0,0): anon27_Then
- out.tmp.dfy(495,18): anon28_Else
- (0,0): anon4
- (0,0): anon29_Else
- (0,0): anon7
- (0,0): anon30_Then
- (0,0): anon9
- (0,0): anon31_Else
- (0,0): anon35_Then
- (0,0): anon36_Then
- (0,0): anon37_Then
- (0,0): anon22
- (0,0): anon38_Then
-out.tmp.dfy(509,25): Error: target object may be null
-Execution trace:
- (0,0): anon0
-out.tmp.dfy(522,10): Error: assertion violation
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 70 verified, 26 errors
-
--------------------- LetExpr.dfy --------------------
-LetExpr.dfy(5,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-LetExpr.dfy(104,21): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
-
-Dafny program verifier finished with 19 verified, 2 errors
-out.tmp.dfy(10,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-out.tmp.dfy(101,21): Error: assertion violation
-Execution trace:
- (0,0): anon0
- (0,0): anon11_Then
-
-Dafny program verifier finished with 19 verified, 2 errors
-
-Dafny program verifier finished with 23 verified, 0 errors
-Compiled assembly into Compilation.exe
diff --git a/Test/dafny0/Array.dfy b/Test/dafny0/Array.dfy
deleted file mode 100644
index d8bffce4..00000000
--- a/Test/dafny0/Array.dfy
+++ /dev/null
@@ -1,255 +0,0 @@
-class A {
- method M() {
- var y := new A[100];
- y[5] := null;
- }
-
- method N0() {
- var a: array<int>;
- if (a != null && 5 < a.Length) {
- a[5] := 12; // error: violates modifies clause
- }
- }
-
- method N1(a: array<int>)
- modifies a;
- {
- var b := a.Length; // error: a may be null
- }
-
- method N2(a: array<int>)
- requires a != null;
- modifies a;
- {
- a[5] := 12; // error: index may be outside bounds
- }
-
- method N3(a: array<int>)
- requires a != null && 5 < a.Length;
- modifies a;
- ensures (forall i :: 0 <= i && i < a.Length ==> a[i] == old(a[i]) || (i == 5 && a[i] == 12));
- {
- a[5] := 12; // all is good
- }
-
- var zz0: array<A>;
- var zz1: array<B>;
- method O() {
- var zz2 := new A[25];
- assert zz2 != zz0; // holds because zz2 is newly allocated
- var o: object := zz0;
- assert this != o; // holds because zz0 has a different type
- /****** This would be a good thing to be able to verify, but the current encoding is not up to the task
- if (zz0 != null && zz1 != null && 2 <= zz0.Length && zz0.Length == zz1.Length) {
- o := zz1[1];
- assert zz0[1] == o ==> o == null; // holds because zz0 and zz1 have different element types
- }
- ******/
- assert zz2[20] == null; // error: no reason that this must hold
- }
-
- var x: array<int>;
- method P0()
- modifies this;
- {
- if (x != null && 100 <= x.Length) {
- x[5] := 12; // error: violates modifies clause
- }
- }
- method P1()
- modifies this`x;
- {
- if (x != null && 100 <= x.Length) {
- x[5] := 12; // error: violates modifies clause
- }
- }
- method P2()
- modifies x;
- {
- if (x != null && 100 <= x.Length) {
- x[5] := 12; // fine
- }
- }
-
- method Q() {
- var a := new int[5];
- a[0],a[1],a[2],a[3],a[4] := 0,1,2,3,4;
-
- assert [1,2,3,4] == a[1..];
- assert [1,2,3,4] == a[1.. a.Length];
- assert [1] == a[1..2];
- assert [0,1] == a[..2];
- assert [0,1] == a[0..2];
- assert forall i :: 0 <= i <= a.Length ==> [] == a[i..i];
- assert [0,1,2,3,4] == a[..];
- assert forall i :: 0 <= i < a.Length ==> a[i] == i;
- }
-
- method ArrayToSequenceTests(a: array<int>, lo: int, hi: int)
- requires a != null;
- {
- if (a.Length == 10) {
- var s;
- s := a[2..5];
- assert |s| == 3;
- s := a[..5];
- assert |s| == 5;
- s := a[2..];
- assert |s| == 8;
- s := a[..];
- assert |s| == 10;
- s := a[..10] + a[0..];
- } else {
- if {
- case 0 <= lo <= a.Length =>
- var s := a[lo..] + a[..lo];
- case 0 <= lo <= a.Length && 0 <= hi <= a.Length =>
- var s := a[lo..hi]; // error: lo may be greater than hi
- case true =>
- }
- }
- }
-
- function BadRangeReads(a: array<int>, all: bool): bool
- {
- a != null && a.Length == 10 &&
- if all then
- a[..] == [] // error: not allowed to read the elements of a
- else
- a[2..5] + // error: not allowed to read the elements of a
- a[..5] + // error: not allowed to read the elements of a
- a[2..] == [] // error: not allowed to read the elements of a
- }
- function GoodRangeReads(a: array<int>, all: bool): bool
- reads a;
- {
- a != null && a.Length == 10 &&
- if all then
- a[..] == [] // no prob, since we now have a reads clause
- else
- a[2..5] + a[..5] + a[2..] == [] // no prob, since we now have a reads clause
- }
- function AnotherGoodRangeReads(a: array<int>, j: int): bool
- {
- a != null && 0 <= j && j <= a.Length &&
- a[j..j] == []
- }
-}
-
-type B;
-
-// -------------------------------
-
-class ArrayTests {
- function F0(a: array<int>): bool
- {
- a != null && 10 <= a.Length &&
- a[7] == 13 // error: reads on something outside reads clause
- }
-
- var b: array<int>;
- function F1(): bool
- reads this;
- {
- b != null && 10 <= b.Length &&
- b[7] == 13 // error: reads on something outside reads clause
- }
-
- function F2(a: array<int>): bool
- reads this, b, a;
- {
- a != null && 10 <= a.Length &&
- a[7] == 13 // good
- &&
- b != null && 10 <= b.Length &&
- b[7] == 13 // good
- }
-
- method M0(a: array<int>)
- requires a != null && 10 <= a.Length;
- {
- a[7] := 13; // error: updates location not in modifies clause
- }
-
- method M1()
- requires b != null && 10 <= b.Length;
- modifies this;
- {
- b[7] := 13; // error: updates location not in modifies clause
- }
-
- method M2()
- modifies this;
- {
- var bb := new int[75];
- b := bb; // fine
- }
-
- method M3(a: array<int>)
- requires a != null && 10 <= a.Length;
- requires b != null && 10 <= b.Length;
- modifies this, b, a;
- {
- a[7] := 13; // good
- b[7] := 13; // good
- }
-}
-
-// -------------------- induction attribute --------------------------------
-
-ghost method Fill_I(s: seq<int>)
- requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i];
- ensures forall i,j {:induction i} :: 0 <= i < j < |s| ==> s[i] <= s[j];
-{ // error: cannot prove postcondition
-}
-
-ghost method Fill_J(s: seq<int>)
- requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i];
- ensures forall i,j {:induction j} :: 0 <= i < j < |s| ==> s[i] <= s[j];
-{
-}
-
-ghost method Fill_All(s: seq<int>)
- requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i];
- ensures forall i,j {:induction i,j} :: 0 <= i < j < |s| ==> s[i] <= s[j];
-{
-}
-
-ghost method Fill_True(s: seq<int>)
- requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i];
- ensures forall i,j {:induction} :: 0 <= i < j < |s| ==> s[i] <= s[j];
-{
-}
-
-ghost method Fill_False(s: seq<int>)
- requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i];
- ensures forall i,j {:induction false} :: 0 <= i < j < |s| ==> s[i] <= s[j];
-{ // error: cannot prove postcondition
-}
-
-ghost method Fill_None(s: seq<int>)
- requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i];
- ensures forall i,j :: 0 <= i < j < |s| ==> s[i] <= s[j];
-{ // error: cannot prove postcondition
-}
-
-// -------------- some regression tests; there was a time when array-element LHSs of calls were not translated correctly
-
-method Test_ArrayElementLhsOfCall(a: array<int>, i: int, c: Cdefg<int>) returns (x: int)
- requires a != null && c != null;
- modifies a, c;
-{
- if (0 <= i < a.Length) {
- a[i] := x;
- a[i] := Test_ArrayElementLhsOfCall(a, i-1, c); // this line used to crash Dafny
- c.t := x;
- c.t := Test_ArrayElementLhsOfCall(a, i-1, c); // this line used to crash Dafny
- var n: nat;
- n := x; // error: subrange check is applied and it cannot be verified
- n := Test_ArrayElementLhsOfCall(a, i-1, c); // error: subrange check is applied and it cannot be verified
- }
-}
-
-class Cdefg<T> {
- var t: T;
-}
diff --git a/Test/dafny0/BadFunction.dfy b/Test/dafny0/BadFunction.dfy
deleted file mode 100644
index 3affaa80..00000000
--- a/Test/dafny0/BadFunction.dfy
+++ /dev/null
@@ -1,13 +0,0 @@
-// The following function gives rise to an inconsistent axiom, except
-// for its CanUseFunctionDefs antecedent, which saves the day.
-function F(x: int): int
- decreases x;
-{
- F(x) + 1 // error: does not decrease termination metric
-}
-
-method M()
-{
- assert F(5) == 0; // no error is generated here, because of the inconsistent axiom
- assert false; // ditto
-}
diff --git a/Test/dafny0/Basics.dfy b/Test/dafny0/Basics.dfy
deleted file mode 100644
index 7fca7199..00000000
--- a/Test/dafny0/Basics.dfy
+++ /dev/null
@@ -1,242 +0,0 @@
-class Global {
- static function G(x: int): int { x+x }
- static method N(ghost x: int) returns (ghost r: int)
- ensures r == Global.G(x);
- {
- if {
- case true => r := G(x+0);
- case true =>
- var g: Global;
- r := g.G(x);
- case true =>
- var g: Global := null;
- r := g.G(x);
- case true =>
- r := Global.G(x);
- }
- }
-}
-
-method TestCalls(k: nat) {
- var g: Global, h: Global;
- assume g != h;
- ghost var r: int;
- ghost var s := Global.G(k);
-
- r := Global.N(k);
- assert r == s;
-
- r := g.N(k);
- assert r == s;
- r := h.N(k);
- assert r == s;
-
- g := null;
- r := g.N(k);
- assert r == s;
-
- r := Global.N(r);
- if (k == 0) {
- assert r == s;
- } else {
- assert r == s; // error: G(k) and G(k+k) are different
- }
-}
-
-// ---------- chaining operators ------------------------------------
-
-function UpTruth(j: int, k: int): bool
- requires 10 <= j < 180 < 220 <= k;
-{
- 0 < 2 <= 2 < j != 200 < k < k + 1
-}
-
-function DownTruth(j: int, k: int): bool
- requires k >= 220 > 180 > j >= 10;
-{
- k + 1 > k > 200 != j > 2 >= 2 > 0
-}
-
-method ChallengeTruth(j: int, k: int)
- requires 80 <= j < 150 && 250 <= k < 1000;
-{
- assert UpTruth(j, k);
- assert DownTruth(j, k);
- // but this is not equally true:
- assert j <= j + k != k + j + 1 < k+k+j <=/*this is the error*/ j+j+k < k+k+j+j == 2*k + 2*j == 2*(k+j);
-}
-
-// --------- multi assignments --------------------------------
-
-class Multi {
- var x: int;
- var y: int;
- var next: Multi;
- method Mutate(z: int) returns (m: Multi)
- requires 0 <= z;
- modifies this;
- ensures y == old(y);
- {
- x := x + z;
- }
- method IncX() returns (oldX: int)
- modifies this;
- ensures x == old(x) + 1 && oldX == old(x);
- {
- x, oldX := x + 1, x;
- }
-}
-
-method TestMulti(m: Multi, p: Multi)
- requires m != null && p != null;
- modifies m, p;
-{
- m.x := 10;
- m.y := 12;
- p.x := 20;
- p.y := 22;
- if (*) {
- assert p.x == 20;
- assert m.x == 10; // error: m and p may be the same
- }
- var t, u;
- u, m.x, t := 100, u + t + m.x, 200;
- m.x := 0;
- u, m.x, t := 200, u + t + m.x, 400;
- assert m.x == 300;
- if (p.x != 300) {
- p.x, m.x := m.x, p.x;
- }
- assert p.x == 300;
- if (*) {
- p.x, m.y := 10, 10;
- p.x, m.x := 8, 8;
- }
-
- var a, b := new int[20], new int[30];
- a[4], b[10], a[0], a[3], b[18] := 0, 1, 2, 3, 4;
- a[4], b[b[18]] := 271, 272;
- a[4], a[b[18]] := 273, 274; // error: duplicate assignment (since b[18] is 4)
-}
-
-class MyBoxyClass<T> {
- var f: T;
-}
-
-method TestBoxAssignment<T>(x: MyBoxyClass<int>, y: MyBoxyClass<T>, t: T)
- requires x != null && y != null;
- modifies x, y;
-{
- y.f := t;
- x.f := 15;
- // all together now:
- y.f, x.f := t, 15; // error: duplicate assignment (if T==int and x==y)
- var k: int := x.f;
-}
-
-method TestCallsWithFancyLhss(m: Multi)
- requires m != null && m.next != null;
- modifies m, m.next;
-{
- m.x := 10;
- var p := m.next;
- m.next.next := m.Mutate(m.x); // fine
- if (*) {
- assert m.next == old(m.next); // error: the call to Mutate may have changed m.next
- }
- m.next.next := m.Mutate(20); // error: LHS may not be well defined (m.next may be null)
- m.x, m.next := 12, p;
- m.x, m.y := SwapEm(m.x, m.y);
- assert m.y == 12;
- if (*) {
- m.x, m.x := SwapEm(m.x, m.y); // error: duplicate among LHSs
- }
- m.x := 30;
- var xx := m.IncX();
- assert xx == 30;
- m.y := m.IncX();
- assert m.y == 31 && m.x == 32;
- m.x := m.IncX();
- assert m.x == 32;
- xx := m.IncX();
- if (*) {
- assert xx == 33; // error: xx will in fact be 32
- } else {
- assert xx == 32; // see!
- }
-}
-
-method SwapEm(a: int, b: int) returns (x: int, y: int)
- ensures x == b && y == a;
-{
- x, y := b, a;
-}
-
-function method abs(a:int): int
-{
- if a <= 0 then -a else a
-}
-// test of verifier using euclidean division.
-method EuclideanTest(a: int, b: int)
- requires b != 0;
-{
- var q, r := a / b, a % b;
- assert 0 <= r < abs(b);
- assert a == b * q + r;
- assert (a/b) * b + a % b == a;
-}
-
-method havocInMultiassignment()
-{
- var i: nat, j: nat;
- i, j := *, 3;
- assert 0 <= i;
-}
-
-method m()
-{
- var i: int, j: int;
- i, j := 3, 6;
- i, i := 3, 3;
-}
-
-method swap(a: array<int>, i: nat, j: nat)
- requires a != null && 0 <= i < a.Length && 0 <= j < a.Length;
- modifies a;
-{
- a[i], a[j] := a[j], a[i];
-}
-
-class CC {
- var x : int;
- var y : int;
-}
-
-method notQuiteSwap(c: CC, d: CC)
- requires c != null && d != null;
- modifies c,d;
-{
- c.x, d.x := c.x, c.x;
-}
-
-method notQuiteSwap2(c: CC, d: CC)
- requires c != null && d != null;
- modifies c,d;
-{
- c.x, d.x := d.x, c.y; // BAD: c and d could be the same.
-}
-
-method OKNowIt'sSwapAgain(c: CC, d: CC)
- requires c != null && d != null;
- modifies c,d;
-{
- c.x, d.x := d.x, c.x;
-}
-
-method notQuiteSwap3(c: CC, d: CC)
- requires c != null && d != null && c != d;
- modifies c,d;
-{
- c.x, d.x := 4, c.y;
- c.x, c.y := 3, c.y;
-}
diff --git a/Test/dafny0/Calculations.dfy b/Test/dafny0/Calculations.dfy
deleted file mode 100644
index 9e44f62e..00000000
--- a/Test/dafny0/Calculations.dfy
+++ /dev/null
@@ -1,37 +0,0 @@
-method CalcTest0(s: seq<int>) {
- calc {
- s[0]; // error: ill-formed line
- }
-
- calc {
- 2;
- { assert s[0] == 1; } // error: ill-formed hint
- 1 + 1;
- }
-
- if (|s| > 0) {
- calc {
- s[0]; // OK: well-formed in this context
- { assert s[0] == s[0]; }
- <= s[0];
- }
- }
-}
-
-method CalcTest1(x: int, y: int) {
- calc {
- x + y;
- { assume x == 0; }
- y;
- }
- assert x == 0; // OK: follows from x + y == y;
-}
-
-method CalcTest2(x: int, y: int) {
- calc {
- x + y;
- { assume x == 0; }
- y + x;
- }
- assert x == 0; // error: even though assumed above, is not exported by the calculation
-} \ No newline at end of file
diff --git a/Test/dafny0/CallStmtTests.dfy b/Test/dafny0/CallStmtTests.dfy
deleted file mode 100644
index 735efe81..00000000
--- a/Test/dafny0/CallStmtTests.dfy
+++ /dev/null
@@ -1,21 +0,0 @@
-
-method testing1(t: int)
-{
- t := m(); // error: should be checked at the Dafny level, not fall to Boogie.
-}
-
-method m() returns (r: int)
-{
- return 3;
-}
-
-method testing2()
-{
- var v;
- v := m2(); // error: v needs to be ghost because r is.
-}
-
-method m2() returns (ghost r: int)
-{
- r := 23;
-}
diff --git a/Test/dafny0/ChainingDisjointTests.dfy b/Test/dafny0/ChainingDisjointTests.dfy
deleted file mode 100644
index 17a4fa9f..00000000
--- a/Test/dafny0/ChainingDisjointTests.dfy
+++ /dev/null
@@ -1,33 +0,0 @@
-
-method testing1()
-{
- var a, b, c := {1,2}, {3, 4}, {5, 6};
- assert a !! b !! c;
- testing2(a, b, c);
- assert !({1,2} !! {2,3});
- assert !({1,2} !! {9} !! {2,3}); // tests the accumulation
- assert !({1,2} !! {9} !! {2,3});
- assert !({1,2} !! {9} !! {8} !! {2,3}); // doesn't break at 4. that seems like a good stopping place.
- assert !({9} !! {1,2} !! {8} !! {2,3});
- assert !({9} !! {1} + {2} !! {8} !! {2,3}); // mixing in some other operators
- assert !({1} !! {1} + {2});
-}
-
-method testing2(a: set<int>, b: set<int>, c: set<int>)
- requires a !! b !! c;
-{
- assert a !! b;
- assert a !! c;
- assert b !! c;
-}
-
-method testing3(a: set<int>, b: set<int>, c: set<int>, d: set<int>) // again with the four.
- requires a !! b !! c !! d;
-{
- assert a !! b;
- assert a !! c;
- assert b !! c;
- assert a !! d;
- assert b !! d;
- assert c !! d;
-}
diff --git a/Test/dafny0/CoPredicates.dfy b/Test/dafny0/CoPredicates.dfy
deleted file mode 100644
index c5651c90..00000000
--- a/Test/dafny0/CoPredicates.dfy
+++ /dev/null
@@ -1,59 +0,0 @@
-codatatype Stream<T> = Cons(head: T, tail: Stream);
-
-function Upward(n: int): Stream<int>
-{
- Cons(n, Upward(n + 1))
-}
-
-copredicate Pos(s: Stream<int>)
-{
- 0 < s.head && Pos(s.tail)
-}
-
-copredicate X(s: Stream)
-{
- X(s)
-}
-
-ghost method AlwaysLemma(s: Stream)
- ensures X(s);
-{
-}
-
-function Doubles(n: int): Stream<int>
-{
- Cons(2*n, Doubles(n + 1))
-}
-
-copredicate Even(s: Stream<int>)
-{
- s.head % 2 == 0 && Even(s.tail)
-}
-
-ghost method Lemma0(n: int)
- ensures Even(Doubles(n));
-{
-}
-
-function UpwardBy2(n: int): Stream<int>
-{
- Cons(n, UpwardBy2(n + 2))
-}
-
-ghost method Lemma1(n: int)
- ensures Even(UpwardBy2(2*n)); // error: this is true, but Dafny can't prove it
-{
-}
-
-function U2(n: int): Stream<int>
- requires n % 2 == 0;
-{
- UpwardBy2(n)
-}
-
-// Postponed:
-//ghost method Lemma2(n: int)
-// ensures Even(UpwardBy2(2*n)); // this is true, and Dafny can prove it
-//{
-// assert Even(U2(2*n)); // ... thanks to this lemma
-//}
diff --git a/Test/dafny0/Coinductive.dfy b/Test/dafny0/Coinductive.dfy
deleted file mode 100644
index 431d6bb1..00000000
--- a/Test/dafny0/Coinductive.dfy
+++ /dev/null
@@ -1,106 +0,0 @@
-// --------------------------------------------------
-
-module TestInductiveDatatypes
-{
- // The following types test for cycles that go via instantiated type arguments
-
- datatype Record<T> = Ctor(T);
-
- datatype RecInt = Ctor(Record<int>); // this is fine
- datatype Rec_Forever = Ctor(Record<Rec_Forever>); // error
- datatype Rec_Stops = Cons(Record<Rec_Stops>, Rec_Stops) | Nil; // this is okay
-
- datatype D<T> = Ctor(E<D<T>>); // error: illegal cycle
- datatype E<T> = Ctor(T);
-
- // the following is okay
- datatype MD<T> = Ctor(ME<T>);
- datatype ME<T> = Ctor(T);
- method M()
- {
- var d: MD<MD<int>>;
- }
-
- datatype A = Ctor(B); // superficially looks like a cycle, but can still be constructed
- datatype B = Ctor(List<A>);
- datatype List<T> = Nil | Cons(T, List);
-}
-
-module MoreInductive {
- datatype Tree<G> = Node(G, List<Tree<G>>);
- datatype List<T> = Nil | Cons(T, List<T>);
-
- datatype M = All(List<M>);
- datatype H<'a> = HH('a, Tree<'a>);
- datatype K<'a> = KK('a, Tree<K<'a>>); // error
- datatype L<'a> = LL('a, Tree<List<L<'a>>>);
-}
-
-// --------------------------------------------------
-
-module TestCoinductiveDatatypes
-{
- codatatype InfList<T> = Done | Continue(T, InfList);
-
- codatatype Stream<T> = More(T, Stream<T>);
-
- codatatype BinaryTreeForever<T> = BNode(val: T, left: BinaryTreeForever<T>, right: BinaryTreeForever<T>);
-
- datatype List<T> = Nil | Cons(T, List);
-
- codatatype BestBushEver<T> = Node(value: T, branches: List<BestBushEver<T>>);
-
- codatatype LazyRecord<T> = Lazy(contents: T);
- class MyClass<T> { }
- datatype GenericDt<T> = Blue | Green(T);
- datatype GenericRecord<T> = Rec(T);
-
- datatype FiniteEnough_Class = Ctor(MyClass<FiniteEnough_Class>);
- datatype FiniteEnough_Co = Ctor(LazyRecord<FiniteEnough_Co>);
- datatype FiniteEnough_Dt = Ctor(GenericDt<FiniteEnough_Dt>); // fine
- datatype NotFiniteEnough_Dt = Ctor(GenericRecord<NotFiniteEnough_Dt>); // error
-
-}
-
-// --------------- CoPredicates --------------------------
-
-module CoPredicateResolutionErrors {
-
- codatatype Stream<T> = StreamCons(head: T, tail: Stream);
-
- function Upward(n: int): Stream<int>
- {
- StreamCons(n, Upward(n + 1))
- }
-
- function Doubles(n: int): Stream<int>
- {
- StreamCons(2*n, Doubles(n + 1))
- }
-
- copredicate Pos(s: Stream<int>)
- {
- 0 < s.head && Pos(s.tail) && Even(s)
- }
-
- copredicate Even(s: Stream<int>)
- {
- s.head % 2 == 0 && Even(s.tail)
- && (s.head == 17 ==> Pos(s))
- && (Pos(s) ==> s.head == 17) // error: cannot make recursive copredicate call in negative position
- && !Even(s) // error: cannot make recursive copredicate call in negative position
- && (Even(s) <==> Even(s)) // error (x2): recursive copredicate calls allowed only in positive positions
- }
-
- copredicate Another(s: Stream<int>)
- {
- !Even(s) // here, negation is fine
- }
-
- ghost method Lemma(n: int)
- ensures Even(Doubles(n));
- {
- }
-}
-
-// --------------------------------------------------
diff --git a/Test/dafny0/Compilation.dfy b/Test/dafny0/Compilation.dfy
deleted file mode 100644
index c9545c93..00000000
--- a/Test/dafny0/Compilation.dfy
+++ /dev/null
@@ -1,111 +0,0 @@
-// The tests in this file are designed to run through the compiler. They contain
-// program snippets that are tricky to compile or whose compilation once was buggy.
-
-module OnceBuggy {
- datatype MyDt<T> = Nil | Cons(T, MyDt<T>);
-
- method M<U>(x: MyDt<int>)
- {
- match (x) {
- case Cons(head, tail) =>
- var y: int := head;
- case Nil =>
- }
- }
-}
-
-// --------------------------------------------------
-
-module CoRecursion {
- codatatype Stream<T> = More(head: T, rest: Stream);
-
- function method AscendingChain(n: int): Stream<int>
- {
- More(n, AscendingChain(n+1))
- }
-
- datatype List<T> = Nil | Cons(car: T, cdr: List);
-
- function method Prefix(n: nat, s: Stream): List
- {
- if n == 0 then Nil else
- Cons(s.head, Prefix(n-1, s.rest))
- }
-
- class Cell { var data: int; }
-
- // When run, the following method should print
- // 400
- // 320
- // 40
- // 41
- // 42
- method Main() {
- var m := 17;
- var cell := new Cell;
- cell.data := 40;
- var mr := More(400, More(320, AscendingChain(cell.data)));
- m := 30;
- cell.data := 60;
- var l := Prefix(5, mr);
- while (l != Nil)
- decreases l;
- {
- match (l) { case Cons(x,y) => }
- print l.car, "\n";
- l := l.cdr;
- }
- }
-}
-
-ghost module S {
- class C {
- var f: int;
- method m()
- }
-}
-
-module T refines S {
- class C {
- method m() {
- print "in T.C.m()";
- }
- }
-}
-module A {
- import X as S default T;
- import Y as S default T;
- import Z = T;
- static method run() {
- var x := new X.C;
- x.m();
- var y := new Y.C;
- y.m();
- var z := new Z.C;
- z.m();
- }
-}
-
-method NotMain() {
- A.run();
-}
-
-
-ghost module S1 {
- import B as S default T;
- static method do()
-}
-
-module T1 refines S1 {
- static method do() {
- var x := 3;
- }
-}
-module A1 {
- import X as S1 default T1;
- static method run() {
- X.do();
- var x := new X.B.C;
- x.m();
- }
-}
diff --git a/Test/dafny0/Comprehensions.dfy b/Test/dafny0/Comprehensions.dfy
deleted file mode 100644
index ca1fcfb7..00000000
--- a/Test/dafny0/Comprehensions.dfy
+++ /dev/null
@@ -1,43 +0,0 @@
-method M()
-{
- var numbers := set i | 0 <= i && i < 100;
- var squares := set i | 0 <= i && i < 100 :: Id(i)*i; // verifying properties about set comprehensions with a term expression is hard
-
- assert 12 in numbers;
- assert Id(5) == 5;
- assert 25 in squares;
- assert 200 in numbers; // error
-}
-
-function method Id(x: int): int { x } // for triggering
-
-datatype D = A | B;
-// The following mainly test that set comprehensions can be compiled, but one would
-// have to run the resulting program to check that the compiler is doing the right thing.
-method Main()
-{
- var q := set i,j | 0 <= i && i < 10 && 0 <= j && j < 3 :: i+j;
- PrintSet(q);
- q := set b: bool | true :: if b then 3 else 7;
- var d := set b:D | true;
- var test := forall d:D :: d == A || d == B;
- PrintSet(q);
- var m := set k | k in q :: 2*k;
- PrintSet(m);
- PrintSet(set k | k in q && k % 2 == 0);
- var sq := [30, 40, 20];
- PrintSet(set k, i | k in sq && 0 <= i && i < k && i % 7 == 0 :: k + i);
- var bb := forall k, i | k in sq && 0 <= i && i < k && i % 7 == 0 :: k + i == 17;
-}
-
-method PrintSet<T>(s: set<T>) {
- var q := s;
- while (q != {})
- decreases q;
- {
- var x := choose q;
- print x, " ";
- q := q - {x};
- }
- print "\n";
-}
diff --git a/Test/dafny0/ControlStructures.dfy b/Test/dafny0/ControlStructures.dfy
deleted file mode 100644
index c46eee3a..00000000
--- a/Test/dafny0/ControlStructures.dfy
+++ /dev/null
@@ -1,239 +0,0 @@
-datatype D = Green | Blue | Red | Purple;
-
-method M0(d: D)
-{
- match (d) { // error: two missing cases: Blue and Purple
- case Green =>
- case Red =>
- }
-}
-
-method M1(d: D)
- requires d != D.Blue;
-{
- match (d) { // error: missing case: Purple
- case Green =>
- case Red =>
- }
-}
-
-method M2(d: D)
- requires d != D.Blue && d != D.Purple;
-{
- match (d) {
- case Green =>
- case Red =>
- }
-}
-
-method M3(d: D)
- requires d == D.Green;
-{
- if (d != D.Green) {
- match (d) {
- // nothing here
- }
- }
-}
-
-method M4(d: D)
- requires d == D.Green || d == D.Red;
-{
- if (d != D.Green) {
- match (d) { // error: missing case Red
- // nothing here
- }
- }
-}
-
-function F0(d: D): int
-{
- match (d) // error: missing cases Red
- case Purple => 80
- case Green => 0
- case Blue => 2
-}
-
-function F1(d: D, x: int): int
- requires x < 100;
- requires d == D.Red ==> x == 200; // (an impossibility, given the first precondition, so d != Red)
-{
- match (d)
- case Purple => 80
- case Green => 0
- case Blue => 2
-}
-
-// --------------- alternative statements ---------------------
-
-method A0(x: int) returns (r: int)
- ensures 0 <= r;
-{
- if { // error: missing case (x == 0)
- case x < 0 => r := 12;
- case 0 < x => r := 13;
- }
-}
-
-method A1(x: int) returns (r: int)
- ensures 0 <= r;
-{
- if {
- case x <= 0 => r := 12;
- case 0 <= x => r := 13;
- }
-}
-
-method DutchFlag(A: array<int>, N: int, l: int, r: int) returns (result: int)
- requires A != null && N == A.Length;
- requires 0 <= l && l+2 <= r && r <= N;
- modifies A;
- ensures l <= result && result < r;
- ensures forall k, j :: l <= k && k < result && result <= j && j < r ==> A[k] <= A[j];
- ensures forall k :: l <= k && k < result ==> A[k] <= old(A[l]);
- ensures forall k :: result <= k && k < r ==> old(A[l]) <= A[k];
-{
- var pv := A[l];
- var i := l;
- var j := r-1;
- A[l], A[j] := A[j], A[l];
-
- while (i < j)
- invariant l <= i && i <= j && j < r;
- invariant forall k :: l <= k && k < i ==> A[k] <= pv;
- invariant forall k :: j <= k && k < r ==> pv <= A[k];
- {
- if {
- case A[i] <= pv =>
- i := i + 1;
- case pv <= A[j-1] =>
- j := j - 1;
- case A[j-1] < pv && pv < A[i] =>
- A[j-1], A[i] := A[i], A[j-1];
- assert A[i] < pv && pv < A[j-1];
- i, j := i + 1, j - 1;
- }
- }
- result := i;
-}
-
-// --------------- alternative loop statements ---------------
-
-method B(x: int) returns (r: int)
- ensures r == 0;
-{
- r := x;
- while
- decreases if 0 <= r then r else -r;
- {
- case r < 0 =>
- r := r + 1;
- case 0 < r =>
- r := r - 1;
- }
-}
-
-// --------------- breaks ---------------
-
-method TheBreaker_AllGood(M: int, N: int, O: int)
-{
- var a, b, c, d, e;
- var i := 0;
- while (i < M)
- {
- var j := 0;
- label InnerHasLabel:
- while (j < N)
- {
- var u := 2000;
- label MyLabelBlock:
- label MyLabelBlockAgain:
- if (*) {
- a := 15; break;
- } else if (*) {
- b := 12; break break;
- } else if (*) {
- c := 21; break InnerHasLabel;
- } else if (*) {
- while (u < 10000) {
- u := u + 3;
- if (*) { u := 1998; break MyLabelBlock; }
- if (*) { u := 1998; break MyLabelBlockAgain; }
- }
- assert 10000 <= u;
- u := 1998;
- } else {
- u := u - 2;
- }
- assert u == 1998;
- var k := 0;
- while
- decreases O - k;
- {
- case k < O && k % 2 == 0 =>
- d := 187; break;
- case k < O =>
- if (*) { e := 4; break InnerHasLabel; }
- if (*) { e := 7; break; }
- if (*) { e := 37; break break break; }
- k := k + 1;
- }
- assert O <= k || d == 187 || e == 7;
- j := j + 1;
- }
- assert N <= j || a == 15 || c == 21 || e == 4;
- i := i + 1;
- }
- assert M <= i || b == 12 || e == 37;
-}
-
-method TheBreaker_SomeBad(M: int, N: int, O: int)
-{
- var a, b, c, d, e;
- var i := 0;
- while (i < M)
- {
- var j := 0;
- label InnerHasLabel:
- while (j < N)
- {
- var u := 2000;
- label MyLabelBlock:
- label MyLabelBlockAgain:
- if (*) {
- a := 15; break;
- } else if (*) {
- b := 12; break break;
- } else if (*) {
- c := 21; break InnerHasLabel;
- } else if (*) {
- while (u < 10000) {
- u := u + 3;
- if (*) { u := 1998; break MyLabelBlock; }
- if (*) { u := 1998; break MyLabelBlockAgain; }
- }
- assert u < 2000; // error (and no way to get past this assert statement)
- } else {
- u := u - 2;
- }
- assert u == 1998;
- var k := 0;
- while
- decreases O - k;
- {
- case k < O && k % 2 == 0 =>
- d := 187; break;
- case k < O =>
- if (*) { e := 4; break InnerHasLabel; }
- if (*) { e := 7; break; }
- if (*) { e := 37; break break break; }
- k := k + 1;
- }
- assert O <= k || e == 7; // error: d == 187
- j := j + 1;
- }
- assert N <= j || c == 21 || e == 4; // error: a == 15
- i := i + 1;
- }
- assert M <= i || b == 12; // error: e == 37
-}
diff --git a/Test/dafny0/Corecursion.dfy b/Test/dafny0/Corecursion.dfy
deleted file mode 100644
index 9f1b1328..00000000
--- a/Test/dafny0/Corecursion.dfy
+++ /dev/null
@@ -1,52 +0,0 @@
-
-// --------------------------------------------------
-
-module CoRecursion {
- codatatype Stream<T> = More(head: T, rest: Stream);
-
- function AscendingChain(n: int): Stream<int>
- {
- More(n, AscendingChain(n+1))
- }
-
- function AscendingChainAndRead(n: int): Stream<int>
- reads this; // with a reads clause, this function is not a co-recusvie function
- {
- More(n, AscendingChainAndRead(n+1)) // error: cannot prove termination
- }
-
- datatype List<T> = Nil | Cons(T, List);
-
- function Prefix(n: nat, s: Stream): List
- {
- if n == 0 then Nil else
- Cons(s.head, Prefix(n-1, s.rest))
- }
-}
-
-// --------------------------------------------------
-
-module CoRecursionNotUsed {
- codatatype Stream<T> = More(T, Stream);
-
- function F(s: Stream, n: nat): Stream
- decreases n, true;
- {
- G(s, n)
- }
- function G(s: Stream, n: nat): Stream
- decreases n, false;
- {
- if n == 0 then s else Tail(F(s, n-1))
- }
-
- function Tail(s: Stream): Stream
- {
- match s case More(hd, tl) => tl
- }
-
- function Diverge(n: nat): nat
- {
- Diverge(n) // error: cannot prove termination
- }
-}
diff --git a/Test/dafny0/DTypes.dfy b/Test/dafny0/DTypes.dfy
deleted file mode 100644
index 55d107c5..00000000
--- a/Test/dafny0/DTypes.dfy
+++ /dev/null
@@ -1,156 +0,0 @@
-class C {
- var n: set<Node>;
-
- method M(v: Stack)
- requires v != null;
- {
- var o: object := v;
- assert o !in n; // should be known from the types involved
- }
-
- method N(v: Stack)
- /* this time without the precondition */
- {
- var o: object := v;
- assert o !in n; // error: v may be null
- }
-
- method A0(a: CP<int,C>, b: CP<int,object>)
- {
- var x: object := a;
- var y: object := b;
- assert x == y ==> x == null;
- }
-
- method A1(a: CP<int,C>)
- {
- var x: object := a;
- assert (forall b: CP<int,Stack> :: x == b ==> b == null); // follows from type antecedents
- }
-
- var a2x: set<CP<C,Node>>;
- method A2(b: set<CP<Node,C>>)
- requires null !in b;
- {
- var x: set<object> := a2x;
- var y: set<object> := b;
- assert x * y == {};
- }
-
- method A3(b: set<CP<Node,C>>)
- /* this time without the precondition */
- {
- var x: set<object> := a2x;
- var y: set<object> := b;
- assert x * y <= {null};
- }
-
- method A4(b: set<CP<Node,C>>)
- /* again, without the precondition */
- {
- var x: set<object> := a2x;
- var y: set<object> := b;
- assert x * y == {}; // error
- }
-
- method A5()
- {
- var a := new CP<int,C>;
- var b := new CP<int,object>;
- while (a != null)
- decreases *; // omit loop termination check (in fact, the loop does not terminate)
- {
- var x: object := a;
- var y: object := b;
- assert x == y ==> x == null;
- a := a; // make 'a' a loop target
- }
- }
-}
-
-class Stack { }
-class Node { }
-
-class CP<T,U> {
-}
-
-datatype Data = Lemon | Kiwi(int);
-
-function G(d: Data): int
- requires d != Data.Lemon;
-{
- match d
- case Lemon => G(d)
- case Kiwi(x) => 7
-}
-
-// -------- some things about induction ---------------------------------
-
-datatype Tree<T> = Leaf(T) | Branch(Tree<T>, Tree<T>);
-
-class DatatypeInduction<T> {
- function LeafCount<G>(tree: Tree<G>): int
- {
- match tree
- case Leaf(t) => 1
- case Branch(left, right) => LeafCount(left) + LeafCount(right)
- }
-
- method Theorem0(tree: Tree<T>)
- ensures 1 <= LeafCount(tree);
- {
- assert (forall t: Tree<T> :: 1 <= LeafCount(t));
- }
-
- // also make sure it works for an instantiated generic datatype
- method Theorem1(bt: Tree<bool>, it: Tree<int>)
- ensures 1 <= LeafCount(bt);
- ensures 1 <= LeafCount(it);
- {
- assert (forall t: Tree<bool> :: 1 <= LeafCount(t));
- assert (forall t: Tree<int> :: 1 <= LeafCount(t));
- }
-
- method NotATheorem0(tree: Tree<T>)
- ensures LeafCount(tree) % 2 == 1;
- {
- assert (forall t: Tree<T> :: LeafCount(t) % 2 == 1); // error: fails for Branch case
- }
-
- method NotATheorem1(tree: Tree<T>)
- ensures 2 <= LeafCount(tree);
- {
- assert (forall t: Tree<T> :: 2 <= LeafCount(t)); // error: fails for Leaf case
- }
-
- function Predicate(): bool
- {
- (forall t: Tree<T> :: 2 <= LeafCount(t))
- }
-
- method NotATheorem2()
- {
- assert Predicate(); // error (this tests Related Location for induction via a predicate)
- }
-
- // ----- here is a test for induction over integers
-
- method IntegerInduction_Succeeds(a: array<int>)
- requires a != null;
- requires a.Length == 0 || a[0] == 0;
- requires forall j :: 1 <= j && j < a.Length ==> a[j] == a[j-1]+2*j-1;
- {
- // The following assertion can be proved by induction:
- assert forall n {:induction} :: 0 <= n && n < a.Length ==> a[n] == n*n;
- }
-
- method IntegerInduction_Fails(a: array<int>)
- requires a != null;
- requires a.Length == 0 || a[0] == 0;
- requires forall j :: 1 <= j && j < a.Length ==> a[j] == a[j-1]+2*j-1;
- {
- // ...but the induction heuristics don't recognize the situation as one where
- // applying induction would be profitable:
- assert forall n :: 0 <= n && n < a.Length ==> a[n] == n*n; // error reported
- }
-}
diff --git a/Test/dafny0/Datatypes.dfy b/Test/dafny0/Datatypes.dfy
deleted file mode 100644
index 70177ef4..00000000
--- a/Test/dafny0/Datatypes.dfy
+++ /dev/null
@@ -1,249 +0,0 @@
-datatype List<T> = Nil | Cons(T, List<T>);
-
-class Node {
- var data: int;
- var next: Node;
-
- function Repr(list: List<int>): bool
- reads *;
- decreases list;
- { match list
- case Nil =>
- next == null
- case Cons(d,cdr) =>
- data == d && next != null && next.Repr(cdr)
- }
-
- method Init()
- modifies this;
- ensures Repr(Nil);
- {
- next := null;
- }
-
- method Add(d: int, L: List<int>) returns (r: Node)
- requires Repr(L);
- ensures r != null && r.Repr(Cons(d, L));
- {
- r := new Node;
- r.data := d;
- r.next := this;
- }
-}
-
-class AnotherNode {
- var data: int;
- var next: AnotherNode;
-
- function Repr(n: AnotherNode, list: List<int>): bool
- reads *;
- decreases list;
- { match list
- case Nil =>
- n == null
- case Cons(d,cdr) =>
- n != null && n.data == d && Repr(n.next, cdr)
- }
-
- method Create() returns (n: AnotherNode)
- ensures Repr(n, Nil);
- {
- n := null;
- }
-
- method Add(n: AnotherNode, d: int, L: List<int>) returns (r: AnotherNode)
- requires Repr(n, L);
- ensures Repr(r, Cons(d, L));
- {
- r := new AnotherNode;
- r.data := d;
- r.next := n;
- }
-}
-
-method TestAllocatednessAxioms(a: List<Node>, b: List<Node>, c: List<AnotherNode>)
-{
- var n := new Node;
- var p := n;
- match a {
- case Nil =>
- case Cons(x, tail) => assert x != n; p := x;
- }
- match b {
- case Nil =>
- case Cons(x, tail) =>
- match tail {
- case Nil =>
- case Cons(y, more) =>
- assert y != n;
- assert y != p; // error: if p is car(a), then it and y may very well be equal
- }
- }
- match c {
- case Nil =>
- case Cons(x, tail) =>
- match tail {
- case Nil =>
- case Cons(y, more) =>
- var o: object := y;
- assert p != null ==> p != o; // follows from well-typedness
- }
- }
-}
-
-class NestedMatchExpr {
- function Cadr<T>(a: List<T>, Default: T): T
- {
- match a
- case Nil => Default
- case Cons(x,t) =>
- match t
- case Nil => Default
- case Cons(y,tail) => y
- }
- // CadrAlt is the same as Cadr, but it writes its two outer cases in the opposite order
- function CadrAlt<T>(a: List<T>, Default: T): T
- {
- match a
- case Cons(x,t) => (
- match t
- case Nil => Default
- case Cons(y,tail) => y)
- case Nil => Default
- }
- method TestNesting0()
- {
- var x := 5;
- var list := Cons(3, Cons(6, Nil));
- assert Cadr(list, x) == 6;
- match (list) {
- case Nil => assert false;
- case Cons(h,t) => assert Cadr(t, x) == 5;
- }
- }
- method TestNesting1(a: List<NestedMatchExpr>)
- ensures Cadr(a, this) == CadrAlt(a, this);
- {
- match (a) {
- case Nil =>
- case Cons(x,t) =>
- match (t) {
- case Nil =>
- case Cons(y,tail) =>
- }
- }
- }
-}
-
-// ------------------- datatype destructors ---------------------------------------
-
-datatype XList = XNil | XCons(Car: int, Cdr: XList);
-
-method Destructors0(d: XList) {
- Lemma_AllCases(d);
- if {
- case d.XNil? =>
- assert d == XNil;
- case d.XCons? =>
- var hd := d.Car;
- var tl := d.Cdr;
- assert d == XCons(hd, tl);
- }
-}
-
-method Destructors1(d: XList) {
- match (d) {
- case XNil =>
- assert d.XNil?;
- case XCons(hd,tl) =>
- assert d.XCons?;
- }
-}
-
-method Destructors2(d: XList) {
- // this method gets it backwards
- match (d) {
- case XNil =>
- assert d.XCons?; // error
- case XCons(hd,tl) =>
- assert d.XNil?; // error
- }
-}
-
-ghost method Lemma_AllCases(d: XList)
- ensures d.XNil? || d.XCons?;
-{
- match (d) {
- case XNil =>
- case XCons(hd,tl) =>
- }
-}
-
-method InjectivityTests(d: XList)
- requires d != XNil;
-{
- match (d) {
- case XCons(a,b) =>
- match (d) {
- case XCons(x,y) =>
- assert a == x && b == y;
- }
- assert a == d.Car;
- assert b == d.Cdr;
- assert d == XCons(d.Car, d.Cdr);
- }
-}
-
-method MatchingDestructor(d: XList) returns (r: XList)
- ensures r.Car == 5; // error: specification is not well-formed (since r might not be an XCons)
-{
- if (*) {
- var x0 := d.Car; // error: d might not be an XCons
- } else if (d.XCons?) {
- var x1 := d.Car;
- }
- r := XCons(5, XNil);
-}
-
-datatype Triple = T(a: int, b: int, c: int); // just one constructor
-datatype TripleAndMore = T'(a: int, b: int, c: int) | NotATriple;
-
-method Rotate0(t: Triple) returns (u: Triple)
-{
- u := T(t.c, t.a, t.b);
-}
-
-method Rotate1(t: TripleAndMore) returns (u: TripleAndMore)
-{
- if {
- case t.T'? =>
- u := T'(t.c, t.a, t.b);
- case true =>
- u := T'(t.c, t.a, t.b); // error: t may be NotATriple
- }
-}
-
-// -------------
-
-method FwdBug(f: Fwd, initialized: bool)
- requires !f.FwdCons?;
-{
- match (f) {
- case FwdNil =>
- // Syntactically, there is a missing case here, but the verifier checks that this is still cool.
- // There was once a bug in Dafny, where this had caused an ill-defined Boogie program.
- }
- if (!initialized) { // There was once a Dafny parsing bug with this line
- }
-}
-
-function FwdBugFunction(f: Fwd): bool
- requires !f.FwdCons?;
-{
- match f
- case FwdNil => true
- // Syntactically, there is a missing case here, but the verifier checks that this is still cool.
- // There was once a bug in Dafny, where this had caused an ill-defined Boogie program.
-}
-
-datatype Fwd = FwdNil | FwdCons(int, Fwd);
diff --git a/Test/dafny0/Definedness.dfy b/Test/dafny0/Definedness.dfy
deleted file mode 100644
index f99d1503..00000000
--- a/Test/dafny0/Definedness.dfy
+++ /dev/null
@@ -1,240 +0,0 @@
-// ----------------- wellformed specifications ----------------------
-
-class SoWellformed {
- var xyz: int;
- var next: SoWellformed;
-
- function F(x: int): int
- { 5 / x } // error: possible division by zero
-
- function G(x: int): int
- requires 0 < x;
- { 5 / x }
-
- function H(x: int): int
- decreases 5/x; // error: possible division by zero
- { 12 }
-
- function I(x: int): int
- requires 0 < x;
- decreases 5/x;
- { 12 }
-
- method M(a: SoWellformed, b: int) returns (c: bool, d: SoWellformed)
- requires a.xyz == 7; // error: not always defined
- ensures c ==> d.xyz == -7; // error: not always defined
- decreases 5 / b; // error: not always defined
- {
- c := false;
- }
-
- method N(a: SoWellformed, b: int) returns (c: bool, d: SoWellformed)
- decreases 5 / b;
- requires a.next != null; // error: not always defined
- requires a.next.xyz == 7; // this is well-defined, given that the previous line is
- requires b < -2;
- ensures 0 <= b ==> d.xyz == -7 && !c;
- {
- c := true;
- }
-
- method O(a: SoWellformed, b: int) returns (c: bool, d: SoWellformed)
- modifies a.next; // this may not be well-defined, but that's okay for modifies clauses
- {
- c := true;
- }
-
- method P(a: SoWellformed, b: int) returns (c: bool, d: SoWellformed)
- requires next != null;
- modifies this;
- ensures next.xyz < 100; // error: may not be well-defined (if body sets next to null)
- {
-
- }
- method Q(a: SoWellformed, s: set<SoWellformed>) returns (c: bool, d: SoWellformed)
- requires next != null;
- modifies s;
- ensures next.xyz < 100; // error: may not be well-defined (if this in s and body sets next to null)
- {
-
- }
- method R(a: SoWellformed, s: set<SoWellformed>) returns (c: bool, d: SoWellformed)
- requires next != null && this !in s;
- modifies s;
- ensures next.xyz < 100; // fine
- {
-
- }
-}
-
-// ---------------------- welldefinedness checks for statements -------------------
-
-class StatementTwoShoes {
- var x: int;
- var s: StatementTwoShoes;
- function method F(b: int): StatementTwoShoes
- requires 0 <= b;
- reads this;
- {
- s
- }
-
- method M(p: StatementTwoShoes, a: int)
- modifies this, p;
- {
- p.x := a; // error: receiver may be null
- F(a).x := a; // error: LHS may not be well defined (fn precondition)
- x := F(a-10).x; // error: RHS may not be well defined (fn precondition)
- }
-
- method N(a: int, b: int)
- {
- assert 5 / a == 5 / a; // error: expression may not be well defined (div by zero)
- assume 20 / b == 5; // error: expression may not be well defined (div by zero)
- }
-
- method O(a: int) returns (b: int)
- {
- if (20 / a == 5) { // error: expression may not be well defined (div by zero)
- b := a;
- }
- }
-
- method P(a: int)
- {
- while (20 / a == 5) { // error: expression may not be well defined (div by zero)
- break;
- }
- }
-
- method Q(a: int, b: int)
- {
- var i := 1;
- while (i < a)
- decreases F(i), F(a), a - i; // error: component 1 may not be well defined (fn precond)
- {
- i := i + 1;
- }
- i := 1;
- while (i < a)
- decreases F(b), a - i; // error: component 0 may not be well defined (fn precond)
- {
- i := i + 1;
- }
- }
-
- method R(a: int)
- {
- var i := 0;
- while (i < 100) // The following produces 3 complaints instead of 1, because loop invariants are not subject to subsumption
- invariant F(a) != null; // error: expression may not be well defined (fn precond), and error: loop invariant may not hold
- decreases F(a), 100 - i; // error: component 0 not well defined
- {
- i := i + 1;
- }
- }
-
- method S(a: int)
- {
- var j := 0;
- while (20 / a == 5 && j < 100) // error: guard may not be well defined (div by zero)
- invariant j <= 100;
- decreases F(101 - j), 100 - j;
- {
- j := j + 1;
- }
- }
-
- method T(a: int)
- requires a != 0 && 20 / a == 5;
- {
- var k := a;
- var j := 0;
- while (20 / k == 5 && j < 100) // fine
- decreases 100 - j;
- {
- j := j + 1;
- }
- j := 0;
- while (20 / k == 5 && j < 100) // error: guard may not be well defined (div by zero)
- decreases 100 - j;
- {
- k := *;
- j := j + 1;
- }
- }
-
- method U()
- {
- var i := 0;
- while (i < 100)
- invariant i <= 100;
- invariant F(123 - i) == this;
- {
- i := i + 1;
- }
- i := 0;
- while (i < 100)
- invariant F(if i==77 then -3 else i) == this; // error: expression may not be well defined (fn precond)
- {
- i := i + 1;
- if (i == 77) { i := i + 1; }
- }
- }
-
- function G(w: int): int { 5 }
- function method H(x: int): int { -x }
-
- method W(x: int)
- {
- var i := 0;
- while (i < 100)
- // The following line produces two complaints, thanks to the w-encoding of the loop's invariant definedness checking
- invariant 5 / x != 5 / x; // error: not well-defined (div by zero), and error: loop invariant does not hold initially
- {
- i := i + 1;
- }
- }
-}
-
-// ----------------- function postconditions ----------------------
-
-class Mountain { var x: int; }
-
-function Postie0(c: Mountain): Mountain
- requires c != null;
- ensures Postie0(c) != null && Postie0(c).x <= Postie0(c).x;
- ensures Postie0(c).x == Postie0(c).x;
-{
- c
-}
-
-function Postie1(c: Mountain): Mountain
- requires c != null;
- ensures Postie1(c) != null && Postie1(c).x == 5; // error: postcondition violation (but no well-formedness problem)
-{
- c
-}
-
-function Postie2(c: Mountain): Mountain
- requires c != null && c.x == 5;
- ensures Postie2(c).x == 5; // error: well-formedness error (null dereference)
-{
- c
-}
-
-function Postie3(c: Mountain): Mountain // all is cool
- requires c != null && c.x == 5;
- ensures Postie3(c) != null && Postie3(c).x < 10;
- ensures Postie3(c).x == 5;
-{
- c
-}
-
-function Postie4(c: Mountain): Mountain
- requires c != null && c.x <= 5;
- ensures Postie4(c) != null && Postie4(c).x < 10;
- ensures Postie4(c).x == 5; // error: postcondition might not hold
-{
- c
-}
diff --git a/Test/dafny0/EqualityTypes.dfy b/Test/dafny0/EqualityTypes.dfy
deleted file mode 100644
index 251b2e2f..00000000
--- a/Test/dafny0/EqualityTypes.dfy
+++ /dev/null
@@ -1,89 +0,0 @@
-module A {
- datatype Explicit<T(==)> = Nil | Cons(set<T>, Explicit<T>);
- datatype Inferred<T> = Nil | Cons(set<T>, Inferred<T>);
-
- class C {
- method M<T>(x: Explicit<T>)
- method N<T>(x: Inferred<T>)
- }
-}
-
-module B refines A {
- class C {
- method M<T>(x: Explicit<T>)
- method N<T(==)>(x: Inferred<T>)
- }
-}
-
-// ----------------------------
-
-module C {
- type X(==);
- type Y(==);
-}
-
-module D refines C {
- class X { }
- datatype Y = Red | Green | Blue;
-}
-
-module E refines C {
- codatatype X = Next(int, X); // error: X requires equality and codatatypes don't got it
- datatype Y = Nil | Something(Z) | More(Y, Y); // error: Y does not support equality
- codatatype Z = Red | Green(X) | Blue;
-}
-
-module F refines C {
- datatype X<T> = Nil | Cons(T, X<T>); // error: not allowed to add a type parameter to type X
- class Y<T> { } // error: not allowed to add a type parameter to type Y
-}
-
-module G refines C {
- datatype X = Nil | Next(Z, X); // error: X does not support equality
- datatype Y = Nil | Something(Z) | More(Y, Y); // error: Y does not support equality
- codatatype Z = Red | Green | Blue;
-}
-
-// ----------------------------
-
-module H {
- datatype Dt<T> = Nil | Cons(T, Dt);
-
- datatype BulkyList<T> = Nothing | Wrapper(T, BulkyListAux);
- datatype BulkyListAux<T> = Kons(set<T>, BulkyListAuxAux);
- datatype BulkyListAuxAux<T> = GoBack(BulkyList);
-
- codatatype Stream<T> = Next(head: T, tail: Stream<T>);
-
- method M<T(==)>(x: T)
- { }
- function method F<T>(x: BulkyList<T>, y: BulkyList<T>): int
- { if x == y then 5 else 7 } // this equality is allowed
- function method G<T>(x: Dt<T>, y: Dt<T>): int
- { if x == y then 5 else 7 } // error: the equality is not allowed, because Dt<T> may not support equality
- function method G'<T(==)>(x: Dt<T>, y: Dt<T>): int
- { if x == y then 5 else 7 } // fine
-
- method Caller0(b: BulkyList, y: int) {
- match (b) {
- case Nothing =>
- case Wrapper(t, bla) =>
- var u;
- if (y < 100) { u := t; }
- // The following call is allowed, because it will be inferred that
- // 'u' is of a type that supports equality
- M(u);
- }
- }
- method Caller1(d: Dt) {
- match (d) {
- case Nil =>
- case Cons(t, rest) =>
- M(t); // error: t may be of a type that does not support equality
- }
- }
- method Caller2(co: Stream) {
- var d := Cons(co, Nil);
- Caller1(d); // case in point for the error in Caller1
- }
-}
diff --git a/Test/dafny0/FunctionSpecifications.dfy b/Test/dafny0/FunctionSpecifications.dfy
deleted file mode 100644
index 44709ce8..00000000
--- a/Test/dafny0/FunctionSpecifications.dfy
+++ /dev/null
@@ -1,60 +0,0 @@
-function Fib(n: int): int
- requires 0 <= n;
- ensures 0 <= Fib(n);
-{
- if n < 2 then n else
- Fib(n-2) + Fib(n-1)
-}
-
-datatype List = Nil | Cons(int, List);
-
-function Sum(a: List): int
- ensures 0 <= Sum(a);
-{
- match a
- case Nil => 0
- case Cons(x, tail) => if x < 0 then 0 else Fib(x)
-}
-
-function FibWithoutPost(n: int): int
- requires 0 <= n;
-{
- if n < 2 then n else
- FibWithoutPost(n-2) + FibWithoutPost(n-1)
-}
-
-function SumBad(a: List): int
- ensures 0 <= Sum(a); // this is still okay, because this is calling the good Sum
- ensures 0 <= SumBad(a); // error: cannot prove postcondition
-{
- match a
- case Nil => 0
- case Cons(x, tail) => if x < 0 then 0 else FibWithoutPost(x)
-}
-
-function FibWithExtraPost(n: int): int
- ensures 2 <= n ==> 0 <= FibWithExtraPost(n-1); // This is fine, because the definition of the function is discovered via canCall
- ensures 1 <= n ==> 0 <= FibWithExtraPost(n-1); // Error: In the current implementation of Dafny, one needs to actually call the
- // function in order to benefit from canCall. This may be improved in the future.
- ensures 0 <= FibWithExtraPost(n);
-{
- if n < 0 then 0 else
- if n < 2 then n else
- FibWithExtraPost(n-2) + FibWithExtraPost(n-1)
-}
-
-function DivergentPost(n: int): int
- requires 0 <= n;
- ensures 1 <= n ==> DivergentPost(n-1) == DivergentPost(n-1);
- ensures DivergentPost(2*n - n) == DivergentPost(2*(n+5) - 10 - n); // these are legal ways to denote the result value of the function
- ensures DivergentPost(n+1) == DivergentPost(n+1); // error: call may not terminate
-{
- if n < 2 then n else
- DivergentPost(n-2) + DivergentPost(n-1)
-}
-
-function HoldsAtLeastForZero(x: int): bool
- ensures x == 0 ==> HoldsAtLeastForZero(x);
-{
- x < -2 // error: this does not hold for 0
-}
diff --git a/Test/dafny0/IteratorResolution.dfy b/Test/dafny0/IteratorResolution.dfy
deleted file mode 100644
index 60b1bc7e..00000000
--- a/Test/dafny0/IteratorResolution.dfy
+++ /dev/null
@@ -1,138 +0,0 @@
-iterator MyIter()
-
-module Mx {
-
- iterator ExampleIterator(k: int) yields (x: int, y: int)
- {
- var i := k;
- while (true) {
- if (i % 77 == 0) { yield; }
- yield i, -i;
- i := i + 1;
- }
- }
-
- method IteratorUser() {
- var iter := new ExampleIterator.ExampleIterator(15);
- iter.k := 12; // error: not allowed to assign to iterator's in-parameters
- iter.x := 12; // allowed (but this destroys the validity of 'iter'
- iter.xs := []; // error: not allowed to assign to iterator's yield-history variables
- var j := 0;
- while (j < 100) {
- var more := iter.MoveNext();
- if (!more) {
- break;
- }
- print iter.x, iter.y;
- j := j + 1;
- }
- }
-
- static method StaticM(k: nat) returns (m: int)
- {
- m := k;
- }
-
- module Inner {
- iterator YetAnother(x: int, y: int, z: int) yields (a: bool, b: bool)
- requires true;
- }
-
- class Client {
- method M() {
- var m := StaticM(5);
- var it := new ExampleIterator.ExampleIterator(100);
- var a, b := Worker(it);
- }
- method Worker(xi: ExampleIterator) returns (k: int, m: int) {
- k, m := xi.k + xi.x, xi.y;
- var mr := xi.MoveNext();
- if (mr) {
- k := xi.x;
- } else {
- assert k == xi.k + xi.x && m == xi.y;
- }
- }
- method GenericTester(g0: GenericIterator<bool>, g2: GenericIterator)
- requires g0.u;
- {
- g0.t := true; // error: not allowed to assign to .t
- g0.u := true; // allowed (but this destroys the validity of 'iter'
- var g1 := new GenericIterator.GenericIterator(20);
- assert g1.u < 200; // .u is an integer
-
- assert g2.u == 200; // error: the type parameter of g2 is unknown
-
- var h0 := new GenericIteratorResult.GenericIteratorResult();
- // so far, the instantiated type of h0 is unknown
- var k := h0.t;
- assert k < 87;
-
- var h1 := new GenericIteratorResult.GenericIteratorResult();
- // so far, the instantiated type of h1 is unknown
- if (*) {
- var b: bool := h1.t; // this determines h1 to be of type GenericIteratorResult<bool>
- } else {
- var x: int := h1.t; // error: h1 would have to be a GenericIteratorResult<int>
- }
-
- var h2 := new GenericIteratorResult; // error: constructor is not mentioned
-
- var h3 := new GenericIterator.GenericIterator(30);
- if (h3.t == h3.u) {
- assert !h3.t; // error: type mismatch
- }
- }
- }
-
- iterator GenericIterator<T>(t: T) yields (u: T)
- {
- while (true) {
- yield t;
- }
- }
-
- iterator GenericIteratorResult<T>() yields (t: T)
- {
- while (*) { yield; }
- }
-
- class AnotherClient {
- method StaticM(b: bool) // [sic]
- {
- }
- method Q() {
- StaticM(true); // this is supposed to resolve to AnotherClient.StaticM, not _default.StaticM
- }
- }
-}
-
-// --------------------------------- _decreases<n> fields
-
-class Cell
-{
- var data: int;
-}
-
-iterator Dieter0(c: Cell)
- requires c != null;
- decreases c.data, c.data, c != null;
-{
- assert _decreases0 == _decreases1;
- assert _decreases2;
- assert _decreases3 == null; // error: there is no _decreases3
- assert _decreases0 == null; // error: type mismatch
- _decreases2 := false; // error: the field is immutable
-}
-
-iterator Dieter1(c: Cell)
- requires c != null;
-{
- assert _decreases0 == c;
- assert _decreases1; // error: there is no _decreases1
-}
-
-iterator Dieter2()
-{
- assert _decreases0 == null; // error: there is no _decreases0
-}
diff --git a/Test/dafny0/Iterators.dfy b/Test/dafny0/Iterators.dfy
deleted file mode 100644
index c6a0488b..00000000
--- a/Test/dafny0/Iterators.dfy
+++ /dev/null
@@ -1,235 +0,0 @@
-iterator MyIter<T>(q: T) yields (x: T, y: T)
-{
-}
-
-iterator MyIntIter() yields (x: int, y: int)
-{
- x, y := 0, 0;
- yield;
- yield 2, 3;
- x, y := y, x;
- yield;
-}
-
-iterator Naturals(u: int) yields (n: nat)
- requires u < 25; // just to have some precondition
- ensures false; // never ends
-{
- n := 0;
- while (true)
- {
- yield n;
- n := n + 1;
- }
-}
-
-method Main() {
- var m := new MyIter.MyIter(12);
- assert m.ys == m.xs == [];
- var a := m.x;
- if (a <= 13) {
- print "-- ", m.x, " --\n";
- }
-
- var mer := m.MoveNext();
- if (mer) {
- mer := m.MoveNext();
- mer := m.MoveNext(); // error
- }
-
- var n := new MyIntIter.MyIntIter();
- var patience := 10;
- while (patience != 0)
- invariant n.Valid() && fresh(n._new);
- {
- var more := n.MoveNext();
- if (!more) { break; }
- print n.x, ", ", n.y, "\n";
- patience := patience - 1;
- }
-
- var o := new Naturals.Naturals(18);
- var remaining := 100;
- while (remaining != 0)
- invariant o.Valid() && fresh(o._new);
- {
- var more := o.MoveNext();
- assert more;
- print o.n, " ";
- remaining := remaining - 1;
- if (remaining % 10 == 0) { print "\n"; }
- }
-}
-
-// -----------------------------------------------------------
-
-class Cell {
- var data: int;
-}
-
-iterator IterA(c: Cell)
- requires c != null;
- modifies c;
-{
- while (true) {
- c.data := *;
- yield;
- }
-}
-
-method TestIterA()
-{
- var c := new Cell;
- var iter := new IterA.IterA(c);
- var tmp := c.data;
- var more := iter.MoveNext();
- assert tmp == c.data; // error
-}
-
-// -----------------------------------------------------------
-
-iterator IterB(c: Cell)
- requires c != null;
- modifies c;
- yield ensures c.data == old(c.data);
- ensures true;
- decreases c, c != null, c.data;
-{
- assert _decreases0 == c;
- assert _decreases1 == (c != null);
- assert _decreases2 == c.data; // error: c is not protected by the reads clause
- var tmp := c.data;
- if (*) { yield; }
- assert tmp == c.data; // error: c is not protected by the reads clause
- c.data := *;
-}
-
-method TestIterB()
-{
- var c := new Cell;
- var iter := new IterB.IterB(c);
- var tmp := c.data;
- var more := iter.MoveNext();
- if (more) {
- assert tmp == c.data; // no prob
- } else {
- assert tmp == c.data; // error: the postcondition says nothing about this
- }
-}
-
-// ------------------ yield statements, and_decreases variables ----------------------------------
-
-iterator IterC(c: Cell)
- requires c != null;
- modifies c;
- reads c;
- yield ensures c.data == old(c.data);
- ensures true;
- decreases c, c, c.data;
-{
- assert _decreases2 == c.data; // this time, all is fine, because the iterator has an appropriate reads clause
- var tmp := c.data;
- if (*) { yield; }
- if (*) { yield; }
- assert tmp == c.data; // this time, all is fine, because the iterator has an appropriate reads clause
- c.data := *;
-}
-
-method TestIterC()
-{
- var c := new Cell;
- var iter := new IterC.IterC(c);
- var tmp := c.data;
- var more := iter.MoveNext();
- if (more) {
- assert tmp == c.data; // no prob
- } else {
- assert tmp == c.data; // error: the postcondition says nothing about this
- }
-
- iter := new IterC.IterC(c);
- c.data := 17;
- more := iter.MoveNext(); // error: iter.Valid() may not hold
-}
-
-// ------------------ allocations inside an iterator ------------------
-
-iterator AllocationIterator(x: Cell)
-{
- assert _new == {};
- var h := new Cell;
- assert _new == {h};
-
- SomeMethod();
- assert x !in _new;
- assert null !in _new;
- assert h in _new;
-
- ghost var saveNew := _new;
- var u, v := AnotherMethod();
- assert u in _new;
- if {
- case true => assert v in _new - saveNew ==> v != null && fresh(v);
- case true => assert !fresh(v) ==> v !in _new;
- case true => assert v in _new; // error: it may be, but, then again, it may not be
- }
-}
-
-static method SomeMethod()
-{
-}
-
-static method AnotherMethod() returns (u: Cell, v: Cell)
- ensures u != null && fresh(u);
-{
- u := new Cell;
-}
-
-iterator DoleOutReferences(u: Cell) yields (r: Cell, c: Cell)
- yield ensures r != null && fresh(r) && r !in _new;
- yield ensures c != null && fresh(c); // but we don't say whether it's in _new
- ensures false; // goes forever
-{
- var myCells: seq<Cell> := [];
- while (true)
- invariant forall z :: z in myCells ==> z in _new;
- {
- c := new Cell;
- r := new Cell;
- c.data, r.data := 12, 12;
- myCells := myCells + [c];
- _new := _new - {r}; // remove our interest in 'r'
- yield;
- if (*) {
- _new := _new + {c}; // fine, since 'c' is already in _new
- _new := _new + {u}; // error: this does not shrink the set
- } else if (*) {
- assert c.data == 12; // still true, since 'c' is in _new
- assert c in _new; // as is checked here as well
- assert r.data == 12; // error: it may have changed
- } else {
- parallel (z | z in myCells) {
- z.data := z.data + 1; // we're allowed to modify these, because they are all in _new
- }
- }
- }
-}
-
-method ClientOfNewReferences()
-{
- var m := new DoleOutReferences.DoleOutReferences(null);
- var i := 86;
- while (i != 0)
- invariant m.Valid() && fresh(m._new);
- {
- var more := m.MoveNext();
- assert more; // follows from 'ensures' clause of the iterator
- if (*) {
- m.r.data := i; // this change is allowed, because we own it
- } else {
- m.c.data := i; // this change, by itself, is allowed
- assert m.Valid(); // error: ... however, don't expect m.Valid() to survive the change to m.c.data
- }
- i := i - 1;
- }
-}
diff --git a/Test/dafny0/LetExpr.dfy b/Test/dafny0/LetExpr.dfy
deleted file mode 100644
index 11bf4fbe..00000000
--- a/Test/dafny0/LetExpr.dfy
+++ /dev/null
@@ -1,149 +0,0 @@
-method M0(n: int)
- requires var f := 100; n < f; requires var t, f := true, false; (t && f) || n < 100;
-{
- assert n < 200;
- assert 0 <= n; // error
-}
-
-method M1()
-{
- assert var f := 54; var g := f + 1; g == 55;
-}
-
-method M2()
-{
- assert var f := 54; var f := f + 1; f == 55;
-}
-
-function method Fib(n: nat): nat
-{
- if n < 2 then n else Fib(n-1) + Fib(n-2)
-}
-
-method M3(a: array<int>) returns (r: int)
- requires a != null && forall i :: 0 <= i < a.Length ==> a[i] == 6;
- ensures (r + var t := r; t*2) == 3*r;
-{
- assert Fib(2) + Fib(4) == Fib(0) + Fib(1) + Fib(2) + Fib(3);
-
- {
- var x,y := Fib(8), Fib(11);
- assume x == 21;
- assert Fib(7) == 3 ==> Fib(9) == 24;
- assume Fib(1000) == 1000;
- assume Fib(9) - Fib(8) == 13;
- assert Fib(9) <= Fib(10);
- assert y == 89;
- }
-
- assert Fib(1000) == 1000; // does it still know this?
-
- parallel (i | 0 <= i < a.Length) ensures true; {
- var j := i+1;
- assert j < a.Length ==> a[i] == a[j];
- }
-}
-
-// M4 is pretty much the same as M3, except with things rolled into expressions.
-method M4(a: array<int>) returns (r: int)
- requires a != null && forall i :: 0 <= i < a.Length ==> a[i] == 6;
- ensures (r + var t := r; t*2) == 3*r;
-{
- assert Fib(2) + Fib(4) == Fib(0) + Fib(1) + Fib(2) + Fib(3);
- assert
- var x,y := Fib(8), Fib(11);
- assume x == 21;
- assert Fib(7) == 3 ==> Fib(9) == 24;
- assume Fib(1000) == 1000;
- assume Fib(9) - Fib(8) == 13;
- assert Fib(9) <= Fib(10);
- y == 89;
- assert Fib(1000) == 1000; // still known, because the assume was on the path here
- assert forall i :: 0 <= i < a.Length ==> var j := i+1; j < a.Length ==> a[i] == a[j];
-}
-
-var index: int;
-method P(a: array<int>) returns (b: bool, ii: int)
- requires a != null && exists k :: 0 <= k < a.Length && a[k] == 19;
- modifies this, a;
- ensures ii == index;
- // The following uses a variable with a non-old definition inside an old expression:
- ensures 0 <= index < a.Length && old(a[ii]) == 19;
- ensures 0 <= index < a.Length && var newIndex := index; old(a[newIndex]) == 19;
- // The following places both the variable and the body inside an old:
- ensures b ==> old(var oldIndex := index; 0 <= oldIndex < a.Length && a[oldIndex] == 17);
- // Here, the definition of the variable is old, and it's used both inside and
- // inside an old expression:
- ensures var oi := old(index); oi == index ==> a[oi] == 21 && old(a[oi]) == 19;
-{
- b := 0 <= index < a.Length && a[index] == 17;
- var i, j := 0, -1;
- while (i < a.Length)
- invariant 0 <= i <= a.Length;
- invariant forall k :: 0 <= k < i ==> a[k] == 21;
- invariant forall k :: i <= k < a.Length ==> a[k] == old(a[k]);
- invariant (0 <= j < i && old(a[j]) == 19) ||
- (j == -1 && exists k :: i <= k < a.Length && a[k] == 19);
- {
- if (a[i] == 19) { j := i; }
- i, a[i] := i + 1, 21;
- }
- index := j;
- ii := index;
-}
-
-method PMain(a: array<int>)
- requires a != null && exists k :: 0 <= k < a.Length && a[k] == 19;
- modifies this, a;
-{
- var s := a[..];
- var b17, ii := P(a);
- assert s == old(a[..]);
- assert s[index] == 19;
- if (*) {
- assert a[index] == 19; // error (a can have changed in P)
- } else {
- assert b17 ==> 0 <= old(index) < a.Length && old(a[index]) == 17;
- assert index == old(index) ==> a[index] == 21 && old(a[index]) == 19;
- }
-}
-
-// ---------- lemmas ----------
-
-method Theorem0(n: int)
- requires 1 <= n;
- ensures 1 <= Fib(n);
-{
- if (n < 3) {
- } else {
- Theorem0(n-2);
- Theorem0(n-1);
- }
-}
-
-ghost method Theorem1(n: int)
- requires 1 <= n;
- ensures 1 <= Fib(n);
-{
- // in a ghost method, the induction tactic takes care of it
-}
-
-function Theorem2(n: int): int
- requires 1 <= n;
- ensures 1 <= Fib(n);
-{
- if n < 3 then 5 else
- var x := Theorem2(n-2);
- var y := Theorem2(n-1);
- x + y
-}
-
-function Theorem3(n: int): int
- requires 1 <= n;
- ensures 1 <= Fib(n);
-{
- if n < 3 then 5 else
- var x := Theorem3(n-2);
- var y := Theorem3(n-1);
- 5
-}
diff --git a/Test/dafny0/LiberalEquality.dfy b/Test/dafny0/LiberalEquality.dfy
deleted file mode 100644
index b9b4629b..00000000
--- a/Test/dafny0/LiberalEquality.dfy
+++ /dev/null
@@ -1,55 +0,0 @@
-
-class Array<T>
-{
- var Length: nat;
-}
-
-class Test<T> {
- var a: Array<int>;
- var b: Array<T>;
- predicate valid()
- reads this, a, b;
- {
- a != null && b != null && a != b && a.Length == b.Length
- }
-}
-
-method m1<T, U>(t: T, u: U)
- requires t != u; // Cannot compare type parameters (can only compare reference types that could be the same)
-{
-
-}
-
-method m2<T>(t: array<T>, a: array<int>)
- requires t != null && a != null && t != a && t.Length == a.Length;
-{
-
-}
-
-
-class Weird<T, U, V>
-{
-
-}
-
-
-method m3<T, V>(a: Weird<T, int, V>, b: Weird<T, bool, V>)
- requires a == b; // Bad: second parameter can't be both bool and int.
-{
-
-}
-
-
-method m4<T, U, V>(a: Weird<T, U, V>, b: Weird<T, bool, V>)
- requires a == b;
-{
-
-}
-
-
-// Just to make sure nothing went wrong.
-method m5(a: array<int>, b: array<bool>)
- requires a == b; // Bad: never equal
-{
-
-}
diff --git a/Test/dafny0/LoopModifies.dfy b/Test/dafny0/LoopModifies.dfy
deleted file mode 100644
index c9d87f86..00000000
--- a/Test/dafny0/LoopModifies.dfy
+++ /dev/null
@@ -1,318 +0,0 @@
-
-// regular modifies sanity test:
-method Testing1(a: array<int>)
- requires a != null && a.Length > 0;
-{
- a[0] := 0; // ERROR
-}
-
-// array inside while loop, without explict modifies clause:
-method Testing2(a: array<int>)
- requires a != null && a.Length > 0;
-{
- var i := 0;
- while(i < 10)
- invariant 0 <= i <= 10;
- {
- a[0] := i; // ERROR
- i := i + 1;
- }
-}
-
-// array inside while loop, without explict modifies clause:
-method Testing2A(a: array<int>)
- requires a != null && a.Length > 0;
- modifies a;
-{
- var i := 0;
- while(i < 10)
- invariant 0 <= i <= 10;
- {
- // now there is no problem.
- a[0] := i;
- i := i + 1;
- }
-}
-
-// array inside while loop, with explict modifies clause:
-method Testing3(a: array<int>)
- requires a != null && a.Length > 0;
-{
- var i := 0;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies;
- {
- a[0] := i; // ERROR
- i := i + 1;
- }
-}
-
-// modifies restricts:
-method Testing4(a: array<int>)
- requires a != null && a.Length > 0;
- modifies a;
-{
- var i := 0;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies;
- {
- a[0] := i; // ERROR
- i := i + 1;
- }
- // should be ok.
- a[0] := 1;
-}
-
-// modifies not a subset:
-method Testing5(a: array<int>)
- requires a != null && a.Length > 0;
- modifies;
-{
- var i := 0;
- while(i < 10) // ERROR
- invariant 0 <= i <= 10;
- modifies a;
- {
- a[0] := i;
- i := i + 1;
- }
-}
-
-// modifies is a subset, but modifications occur outside:
-method Testing6(a: array<int>, b: array<int>)
- requires a != null && a.Length > 0;
- requires b != null && b.Length > 0;
- modifies a, b;
-{
- var i := 0;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies a;
- {
- // cool.
- a[0] := i;
-
- // not cool.
- b[0] := i; // ERROR
- i := i + 1;
- }
-}
-
-// heap outside modifies is actually preserved:
-method Testing7(a: array<int>, b: array<int>)
- requires a != null && a.Length > 0;
- requires b != null && b.Length > 0;
- requires a != b;
- modifies a, b;
-{
- var i := 0;
- b[0] := 4;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies a;
- {
- // still good.
- a[0] := i;
- i := i + 1;
- }
- // this is new, and good:
- assert b[0] == 4;
-}
-
-// modifies actually restrict frame when nested:
-method Testing8(a: array<int>, b: array<int>, c: array<int>)
- requires a != null && a.Length > 0;
- requires b != null && b.Length > 0;
- requires c != null && c.Length > 0;
- requires a != b && b != c && c != a;
- modifies a, b, c;
-{
- var i := 0;
- b[0] := 4;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies a, b;
- {
- var j := 0;
- while(j < 10)
- invariant 0 <= j <= 10;
- modifies a;
- {
- // happy:
- a[0] := j;
- // not happy:
- b[0] := i; // ERROR
- j := j + 1;
- }
- i := i + 1;
- }
- c[0] := 1;
-}
-
-// heap outside modifies preserved when nested:
-method Testing9(a: array<int>, b: array<int>, c: array<int>)
- requires a != null && a.Length > 0;
- requires b != null && b.Length > 0;
- requires c != null && c.Length > 0;
- requires a != b && b != c && c != a;
- modifies a, b, c;
-{
- var i := 0;
- b[0] := 4;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies a, b;
- {
- var j := 0;
- b[0] := i;
- while(j < 10)
- invariant 0 <= j <= 10;
- modifies a;
- {
- a[0] := j;
- j := j + 1;
- }
- assert b[0] == i;
- i := i + 1;
- }
- c[0] := 1;
-}
-
-// allocation, fresh tests:
-
-// allocated things not automatically in modifies of loops:
-method Testing10(a: array<int>)
- requires a != null && a.Length > 0;
- modifies a;
-{
- var i := 0;
- var arr := new int[1];
- arr[0] := 1; // good, even though not in method modifies.
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies a;
- {
- arr[0] := 1; // ERROR
- i := i + 1;
- }
-}
-
-// unless no modifies given, in which case the context is used:
-method Testing10a(a: array<int>)
- requires a != null && a.Length > 0;
- modifies a;
-{
- var i := 0;
- var arr := new int[1];
- arr[0] := 1; // still good.
- while(i < 10)
- invariant 0 <= i <= 10;
- {
- arr[0] := 1; // no modifies, so allowed to touch arr.
- i := i + 1;
- }
-}
-
-
-// loop inherits modifies clause of enclosing loop, not method.
-method Testing10b(a: array<int>, b: array<int>)
- requires a != null && a.Length > 0;
- requires b != null && b.Length > 0;
- requires a != b;
- modifies a,b;
-{
- b[0] := 4;
- var j := 0;
- while (j < 10)
- modifies a;
- {
- var i := 1;
- while (i < 10)
- // note: no explicit modifies clause
- {
- a[0] := 1;
- i := i + 1;
- }
- assert b[0] == 4; // should be fine.
- j := j + 1;
- }
-}
-
-// arr still accessible after loop that can't touch it.
-method Testing11()
-{
- var i := 0;
- var arr := new int[1];
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies;
- {
- arr := new int[1];
- arr[0] := 1;
- var j := 0;
- while(j < 10)
- invariant 0 <= j <= 10;
- modifies;
- {
- // can't touch arr in here.
- j := j + 1;
- }
- arr[0] := 2;
- i := i + 1;
- }
-}
-
-// allocation inside a loop is still ok:
-method Testing11a(a: array<int>)
- requires a != null && a.Length > 0;
- modifies a;
-{
- var i := 0;
- while(i < 10)
- invariant 0 <= i <= 10;
- modifies a;
- {
- var arr := new int[1];
- arr[0] := 1; // can modify arr, even though it
- // is not in modifies because it is fresh.
- var j := 0;
- while(j < 10)
- invariant 0 <= j <= 10;
- modifies a;
- {
- arr[0] := 3; // ERROR: can't touch arr, as allocated before modifies captured.
- j := j + 1;
- }
- i := i + 1;
- }
-}
-
-class Elem
-{
- var i: int;
-}
-
-// capture of modifies clause at beginning of loop:
-method Testing12(a: Elem, b: Elem, c: Elem)
- requires a != null && b != null && c != null;
- requires a != b && b != c && c != a; // all different.
- modifies a, b, c;
-{
- var i := 0;
- var S := {a, b, c};
- // S "captured" here for purposes of modifies clause.
- while(S != {})
- modifies S;
- decreases S;
- {
- var j := choose S;
- // these still good, even though S shrinks to not include them.
- a.i := i;
- b.i := i;
- c.i := i;
- S := S - {j};
- i := i + 1;
- }
-} \ No newline at end of file
diff --git a/Test/dafny0/Maps.dfy b/Test/dafny0/Maps.dfy
deleted file mode 100644
index 1c245952..00000000
--- a/Test/dafny0/Maps.dfy
+++ /dev/null
@@ -1,192 +0,0 @@
-
-// This method can be used to test compilation.
-method Main()
-{
- var m := map[2:=3];
- // test "in"
- if(2 in m)
- {
- print "m0\n";
- }
- else
- { assert false; }
- // test "!in"
- if(3 !in m)
- {
- print "m1\n";
- }
- else
- { assert false; }
- // dereference
- if(m[2] == 3)
- {
- print "m2\n";
- }
- else
- { assert false; }
- // test disjoint operator
- if(m !! map[3 := 3])
- {
- print "m3\n";
- }
- else
- { assert false; }
- // updates should replace values that already exist
- if(m[2 := 4] == map[2 := 4])
- {
- print "m4\n";
- }
- else
- { assert false; }
- // add something to the map
- if(m[7 := 1] == map[2 := 3,7 := 1])
- {
- print "m5\n";
- }
- else
- { assert false; }
- // test applicative nature of Map<U, V> in C#
- if(m == map[2 := 3])
- {
- print "m6\n";
- }
- else
- { assert false; }
- // this should print all m1, m2, ... m6.
-}
-
-method m()
-{
- var a := map[2:=3]; var b := map[3:=2];
- assert a[b[3]] == 3;
-}
-method m2(a: map<int, bool>, b: map<int, bool>)
- requires forall i | 0 <= i < 100 :: i in a && i in b && a[i] != b[i];
-{
- assert forall i | 0 <= i < 100 :: a[i] || b[i];
-}
-method m3(a: map<int, int>)
- requires forall i | 0 <= i < 100 :: i in a && a[i] == i*i;
-{
- assert a[20] == 400;
-}
-method m4()
-{
- var a := map[3 := 9];
- if(a[4] == 4) // UNSAFE, 4 not in the domain
- {
- m();
- }
-}
-
-method m5(a: map<int, int>)
- requires 20 in a;
-{
- assert a[20] <= 0 || 0 < a[20];
-}
-method m6()
-{
- var a := map[3 := 9];
- assert a[3:=5] == map[3:=5];
- assert a[2:=5] == map[2:=5, 3:=9];
- assert a[2:=5] == map[2:=6, 3:=9, 2:=5]; // test the ordering of assignments in the map literal
-}
-method m7()
-{
- var a := map[1:=1, 2:=4, 3:=9];
- assert forall i | i in a :: a[i] == i * i;
- assert 0 !in a;
- assert 1 in a;
- assert 2 in a;
- assert 3 in a;
- assert forall i | i < 1 || i > 3 :: i !in a;
-}
-method m8()
-{
- var a := map[];
- assert forall i :: i !in a; // check emptiness
- var i,n := 0, 100;
- while(i < n)
- invariant 0 <= i <= n;
- invariant forall i | i in a :: a[i] == i * i;
- invariant forall k :: 0 <= k < i <==> k in a;
- {
- a := a[i := i * i];
- i := i + 1;
- }
- assert a !! map[-1:=2];
- m3(a);
-}
-method m9()
-{
- var a, b := map[], map[];
- assert a !! b;
- b := map[2:=3,4:=2,5:=-6,6:=7];
- assert a !! b;
- assert b !! map[6:=3]; // ERROR, both share 6 in the domain.
-}
-method m10()
-{
- var a, b := map[], map[];
- assert a !! b;
- b := map[2:=3,4:=2,5:=-6,6:=7];
- assert a !! b;
- a := map[3:=3,1:=2,9:=-6,8:=7];
- assert a !! b;
-}
-method m11<U, V>(a: map<U, V>, b: map<U, V>)
- requires forall i :: !(i in a && i in b);
-{
- assert a !! b;
-}
-
-method m12()
-{
- var x := map i | 0 <= i < 10 :: i * 2;
- assert 0 in x;
- assert 1 in x;
- assert 10 !in x;
- assert x[0] == 0 && x[2] == 4;
-}
-
-function domain<U, V>(m: map<U,V>): set<U>
- ensures forall i :: i in domain(m) <==> i in m;
-{
- set s | s in m
-}
-
-method m13()
-{
- var s := {0, 1, 3, 4};
- var x := map i | i in s :: i;
- assert forall i | i in x :: x[i] == i;
- assert domain(x) == s;
-}
-
-function union<U, V>(m: map<U,V>, m': map<U,V>): map<U,V>
- requires m !! m';
- ensures forall i :: i in union(m, m') <==> i in m || i in m';
- ensures forall i :: i in m ==> union(m, m')[i] == m[i];
- ensures forall i :: i in m' ==> union(m, m')[i] == m'[i];
-{
- map i | i in (domain(m) + domain(m')) :: if i in m then m[i] else m'[i]
-}
-
-method m14()
-{
- var s, t := {0, 1}, {3, 4};
- var x,y := map i | i in s :: i, map i | i in t :: 1+i;
- ghost var u := union(x,y);
- assert u[1] == 1 && u[3] == 4;
- assert domain(u) == {0, 1, 3, 4};
-}
-
-class A { var x: int; }
-
-method m15(b: set<A>)
- requires forall a | a in b :: a != null;
-{
- var m := map a | a in b :: a.x;
- var aa := new A;
- assert aa !in m;
-} \ No newline at end of file
diff --git a/Test/dafny0/Modules0.dfy b/Test/dafny0/Modules0.dfy
deleted file mode 100644
index 2bc3c4be..00000000
--- a/Test/dafny0/Modules0.dfy
+++ /dev/null
@@ -1,322 +0,0 @@
-// ---------------------- duplicate types within a module
-
-module Wazzup {
- class WazzupA { }
- class WazzupA { } // error: duplicate type
- datatype WazzupA = W_A_X; // error: duplicate type
- type WazzupA; // error: duplicate type
-
- type WazzupB;
- type WazzupB; // error: duplicate type
- class WazzupB { } // error: duplicate type
- datatype WazzupB = W_B_X; // error: duplicate type
-}
-
-// ---------------------- duplicate types across modules
-
-module M {
- class T { }
- class U { }
-}
-
-module N {
- class T { }
-}
-
-module U {
- import NN = N;
-}
-
-
-module A { // Note, this has the effect of importing two different T's,
- // but that's okay as long as the module doesn't try to access
- // one of them
- import MM = M;
- import NN = N;
- class X {
- var t: MM.T; // error: use of the ambiguous name T
- function F(x: MM.T): // error: use of the ambiguous name T
- MM.T // error: use of the ambiguous name T
- { x }
- method M(x: NN.T) // error: use of the ambiguous name T
- returns (y: NN.T) // error: use of the ambiguous name T
- }
-}
-
-
-// --------------- calls
-
-module X0 {
- class MyClass0 {
- method Down() {
- }
- method Up(x1: MyClass1, // error: MyClass1 is not in scope
- x2: MyClass2) { // error: MyClass2 is not in scope
- }
- }
-}
-
-module X1 {
- import X0' = X0;
- class MyClass1 {
- method Down(x0: X0'.MyClass0) {
- x0.Down();
- }
- method Up(x2: MyClass2) { // error: class MyClass2 is not in scope
- }
- }
-}
-
-module X2 {
- class MyClass2 {
- method Down(x1: MyClass1, x0: MyClass0) {
- x1.Down(x0);
- }
- method WayDown(x0: MyClass0) {
- x0.Down();
- }
- method Up() {
- }
- method Somewhere(y: MyClassY) {
- y.M();
- }
- }
-}
-
-module YY {
- class MyClassY {
- method M() { }
- method P(g: ClassG) { // error: ClassG is not in scope
- }
- }
-}
-
-class ClassG {
- method T() { }
- function method TFunc(): int { 10 }
- method V(y: MyClassY) { // Note, MyClassY is in scope, since we are in the _default
- // module, which imports everything
- y.M();
- }
-}
-
-method Ping() {
- Pong(); // allowed: intra-module call
-}
-
-method Pong() {
- Ping(); // allowed: intra-module call
-}
-
-method ProcG(g: ClassG) {
- g.T(); // allowed: intra-module call
- var t := g.TFunc(); // allowed: intra-module call
-}
-
-// ---------------------- some ghost stuff ------------------------
-
-class Ghosty {
- method Caller() {
- var x := 3;
- ghost var y := 3;
- Callee(x, y); // fine
- Callee(x, x); // fine
- Callee(y, x); // error: cannot pass in ghost to a physical formal
- Theorem(x); // fine
- Theorem(y); // fine, because it's a ghost method
- }
- method Callee(a: int, ghost b: int) { }
- ghost method Theorem(a: int) { }
-}
-
-var SomeField: int;
-
-method SpecialFunctions()
- modifies this;
-{
- SomeField := SomeField + 4;
- var a := old(SomeField); // error: old can only be used in ghost contexts
- var b := fresh(this); // error: fresh can only be used in ghost contexts
- var c := allocated(this); // error: allocated can only be used in ghost contexts
- if (fresh(this)) { // this guard makes the if statement a ghost statement
- ghost var x := old(SomeField); // this is a ghost context, so it's okay
- ghost var y := allocated(this); // this is a ghost context, so it's okay
- }
-}
-
-// ---------------------- illegal match expressions ---------------
-
-datatype Tree = Nil | Cons(int, Tree, Tree);
-
-function NestedMatch0(tree: Tree): int
-{
- match tree
- case Nil => 0
- case Cons(h,l,r) =>
- match tree // error: cannot match on "tree" again
- case Nil => 0
- case Cons(hh,ll,rr) => hh
-}
-
-function NestedMatch1(tree: Tree): int
-{
- match tree
- case Nil => 0
- case Cons(h,l,r) =>
- match l
- case Nil => 0
- case Cons(h0,l0,r0) =>
- match r
- case Nil => 0
- case Cons(h1,l1,r1) => h + h0 + h1
-}
-
-function NestedMatch2(tree: Tree): int
-{
- match tree
- case Nil => 0
- case Cons(h,l,r) =>
- match l
- case Nil => 0
- case Cons(h,l0,tree) => // fine to declare another "h" and "tree" here
- match r
- case Nil => 0
- case Cons(h1,l1,r1) => h + h1
-}
-
-function NestedMatch3(tree: Tree): int
-{
- match tree
- case Nil => 0
- case Cons(h,l,r) =>
- match l
- case Nil => 0
- case Cons(h0,l0,r0) =>
- match l // error: cannot match on "l" again
- case Nil => 0
- case Cons(h1,l1,r1) => h + h0 + h1
-}
-
-// ---------------------- direct imports are not transitive
-
-module ATr {
- class X {
- method M() returns (q: int)
- {
- q := 16;
- }
- static method Q() returns (q: int)
- {
- q := 18;
- }
- }
-}
-
-module BTr {
- import A = ATr;
- class Y {
- method N() returns (x: A.X)
- ensures x != null;
- {
- x := new X;
- }
- }
-}
-
-module CTr {
- import B = BTr;
- class Z {
- var b: B.Y; // fine
- var a: B.X; // error: imports don't reach name X explicitly
- }
-}
-module CTs {
- import B = BTr;
- method P() {
- var y := new B.Y;
- var x := y.N(); // this is allowed and will correctly infer the type of x to
- // be X, but X could not have been mentioned explicitly
- var q := x.M();
- var r := X.Q(); // error: X is not in scope
- var s := x.DoesNotExist(); // error: method not declared in class X
- }
-}
-
-// ---------------------- module-local declarations override imported declarations
-
-module NonLocalA {
- class A {
- method M() { }
- }
- class Common {
- method P() { }
- }
-}
-
-module NonLocalB {
- class B {
- method N() { }
- }
- class D {
- method K() returns (b: B)
- ensures b != null;
- {
- return new B;
- }
- }
- class Common {
- method P() { }
- }
-}
-
-module Local {
- import AA = NonLocalA;
- import BB = NonLocalB;
- class MyClass {
- method MyMethod()
- {
- var b := new B;
- var c := new Common;
- var d := new D;
- c.Q(); // this is fine, since c's type is the local class Common
- b.R(); // fine, since B refers to the locally declared class
- var nonLocalB := d.K();
- nonLocalB.N();
- nonLocalB.R(); // error: this is not the local type B
- }
- }
- class B {
- method R() { }
- }
- class Common {
- method Q() { }
- }
-}
-
-// ------ qualified type names ----------------------------------
-
-module Q_Imp {
- class Node { }
- datatype List<T> = Nil | Cons(T, List);
- class Klassy {
- method Init()
- }
-}
-
-module Q_M {
- method MyMethod(root: Q_Imp.Node, S: set<Node>)
- requires root in S; // error: the element type of S does not agree with the type of root
- {
- var i := new Q_Imp.Node;
- var j := new Node;
- assert i != j; // error: i and j have different types
- var k: LongLostModule.Node; // error: undeclared module
- var l: Wazzup.WazzupA; // error: undeclared module (it has not been imported)
- var m: Q_Imp.Edon; // error: undeclared class in module Q_Imp
- var n: Q_Imp.List;
- var o := new Q_Imp.List; // error: not a class declared in module Q_Imp
- var p := new Q_Imp.Klassy.Create(); // error: Create is not a method
- var q := new Q_Imp.Klassy.Init();
- }
- class Node { }
-}
diff --git a/Test/dafny0/Modules1.dfy b/Test/dafny0/Modules1.dfy
deleted file mode 100644
index 1f47f3b1..00000000
--- a/Test/dafny0/Modules1.dfy
+++ /dev/null
@@ -1,114 +0,0 @@
-module A {
- import B = Babble;
- class X {
- function Fx(z: B.Z): int
- requires z != null;
- decreases 5, 4, 3;
- { z.G() } // fine; this goes to a different module
- }
- datatype Y = Cons(int, Y) | Empty;
-}
-
-class C {
- method M() { }
- function F(): int { 818 }
-}
-
-method MyMethod() { }
-
-var MyField: int;
-
-module Babble {
- class Z {
- method K() { }
- function G(): int
- decreases 10, 8, 6;
- { 25 }
- }
-}
-
-static function MyFunction(): int { 5 }
-
-class D { }
-
-method Proc0(x: int)
- decreases x;
-{
- if (0 <= x) {
- Proc1(x - 1);
- }
-}
-
-method Proc1(x: int)
- decreases x;
-{
- if (0 <= x) {
- Proc0(x - 1);
- }
-}
-
-method Botch0(x: int)
- decreases x;
-{
- Botch1(x - 1); // error: failure to keep termination metric bounded
-}
-
-method Botch1(x: int)
- decreases x;
-{
- Botch0(x); // error: failure to decrease termination metric
-}
-
-// ------ modules ------------------------------------------------
-
-module A_Visibility {
- class C {
- static predicate P(x: int)
- {
- 0 <= x
- }
- }
- method Main() {
- var y;
- if (C.P(y)) {
- assert 0 <= y; // this much is known of C.P
- assert 2 <= y; // error
- } else {
- assert C.P(8); // this is fine
- }
- }
-}
-
-module B_Visibility {
- import A = A_Visibility;
- method Main() {
- var y;
- if (A.C.P(y)) {
- assert 0 <= y; // this much is known of C.P
- assert 2 <= y; // error
- } else {
- assert A.C.P(8); // error: C.P cannot be established outside the declaring module
- }
- }
-}
-
-// ------ qualified type names ----------------------------------
-
-module Q_Imp {
- class Node { }
- class Klassy {
- method Init()
- }
-}
-
-module Q_M {
- import Q = Q_Imp;
- method MyMethod(root: Q.Node, S: set<Q.Node>)
- requires root in S;
- {
- var i := new Q.Node;
- var j := new Q.Node;
- assert i != j; // fine
- var q := new Q.Klassy.Init();
- }
-}
diff --git a/Test/dafny0/Modules2.dfy b/Test/dafny0/Modules2.dfy
deleted file mode 100644
index 2a5b2be7..00000000
--- a/Test/dafny0/Modules2.dfy
+++ /dev/null
@@ -1,57 +0,0 @@
-
-module A {
- class C {
- var f: int;
- }
- datatype D = E(int) | F(int);
- static function f(n:nat): nat
-}
-module B {
- class C {
- var f: int;
- }
- datatype D = E(int) | F(int);
- static function f(n:nat): nat
-}
-module Test {
- import opened A; // nice shorthand for import opened A = A; (see below)
- method m() {
- var c := new C; // fine, as A was opened
- var c' := new A.C;// also fine, as A is bound
- var i := 43;
- var d := E(i); // these all refer to the same value
- var d' := A.E(i);
- var d'':= A.D.E(i);
- assert d == d' == d'';
- assert f(3) >= 0; // true because f(x): nat
- assert A._default.f(3) >= 0;
- }
-}
-
-module Test2 {
- import opened B as A;
- method m() {
- var c := new C; // fine, as A was opened
- var c' := new B.C;// also fine, as A is bound
- assert B.f(0) >= 0;
- }
-}
-
-module Test3 {
- import opened A;
- import opened B; // everything in B clashes with A
- method m() {
- var c := new C; // bad, ambiguous between A.C and B.C
- var c' := new A.C; // good: qualified.
- var i := 43;
- var d := E(i); // bad, as both A and B give a definition of E
- var d' := D.E(i); // bad, as D is still itself ambiguous.
- var d'':= B.D.E(i); // good, just use the B version
- assert f(3) >= 0; // bad because A and be both define f statically.
- }
-}
-
-module Test4 {
- import A = A; // good: looks strange, but A is not bound on the RHS of the equality
- import B; // the same as the above, but for module B
-} \ No newline at end of file
diff --git a/Test/dafny0/ModulesCycle.dfy b/Test/dafny0/ModulesCycle.dfy
deleted file mode 100644
index 72b7e6fb..00000000
--- a/Test/dafny0/ModulesCycle.dfy
+++ /dev/null
@@ -1,12 +0,0 @@
-
-module V {
- import t = T; // error: T is not visible (and isn't even a module)
-}
-
-module A {
- import B = C;
-}
-
-module C {
- import D = A;
-} \ No newline at end of file
diff --git a/Test/dafny0/MultiDimArray.dfy b/Test/dafny0/MultiDimArray.dfy
deleted file mode 100644
index ff30ef8a..00000000
--- a/Test/dafny0/MultiDimArray.dfy
+++ /dev/null
@@ -1,91 +0,0 @@
-class A {
- // all of the following array types are allowed
- var a: array<int>;
- var b: array <bool>;
- var c: array <A>;
- var d: array1 <A>; // this is a synonym for array<A>
- var e: array2 <A>;
- var f: array3 <A>;
- var g: array300 <A>;
- var h: array3000 <array2<int>>;
-
- method M0()
- requires a != null && b != null;
- modifies a;
- {
- if (5 <= a.Length && a.Length <= b.Length) {
- var x := b[2];
- var y := a[1];
- var z := a[2];
- a[2] := a[2] + 1;
- assert x == b[2];
- assert y == a[1];
- assert z == a[2] - 1;
- }
- }
-
- method M1()
- requires a != null && d != null;
- modifies a;
- {
- if (5 <= a.Length && a.Length <= d.Length) {
- var x := d[2];
- var y := a[1];
- var z := a[2];
- a[2] := a[2] + 1;
- assert y == a[1];
- assert z == a[2] - 1;
- assert x == d[2]; // error: a and d may be equal
- }
- }
-
- method M2(i: int, j: int, k: int, val: A)
- requires f != null;
- requires 0 <= i && i < f.Length0;
- requires 0 <= j && j < f.Length1;
- requires 0 <= k && k < f.Length2;
- modifies f;
- {
- if (*) {
- if (k < f.Length0) {
- var save := f[k,j,k];
- f[i,j,k] := val;
- assert save == f[k,j,k]; // error: k and i may be equal
- }
- } else if (k < f.Length0 && k != i) {
- if (k < f.Length0) {
- var save := f[k,j,k];
- f[i,j,k] := val;
- assert save == f[k,j,k]; // fine
- }
- }
- }
-
- method M3(i: int, j: int, k: int)
- requires f != null;
- requires 0 <= i && i < f.Length0;
- requires 0 <= j && j < f.Length1;
- requires 0 <= k && k < f.Length2;
- modifies f;
- decreases i;
- {
- if (i != 0) {
- var z := new A[2,3,5]; // first three primes (nice!)
- var s := z[1,2,4]; // first three powers of 2 (tra-la-la)
- var some: A;
- f[i,j,k] := some;
- M3(i-1, j, k);
- assert s == z[1,2,4];
- if (*) {
- assert f[i,j,k] == some; // error: the recursive call may have modified any element in 'f'
- }
- }
- }
-
- method M4(a: array2<bool>) returns (k: int)
- requires a != null;
- ensures 0 <= k;
- {
- k := a.Length0 + a.Length1;
- }
-}
diff --git a/Test/dafny0/MultiSets.dfy b/Test/dafny0/MultiSets.dfy
deleted file mode 100644
index e74873e3..00000000
--- a/Test/dafny0/MultiSets.dfy
+++ /dev/null
@@ -1,103 +0,0 @@
-
-method test1()
-{
- var ms: multiset<int> := multiset{1,1,1};
- var ms2: multiset<int> := multiset{3};
- assert 1 in ms;
- assert forall i :: i != 1 ==> i !in ms; // 1 is the only thing in ms.
-
- assert ((ms - multiset{1}) - multiset {1}) != multiset{}; // it has more than 2 ones
- assert ((ms - multiset{1}) - multiset {1}) - multiset{1} == multiset{}; // and exactly three
-
- assert ms2 - ms == ms2; // set difference works correctly.
- assert ms - multiset{1} == multiset{1,1};
- assert !(multiset{1} !! multiset{1});
- assert exists m :: !(m !! multiset{1});
- assert forall m :: m !! multiset{};
-
- assert forall s :: (s == set x: int | x in ms :: x) ==> s == {1};
-}
-
-method test2(ms: multiset<int>)
-{
- var s := set x | x in ms :: x; // seems to be a reasonable conversion
- assert forall x :: x in s <==> x in ms;
- assert ms !! multiset{};
-}
-
-method test3(s: set<int>)
-{
- assert forall x :: x in s <==> x in multiset(s);
-}
-method test4(sq: seq<int>, a: array<int>)
- requires a != null;
- modifies a;
-{
- assert sq == sq[..|sq|];
- assert sq == sq[0..];
- assert sq == sq[..];
-
- assert a.Length >= 0;
- var s := a[..];
-}
-
-method test5()
-{
- assert multiset({1,1}) == multiset{1};
- assert multiset([1,1]) == multiset{1,1};
-}
-
-method test6(a: array<int>, n: int, e: int)
- requires a != null && 0 <= n < a.Length;
- modifies a;
- ensures multiset(a[..n+1]) == multiset(a[..n]) + multiset{e};
-{
- a[n] := e;
- assert a[..n+1] == a[..n] + [e];
-}
-method test7(a: array<int>, i: int, j: int)
- requires a != null && 0 <= i < j < a.Length;
- modifies a;
- ensures old(multiset(a[..])) == multiset(a[..]);
- ensures a[j] == old (a[i]) && a[i] == old(a[j]);
- ensures forall k :: 0 <= k < a.Length && k !in {i, j} ==> a[k] == old(a[k]);
-{
- ghost var s := a[..i] + [a[i]] + a[i+1 .. j] + [a[j]] + a[j+1..];
- assert a[..] == s;
- a[i], a[j] := a[j], a[i];
- assert a[..] == a[..i] + [a[i]] + a[i+1 .. j] + [a[j]] + a[j+1..];
- assert s == a[..i] + [old(a[i])] + a[i+1 .. j] + [old(a[j])] + a[j+1..];
-}
-method test8(a: array<int>, i: int, j: int)
- requires a != null && 0 <= i < j < a.Length;
- modifies a;
- ensures old(multiset(a[..])) == multiset(a[..]);
- ensures a[j] == old (a[i]) && a[i] == old(a[j]);
- ensures forall k :: 0 <= k < a.Length && k !in {i, j} ==> a[k] == old(a[k]);
-{
- a[i], a[j] := a[j], a[i];
-}
-method test9(a: array<int>, i: int, j: int, limit: int)
- requires a != null && 0 <= i < j < limit <= a.Length;
- modifies a;
- ensures multiset(a[0..limit]) == old(multiset(a[0..limit]));
- ensures a[j] == old (a[i]) && a[i] == old(a[j]);
- ensures forall k :: 0 <= k < limit && k !in {i, j} ==> a[k] == old(a[k]);
-{
- a[i], a[j] := a[j], a[i];
-}
-method test10(s: seq<int>)
- requires |s| > 4;
-{
- assert multiset( s[3 := 2] ) == multiset(s) - multiset{s[3]} + multiset{2};
- assert multiset( (s[2 := 1])[3 := 2] ) == (((multiset(s) - multiset{s[2]}) + multiset{1}) - multiset{s[3]}) + multiset{2};
- assert multiset( (s[2 := s[3]])[3 := s[2]] ) == (((multiset(s) - multiset{s[2]}) + multiset{s[3]}) - multiset{s[3]}) + multiset{s[2]};
-}
-
-method test11(a: array<int>, n: int, c: int)
- requires a != null && 0 <= c < n <= a.Length;
- modifies a;
- ensures multiset(a[c..n-1]) == multiset(a[c..n]) - multiset{a[n-1]};
-{
-
-} \ No newline at end of file
diff --git a/Test/dafny0/NatTypes.dfy b/Test/dafny0/NatTypes.dfy
deleted file mode 100644
index 0513591c..00000000
--- a/Test/dafny0/NatTypes.dfy
+++ /dev/null
@@ -1,137 +0,0 @@
-method M(n: nat) {
- assert 0 <= n;
-}
-
-method Main() {
- M(25);
- M(-25); // error: cannot pass -25 as a nat
-}
-
-var f: nat;
-
-method CheckField(x: nat, y: int)
- requires 0 <= y;
- modifies this;
-{
- var y: nat := y;
-
- assert 0 <= f;
- while (0 < y)
- {
- f := f + 1;
- if (15 < f) {
- f := f - 12;
- }
- y := y - 1;
- }
- assert 0 <= f;
-
- f := x; // no problem
- f := x + 3; // no problem here either
- f := x - 3; // error: cannot prove RHS is a nat
-}
-
-method Generic<T>(i: int, t0: T, t1: T) returns (r: T) {
- if (0 < i) {
- var n: nat := 5;
- var j := Generic(i-1, n, -4);
- assert 0 <= j; // error: the result is an int, not a nat
- var q := FenEric(n, -4);
- assert 0 <= q; // error: the result is an int, not a nat
- }
- r := t1;
-}
-
-function method FenEric<T>(t0: T, t1: T): T
-{
- t1
-}
-
-datatype Pair<T> = Pr(T, T);
-
-method K(n: nat, i: int) {
- match (Pair.Pr(n, i)) {
- case Pr(k, l) =>
- assert k == n; // fine: although the type of k is int, we know it's equal to n
- assert 0 <= k;
- assert 0 <= l; // error: l is an int
- }
-}
-
-datatype List<T> = Nil | Cons(nat, T, List<T>);
-
-method MatchIt(list: List<object>) returns (k: nat)
-{
- match (list) {
- case Nil =>
- case Cons(n, extra, tail) =>
- var w := MatchIt(tail);
- assert 0 <= w;
- assert 0 <= n; // fine
- assert 0 <= n - 10; // error: possible assertion failure
- }
-
- var m := Sum(list);
- assert 0 <= m;
- k := m;
-}
-
-class GenEric<T> {
- var f: T;
-}
-
-function method GE<T>(d: GenEric<T>): bool { true }
-
-method TestGenEric() {
- var ge;
- if (ge != null) {
- var b := GE(ge);
- var n: nat := ge.f; // error: the generic instantiation uses int, not nat
- }
-}
-
-function method Sum(list: List<object>): nat
-{
- match list
- case Nil => 0
- case Cons(x, y, tail) => x + Sum(tail)
-}
-
-function BadSum(list: List<object>): nat
-{
- match list
- case Nil => 0
- case Cons(x, y, tail) => x + BadSum(tail) - 30 // error: may not be a nat
-}
-
-function Abs(x: int): nat
-{
- if 0 <= x then x else -x
-}
-
-// ----- Here are tests that the type of the result value of a function is known by the
-// ----- time the well-formedness of the function's specification is checked.
-
-function TakesANat(n: nat): bool
-{
- n < 29
-}
-
-function Naturally(): nat
- ensures TakesANat(Naturally()); // the wellformedness of this check requires
-{
- 17
-}
-
-function Integrally_Bad(): int
- ensures TakesANat(Integrally_Bad()); // error: well-formedness check fails
-{
- 17
-}
-
-function Integrally_Good(): int
- ensures 0 <= Integrally_Good();
- ensures TakesANat(Integrally_Good()); // here, the needed information follows from the preceding ensures clause
-{
- 17
-}
diff --git a/Test/dafny0/NoTypeArgs.dfy b/Test/dafny0/NoTypeArgs.dfy
deleted file mode 100644
index c41c7990..00000000
--- a/Test/dafny0/NoTypeArgs.dfy
+++ /dev/null
@@ -1,82 +0,0 @@
-datatype List<T> = Nil | Cons(hd: T, tl: List);
-
-method M0() {
- var l: List;
- l := Cons(5, Nil);
- assert l.hd == 5;
-
- var k: MyClass<bool>;
- k := new MyClass;
- k.data := false;
-
- var h := new MyClass;
- h.data := false;
-
- var y := new MyClass.Init(120);
- var z: int := y.data;
-}
-
-method M1() { // same thing as above, but with types filled in explicitly
- var l: List<int>;
- l := Cons(5, Nil);
- assert l.hd == 5;
-
- var k: MyClass<bool>;
- k := new MyClass<bool>;
- k.data := false;
-
- var h := new MyClass<bool>;
- h.data := false;
-
- var y := new MyClass<int>.Init(120);
- var z: int := y.data;
-}
-
-class MyClass<G> {
- var data: G;
- method Init(g: G)
- modifies this;
- {
- data := g;
- }
-}
-
-// ---------------------------------------------------
-
-// The followinng functions and methods are oblivious of the fact that
-// List takes a type parameter.
-
-function concat(xs: List, ys: List): List
-{
- match xs
- case Nil => ys
- case Cons(x, tail) => Cons(x, concat(tail, ys))
-}
-
-function reverse(xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(t, rest) => concat(reverse(rest), Cons(t, Nil))
-}
-
-ghost method Theorem(xs: List)
- ensures reverse(reverse(xs)) == xs;
-{
- match (xs) {
- case Nil =>
- case Cons(t, rest) =>
- Lemma(reverse(rest), Cons(t, Nil));
- }
-}
-
-ghost method Lemma(xs: List, ys: List)
- ensures reverse(concat(xs, ys)) == concat(reverse(ys), reverse(xs));
-{
- match (xs) {
- case Nil =>
- assert forall ws :: concat(ws, Nil) == ws;
- case Cons(t, rest) =>
- assert forall a, b, c :: concat(a, concat(b, c)) == concat(concat(a, b), c);
- }
-}
diff --git a/Test/dafny0/NonGhostQuantifiers.dfy b/Test/dafny0/NonGhostQuantifiers.dfy
deleted file mode 100644
index dc938496..00000000
--- a/Test/dafny0/NonGhostQuantifiers.dfy
+++ /dev/null
@@ -1,191 +0,0 @@
-// This file contains various tests of resolving quantifiers in ghost and non-ghost positions
-
-class MyClass<T> {
- // This function is in a ghost context, so all is cool.
- function GhostF(): bool
- {
- (forall n :: 2 <= n ==> (exists d :: n < d && d < 2*n))
- }
- // But try to make it a non-ghost function, and Dafny will object because it cannot compile the
- // body into code that will terminate.
- function method NonGhostF(): bool
- {
- (forall n :: 2 <= n ==> (exists d :: n < d && d < 2*n)) // error: can't figure out how to compile
- }
- // Add an upper bound to n and things are cool again.
- function method NonGhostF_Bounded(): bool
- {
- (forall n :: 2 <= n && n < 1000 ==> (exists d :: n < d && d < 2*n))
- }
- // Although the heuristics applied are syntactic, they do see through the structure of the boolean
- // operators ==>, &&, ||, and !. Hence, the following three variations of the previous function can
- // also be compiled.
- function method NonGhostF_Or(): bool
- {
- (forall n :: !(2 <= n && n < 1000) || (exists d :: n < d && d < 2*n))
- }
- function method NonGhostF_ImpliesImplies(): bool
- {
- (forall n :: 2 <= n ==> n < 1000 ==> (exists d :: n < d && d < 2*n))
- }
- function method NonGhostF_Shunting(): bool
- {
- (forall n :: 2 <= n ==> 1000 <= n || (exists d :: n < d && d < 2*n))
- }
-
- function method GoodRange(): bool
- {
- (forall n | 2 <= n :: 1000 <= n || (exists d | n < d :: d < 2*n)) && (exists K: nat | K < 100 :: true)
- }
- function method BadRangeForall(): bool
- {
- forall n | n <= 2 :: 1000 <= n || n % 2 == 0 // error: cannot bound range for n
- }
- function method BadRangeExists(): bool
- {
- exists d | d < 1000 :: d < 2000 // error: cannot bound range for d
- }
- function method WhatAboutThis(): bool
- {
- forall n :: 2 <= n && (forall M | M == 1000 :: n < M) ==> n % 2 == 0 // error: heuristics don't get this one for n
- }
-
- // Here are more tests
-
- function method F(a: array<T>): bool
- requires a != null;
- reads a;
- {
- (exists i :: 0 <= i && i < a.Length / 2 && (forall j :: i <= j && j < a.Length ==> a[i] == a[j]))
- }
-
- function method G0(a: seq<T>): bool
- {
- (exists t :: t in a && (forall u :: u in a ==> u == t))
- }
- function method G1(a: seq<T>): bool
- {
- (exists ti :: 0 <= ti && ti < |a| && (forall ui :: 0 <= ui && ui < |a| ==> a[ui] == a[ti]))
- }
-
- // Regrettably, the heuristics don't know about transitivity:
- function method IsSorted0(s: seq<int>): bool
- {
- (forall i, j :: 0 <= i && i < j && j < |s| ==> s[i] <= s[j]) // error: can't figure out how to compile
- }
- function method IsSorted1(s: seq<int>): bool
- {
- (forall j, i :: 0 <= i && i < j && j < |s| ==> s[i] <= s[j]) // error: can't figure out how to compile
- }
- // Add the redundant conjunct "i < |s|" and things are fine.
- function method IsSorted2(s: seq<int>): bool
- {
- (forall i, j :: 0 <= i && i < |s| && i < j && j < |s| ==> s[i] <= s[j])
- }
- // But if you switch the order of i and j, you need a different redundant conjunct.
- function method IsSorted3(s: seq<int>): bool
- {
- (forall j, i :: 0 <= i && i < |s| && i < j && j < |s| ==> s[i] <= s[j]) // error: can't figure out how to compile
- }
- function method IsSorted4(s: seq<int>): bool
- {
- (forall j, i :: 0 <= i && 0 < j && i < j && j < |s| ==> s[i] <= s[j])
- }
-
- // The heuristics look at bound variables in the order given, as is illustrated by the following
- // two functions.
- function method Order0(S: seq<set<int>>): bool
- {
- (forall i, j :: 0 <= i && i < |S| && j in S[i] ==> 0 <= j)
- }
- function method Order1(S: seq<set<int>>): bool
- {
- (forall j, i :: 0 <= i && i < |S| && j in S[i] ==> 0 <= j) // error: can't figure out how to compile
- }
-
- // Quantifiers can be used in other contexts, too.
- // For example, in assert statements and assignment statements.
- method M(s: seq<int>) returns (r: bool, q: bool) {
- assert (forall x :: x in s ==> 0 <= x);
- r := (forall x :: x in s ==> x < 100);
- q := (exists y :: y*y in s); // error: can't figure out how to compile
- }
- // And if expressions.
- function method Select_Good(S: set<int>, a: T, b: T): T
- {
- if (forall x :: x in S ==> 0 <= x && x < 100) then a else b
- }
- function method Select_Bad(S: set<int>, a: T, b: T): T
- {
- if (forall x :: x*x in S ==> 0 <= x && x < 100) then a else b // error: can't figure out how to compile
- }
- // (the same thing, but in a ghost function is fine, though)
- function Select_Bad_Ghost(S: set<int>, a: T, b: T): T
- {
- if (forall x :: x*x in S ==> 0 <= x && x < 100) then a else b
- }
- // And if statements
- method N(s: seq<int>) returns (ghost g: int, h: int)
- {
- if ( (forall x :: x in s ==> 0 <= x) ) {
- h := 0; g := 0;
- }
- if ( (forall x :: x*x in s ==> x < 100) ) { // this is fine, since the whole statement is a ghost statement
- g := 2;
- }
- if ( (forall x :: x*x in s ==> x < 50) ) {
- h := 6; // error: cannot compile this guard of a non-ghost if statement
- }
- }
-}
-
-// The following functions test what was once a soundness problem
-module DependencyOnAllAllocatedObjects {
- function AllObjects0(): bool
- {
- forall c: SomeClass :: c != null ==> c.f == 0 // error: not allowed to dependend on which objects are allocated
- }
- function AllObjects1(): bool
- {
- forall c: SomeClass :: true // error: not allowed to dependend on which objects are allocated
- }
- function AllObjects10(): bool
- reads *;
- {
- forall c: SomeClass :: c != null ==> c.f == 0 // error: not allowed to dependend on which objects are allocated
- }
- function AllObjects11(): bool
- reads *;
- {
- forall c: SomeClass :: true // error: not allowed to dependend on which objects are allocated
- }
- function method AllObjects20(): bool
- {
- forall c: SomeClass :: c != null ==> c.f == 0 // error: not allowed to dependend on which objects are allocated
- }
- function method AllObjects21(): bool
- {
- forall c: SomeClass :: true // error: not allowed to dependend on which objects are allocated
- }
- function method AllObjects30(): bool
- reads *;
- {
- forall c: SomeClass :: c != null ==> c.f == 0 // error: not allowed to dependend on which objects are allocated
- }
- function method AllObjects31(): bool
- reads *;
- {
- forall c: SomeClass :: true // error: not allowed to dependend on which objects are allocated
- }
-
- method M()
- {
- var b := forall c: SomeClass :: c != null ==> c.f == 0; // error: non-ghost code requires bounds
- ghost var g := forall c: SomeClass :: c != null ==> c.f == 0; // cool (this is in a ghost context
- // outside a function)
- }
-
- class SomeClass {
- var f: int;
- }
-}
diff --git a/Test/dafny0/Parallel.dfy b/Test/dafny0/Parallel.dfy
deleted file mode 100644
index ac11c1eb..00000000
--- a/Test/dafny0/Parallel.dfy
+++ /dev/null
@@ -1,308 +0,0 @@
-class C {
- var data: int;
- var n: nat;
- var st: set<object>;
-
- ghost method CLemma(k: int)
- requires k != -23;
- ensures data < k; // magic, isn't it (or bogus, some would say)
-}
-
-// This method more or less just tests the syntax, resolution, and basic verification
-method ParallelStatement_Resolve(
- a: array<int>,
- spine: set<C>,
- Repr: set<object>,
- S: set<int>,
- clx: C, cly: C, clk: int
- )
- requires a != null && null !in spine;
- modifies a, spine;
-{
- parallel (i: int | 0 <= i < a.Length && i % 2 == 0) {
- a[i] := a[(i + 1) % a.Length] + 3;
- }
-
- parallel (o | o in spine) {
- o.st := o.st + Repr;
- }
-
- parallel (x, y | x in S && 0 <= y+x < 100) {
- Lemma(clx, x, y); // error: precondition does not hold (clx may be null)
- }
-
- parallel (x, y | x in S && 0 <= y+x < 100) {
- cly.CLemma(x + y); // error: receiver might be null
- }
-
- parallel (p | 0 <= p)
- ensures F(p) <= Sum(p) + p - 1; // error (no connection is known between F and Sum)
- {
- assert 0 <= G(p);
- ghost var t;
- if (p % 2 == 0) {
- assert G(p) == F(p+2); // error (there's nothing that gives any relation between F and G)
- t := p+p;
- } else {
- assume H(p, 20) < 100; // don't know how to justify this
- t := p;
- }
- PowerLemma(p, t);
- t := t + 1;
- PowerLemma(p, t);
- }
-}
-
-ghost method Lemma(c: C, x: int, y: int)
- requires c != null;
- ensures c.data <= x+y;
-ghost method PowerLemma(x: int, y: int)
- ensures Pred(x, y);
-
-function F(x: int): int
-function G(x: int): nat
-function H(x: int, y: int): int
-function Sum(x: int): int
-function Pred(x: int, y: int): bool
-
-// ---------------------------------------------------------------------
-
-method M0(S: set<C>)
- requires null !in S;
- modifies S;
- ensures forall o :: o in S ==> o.data == 85;
- ensures forall o :: o != null && o !in S ==> o.data == old(o.data);
-{
- parallel (s | s in S) {
- s.data := 85;
- }
-}
-
-method M1(S: set<C>, x: C)
- requires null !in S && x in S;
-{
- parallel (s | s in S)
- ensures s.data < 100;
- {
- assume s.data == 85;
- }
- if (*) {
- assert x.data == 85; // error (cannot be inferred from parallel ensures clause)
- } else {
- assert x.data < 120;
- }
-
- parallel (s | s in S)
- ensures s.data < 70; // error
- {
- assume s.data == 85;
- }
-}
-
-method M2() returns (a: array<int>)
- ensures a != null;
- ensures forall i,j :: 0 <= i < a.Length/2 <= j < a.Length ==> a[i] < a[j];
-{
- a := new int[250];
- parallel (i: nat | i < 125) {
- a[i] := 423;
- }
- parallel (i | 125 <= i < 250) {
- a[i] := 300 + i;
- }
-}
-
-method M4(S: set<C>, k: int)
- modifies S;
-{
- parallel (s | s in S && s != null) {
- s.n := k; // error: k might be negative
- }
-}
-
-method M5()
-{
- if {
- case true =>
- parallel (x | 0 <= x < 100) {
- PowerLemma(x, x);
- }
- assert Pred(34, 34);
-
- case true =>
- parallel (x,y | 0 <= x < 100 && y == x+1) {
- PowerLemma(x, y);
- }
- assert Pred(34, 35);
-
- case true =>
- parallel (x,y | 0 <= x < y < 100) {
- PowerLemma(x, y);
- }
- assert Pred(34, 35);
-
- case true =>
- parallel (x | x in set k | 0 <= k < 100) {
- PowerLemma(x, x);
- }
- assert Pred(34, 34);
- }
-}
-
-method Main()
-{
- var a := new int[180];
- parallel (i | 0 <= i < 180) {
- a[i] := 2*i + 100;
- }
- var sq := [0, 0, 0, 2, 2, 2, 5, 5, 5];
- parallel (i | 0 <= i < |sq|) {
- a[20+i] := sq[i];
- }
- parallel (t | t in sq) {
- a[t] := 1000;
- }
- parallel (t,u | t in sq && t < 4 && 10 <= u < 10+t) {
- a[u] := 6000 + t;
- }
- var k := 0;
- while (k < 180) {
- if (k != 0) { print ", "; }
- print a[k];
- k := k + 1;
- }
- print "\n";
-}
-
-method DuplicateUpdate() {
- var a := new int[180];
- var sq := [0, 0, 0, 2, 2, 2, 5, 5, 5];
- if (*) {
- parallel (t,u | t in sq && 10 <= u < 10+t) {
- a[u] := 6000 + t; // error: a[10] (and a[11]) are assigned more than once
- }
- } else {
- parallel (t,u | t in sq && t < 4 && 10 <= u < 10+t) {
- a[u] := 6000 + t; // with the 't < 4' conjunct in the line above, this is fine
- }
- }
-}
-
-ghost method DontDoMuch(x: int)
-{
-}
-
-method OmittedRange() {
- parallel (x) { }
- parallel (x) {
- DontDoMuch(x);
- }
-}
-
-// ----------------------- two-state postconditions ---------------------------------
-
-class TwoState_C { ghost var data: int; }
-
-ghost static method TwoState0(y: int)
- ensures exists o: TwoState_C :: o != null && fresh(o);
-{
- var p := new TwoState_C;
-}
-
-method TwoState_Main0() {
- parallel (x) { TwoState0(x); }
- assert false; // error: this location is indeed reachable (if the translation before it is sound)
-}
-
-ghost static method TwoState1(y: int)
- ensures exists c: TwoState_C :: c != null && c.data != old(c.data);
-{
- var c := new TwoState_C;
- c.data := c.data + 1;
-}
-
-method TwoState_Main1() {
- parallel (x) { TwoState1(x); }
- assert false; // error: this location is indeed reachable (if the translation before it is sound)
-}
-
-method X_Legit(c: TwoState_C)
- requires c != null;
- modifies c;
-{
- c.data := c.data + 1;
- parallel (x | c.data <= x)
- ensures old(c.data) < x; // note that the 'old' refers to the method's initial state
- {
- }
-}
-
-// At first glance, this looks like a version of TwoState_Main0 above, but with an
-// ensures clause.
-// However, there's an important difference in the translation, which is that the
-// occurrence of 'fresh' here refers to the initial state of the TwoStateMain2
-// method, not the beginning of the 'parallel' statement.
-// Still, care needs to be taken in the translation to make sure that the parallel
-// statement's effect on the heap is not optimized away.
-method TwoState_Main2()
-{
- parallel (x: int)
- ensures exists o: TwoState_C :: o != null && fresh(o);
- {
- TwoState0(x);
- }
- assert false; // error: this location is indeed reachable (if the translation before it is sound)
-}
-
-// At first glance, this looks like an inlined version of TwoState_Main0 above.
-// However, there's an important difference in the translation, which is that the
-// occurrence of 'fresh' here refers to the initial state of the TwoStateMain3
-// method, not the beginning of the 'parallel' statement.
-// Still, care needs to be taken in the translation to make sure that the parallel
-// statement's effect on the heap is not optimized away.
-method TwoState_Main3()
-{
- parallel (x: int)
- ensures exists o: TwoState_C :: o != null && fresh(o);
- {
- var p := new TwoState_C;
- }
- assert false; // error: this location is indeed reachable (if the translation before it is sound)
-}
-
-// ------- empty parallel statement -----------------------------------------
-
-var emptyPar: int;
-
-method Empty_Parallel0()
- modifies this;
- ensures emptyPar == 8;
-{
- parallel () {
- this.emptyPar := 8;
- }
-}
-
-function EmptyPar_P(x: int): bool
-ghost method EmptyPar_Lemma(x: int)
- ensures EmptyPar_P(x);
-
-method Empty_Parallel1()
- ensures EmptyPar_P(8);
-{
- parallel () {
- EmptyPar_Lemma(8);
- }
-}
-
-method Empty_Parallel2()
-{
- parallel ()
- ensures exists k :: EmptyPar_P(k);
- {
- var y := 8;
- assume EmptyPar_P(y);
- }
- assert exists k :: EmptyPar_P(k); // yes
- assert EmptyPar_P(8); // error: the parallel statement's ensures clause does not promise this
-}
diff --git a/Test/dafny0/ParallelResolveErrors.dfy b/Test/dafny0/ParallelResolveErrors.dfy
deleted file mode 100644
index f260edb5..00000000
--- a/Test/dafny0/ParallelResolveErrors.dfy
+++ /dev/null
@@ -1,108 +0,0 @@
-class C {
- var data: int;
- ghost var gdata: int;
- ghost method Init_ModifyNothing() { }
- ghost method Init_ModifyThis() modifies this;
- {
- data := 6; // error: assignment to a non-ghost field
- gdata := 7;
- }
- ghost method Init_ModifyStuff(c: C) modifies this, c; { }
- method NonGhostMethod() { print "hello\n"; }
-}
-
-method M0(IS: set<int>)
-{
- parallel (i | 0 <= i < 20) {
- i := i + 1; // error: not allowed to assign to bound variable
- }
-
- var k := 0;
- parallel (i | 0 <= i < 20) {
- k := k + i; // error: not allowed to assign to local k, since k is not declared inside parallel block
- }
-
- parallel (i | 0 <= i < 20)
- ensures true;
- {
- var x := i;
- x := x + 1;
- }
-
- ghost var y;
- var z;
- parallel (i | 0 <= i)
- ensures true;
- {
- var x := i;
- x := x + 1;
- y := 18; // (this statement is not allowed, since y is declared outside the parallel, but that check happens only if the first resolution pass of the parallel statement passes, which it doesn't in this case because of the next line)
- z := 20; // error: assigning to a non-ghost variable inside a ghost parallel block
- }
-
- parallel (i | 0 <= i)
- ensures true;
- {
- ghost var x := i;
- x := x + 1; // cool
- }
-
- var ia := new int[20];
- parallel (i | 0 <= i < 20) {
- ia[i] := choose IS; // error: set choose not allowed
- }
-
- var ca := new C[20];
- parallel (i | 0 <= i < 20) {
- ca[i] := new C; // error: new allocation not allowed
- }
- parallel (i | 0 <= i < 20)
- ensures true;
- {
- var c := new C; // allowed
- var d := new C.Init_ModifyNothing();
- var e := new C.Init_ModifyThis();
- var f := new C.Init_ModifyStuff(e);
- c.Init_ModifyStuff(d);
- c.NonGhostMethod(); // error: only allowed to call ghost methods (because of possible 'print' statements, sigh)
- }
-}
-
-method M1() {
- parallel (i | 0 <= i < 20) {
- assert i < 100;
- if (i == 17) { break; } // error: nothing to break out of
- }
-
- parallel (i | 0 <= i < 20) ensures true; {
- if (i == 8) { return; } // error: return not allowed inside parallel block
- }
-
- var m := 0;
- label OutsideLoop:
- while (m < 20) {
- parallel (i | 0 <= i < 20) {
- if (i == 17) { break; } // error: not allowed to break out of loop that sits outside parallel
- if (i == 8) { break break; } // error: ditto (also: attempt to break too far)
- if (i == 9) { break OutsideLoop; } // error: ditto
- }
- m := m + 1;
- }
-
- parallel (i | 0 <= i < 20) {
- var j := 0;
- while (j < i) {
- if (j == 6) { break; } // fine
- if (j % 7 == 4) { break break; } // error: attempt to break out too far
- if (j % 7 == 4) { break OutsideLoop; } // error: attempt to break to place not in enclosing scope
- j := j + 1;
- }
- }
-}
-
-method M2() {
- var a := new int[100];
- parallel (x | 0 <= x < 100) {
- a[x] :| assume a[x] > 0; // error: not allowed to update heap location in a parallel statement with an assume
- }
-}
diff --git a/Test/dafny0/ParseErrors.dfy b/Test/dafny0/ParseErrors.dfy
deleted file mode 100644
index 9a3cc18b..00000000
--- a/Test/dafny0/ParseErrors.dfy
+++ /dev/null
@@ -1,78 +0,0 @@
-// ---------------------- chaining operators -----------------------------------
-
-method TestChaining0(j: int, k: int, m: int)
- requires j != k != m; // error: cannot have more than one != per chain
- requires j == k == m; // dandy
- requires j < k == m == m+1 != m+2 >= 100; // error: cannot mix < and >=
- requires j >= k == m == m-1 != m-2 < 100; // error: cannot mix >= and <
-{
-}
-
-method TestChaining1<T>(s: set<T>, t: set<T>, u: set<T>, x: T, SuperSet: set<set<T>>)
- requires s <= t <= u >= s+u; // error: cannot mix <= and >=
- ensures s <= u;
- ensures s !! t !! u; // valid, means pairwise disjoint
- ensures x in s in SuperSet; // error: 'in' is not chaining
- ensures x !in s in SuperSet; // error: 'in' is not chaining
- ensures x in s !in SuperSet; // error: 'in' is not chaining
- ensures x in s == t; // error: 'in' is not chaining
-{
-}
-
-// ---------------------- calc statements -----------------------------------
-
-method TestCalc()
-{
- calc {} // OK, empty calculations are allowed
- calc {
- 2 + 3; // OK, single-line calculations are allowed
- }
- calc {
- 2 + 3;
- calc { // OK: a calc statement is allowed as a sub-hint
- 2;
- 1 + 1;
- }
- calc {
- 3;
- 1 + 2;
- }
- { assert true; } // OK: multiple subhints are allowed between two lines
- 1 + 1 + 1 + 2;
- { assert 1 + 1 + 1 == 3; }
- { assert true; }
- 3 + 2;
- }
- calc != { // error: != is not allowed as the main operator of a calculation
- 2 + 3;
- 4;
- }
- calc { // OK, these operators are compatible
- 2 + 3;
- > 4;
- >= 2 + 2;
- }
- calc < { // OK, these operators are compatible
- 2 + 3;
- == 5;
- <= 3 + 3;
- }
- calc < { // error: cannot mix < and >= or >
- 2 + 3;
- >= 5;
- > 2 + 2;
- 6;
- }
- calc >= { // error: cannot mix >= and <= or !=
- 2 + 3;
- <= 5;
- != 2 + 2;
- 3;
- }
- calc { // error: cannot have more than one != per calc
- 2 + 3;
- != 4;
- != 1 + 2;
- 3;
- }
-}
diff --git a/Test/dafny0/PredExpr.dfy b/Test/dafny0/PredExpr.dfy
deleted file mode 100644
index 96561ebd..00000000
--- a/Test/dafny0/PredExpr.dfy
+++ /dev/null
@@ -1,79 +0,0 @@
-function SimpleAssert(n: int): int
- ensures n < 100;
-{
- assert n == 58; // error: assert violation
- n // but postcondition is fine
-}
-
-function SimpleAssume(n: int): int
- ensures n < 100;
-{
- assume n == 58; n // all is fine
-}
-
-function Subonacci(n: nat): nat
-{
- if 2 <= n then
- // proving that this case is a nat requires more information,
- // which is here supplied by an assume expression
- assume Subonacci(n-2) <= Subonacci(n-1);
- Subonacci(n-1) - Subonacci(n-2)
- else
- n
-}
-
-function F(n: int): nat
-{
- Subonacci(assume 0 <= n; n) -
- Subonacci(n)
-}
-
-function G(n: int, b: bool): nat
-{
- if b then
- Subonacci(assume 0 <= n; n) + n // the last n is also affected by the assume
- else
- Subonacci(n) // error: n may not be a nat
-}
-
-ghost method M(m: nat, n: int)
-{
- var k := F(m);
- assert k == 0;
- k := F(n);
- assert k == 0; // this is still known
-}
-
-method M0(j: int) returns (n: nat)
-{
- n := assert 0 <= j; j; // error: j may be negative
-}
-
-method M1(j: int) returns (n: nat)
-{
- n := (assume 0 <= j; j) + (assert 0 <= j; j);
- assert n == 2*j;
-}
-
-function SpecOnly(): bool { true }
-
-function method FuncMeth(): int {
- assert SpecOnly(); // this call is allowed, because the .Guard of a
- // PredicateExpr is not included in compilation
- 15
-}
-
-method M5(a: int, b: int)
-{
- var k := if a < 0 then
- assume b < 0; 5
- else
- 5;
- if (*) {
- assert a == -7 ==> b < 0;
- assert b < 0; // error: this condition does not hold on every path here
- } else {
- assert assume a == -7; b < 0; // note, this is different than the ==> above
- assert b < 0; // this condition does hold on all paths to here
- }
-}
diff --git a/Test/dafny0/Predicates.dfy b/Test/dafny0/Predicates.dfy
deleted file mode 100644
index 19375ac2..00000000
--- a/Test/dafny0/Predicates.dfy
+++ /dev/null
@@ -1,182 +0,0 @@
-module A {
- class C {
- var x: int;
- predicate P()
- reads this;
- {
- x < 100
- }
- method M()
- modifies this;
- ensures P();
- {
- x := 28;
- }
- method N()
- modifies this;
- ensures P();
- {
- x := -28;
- }
- }
-}
-
-module B refines A {
- class C {
- predicate P()
- {
- 0 <= x
- }
- }
-}
-
-// ------------------------------------------------
-
-module Loose {
- class MyNumber {
- var N: int;
- ghost var Repr: set<object>;
- predicate Valid
- reads this, Repr;
- {
- this in Repr && null !in Repr &&
- 0 <= N
- }
- constructor Init()
- modifies this;
- ensures Valid && fresh(Repr - {this});
- {
- N, Repr := 0, {this};
- }
- method Inc()
- requires Valid;
- modifies Repr;
- ensures old(N) < N;
- ensures Valid && fresh(Repr - old(Repr));
- {
- N := N + 2;
- }
- method Get() returns (n: int)
- requires Valid;
- ensures n == N;
- {
- n := N;
- }
- }
-}
-
-module Tight refines Loose {
- class MyNumber {
- predicate Valid
- {
- N % 2 == 0
- }
- constructor Init()
- ensures N == 0;
- method Inc()
- ensures N == old(N) + 2;
- }
-}
-
-module UnawareClient {
- import L = Loose;
- method Main0() {
- var n := new L.MyNumber.Init();
- assert n.N == 0; // error: this is not known
- n.Inc();
- n.Inc();
- var k := n.Get();
- assert k == 4; // error: this is not known
- }
-}
-
-module AwareClient {
- import T = Tight;
- method Main1() {
- var n := new T.MyNumber.Init();
- assert n.N == 0;
- n.Inc();
- n.Inc();
- var k := n.Get();
- assert k == 4;
- }
-}
-
-// -------- Tricky refinement inheritance ----------------------------------------
-
-module Tricky_Base {
- class Tree {
- var x: int;
- predicate Constrained
- reads this;
- {
- x < 10
- }
- predicate Valid
- reads this;
- {
- x < 100
- }
- method Init()
- modifies this;
- ensures Valid;
- {
- x := 20;
- }
- }
-}
-
-module Tricky_Full refines Tricky_Base {
- class Tree {
- predicate Valid
- {
- Constrained // this causes an error to be generated for the inherited Init
- }
- }
-}
-
-// -------- Quantifiers ----------------------------------------
-
-module Q0 {
- class C {
- var x: int;
- predicate P
- reads this;
- {
- true
- }
- method M()
- modifies this;
- ensures forall c: C :: c != null ==> c.P;
- {
- }
- predicate Q
- reads this;
- {
- x < 100
- }
- method N()
- modifies this;
- ensures forall c :: c == this ==> c.Q;
- {
- x := 102; // error: fails to establish postcondition (but this error should not be repeated in Q1 below)
- }
- predicate R reads this; // a body-less predicate
- }
-}
-
-module Q1 refines Q0 {
- class C {
- predicate P
- {
- x == 18
- }
- predicate R // no body yet
- }
-}
-
-module Q2 refines Q1 {
- class C {
- predicate R { x % 3 == 2 } // finally, give it a body
- }
-}
diff --git a/Test/dafny0/Refinement.dfy b/Test/dafny0/Refinement.dfy
deleted file mode 100644
index e5c06a5e..00000000
--- a/Test/dafny0/Refinement.dfy
+++ /dev/null
@@ -1,193 +0,0 @@
-module A {
- class X { }
- class T {
- method M(x: int) returns (y: int)
- requires 0 <= x;
- ensures 0 <= y;
- {
- y := 2 * x;
- }
- method Q() returns (q: int, r: int, s: int)
- ensures 0 <= q && 0 <= r && 0 <= s;
- { // error: failure to establish postcondition about q
- r, s := 100, 200;
- }
- }
-}
-
-module B refines A {
- class C { }
- datatype Dt = Ax | Bx;
- class T {
- method P() returns (p: int)
- {
- p := 18;
- }
- method M(x: int) returns (y: int)
- ensures y % 2 == 0; // add a postcondition
- method Q ...
- ensures 12 <= r;
- ensures 1200 <= s; // error: postcondition is not established by
- // inherited method body
- }
-}
-
-// ------------------------------------------------
-
-module A_AnonymousClass {
- var x: int;
- method Increment(d: int)
- modifies this;
- {
- x := x + d;
- }
-}
-
-module B_AnonymousClass refines A_AnonymousClass {
- method Increment...
- ensures x <= old(x) + d;
-}
-
-module C_AnonymousClass refines B_AnonymousClass {
- method Increment(d: int)
- ensures old(x) + d <= x;
- method Main()
- modifies this;
- {
- x := 25;
- Increment(30);
- assert x == 55;
- Increment(12);
- assert x == 66; // error: it's 67
- }
-}
-
-// ------------------------------------------------
-
-module BodyFree {
- function F(x: int): int
- ensures 0 <= F(x);
- method TestF() {
- assert F(6) == F(7); // error: no information about F so far
- }
- method M() returns (a: int, b: int)
- ensures a == b;
-}
-
-module SomeBody refines BodyFree {
- function F(x: int): int
- { if x < 0 then 2 else 3 }
- method TestFAgain() {
- assert F(6) == F(7);
- }
- method M() returns (a: int, b: int)
- {
- a := b; // good
- }
-}
-
-module FullBodied refines BodyFree {
- function F(x: int): int
- { x } // error: does not meet the inherited postcondition
- method M() returns (a: int, b: int)
- { // error: does not establish postcondition
- a := b + 1;
- }
-}
-
-// ------------------------------------------------
-
-module Abstract {
- class MyNumber {
- ghost var N: int;
- ghost var Repr: set<object>;
- predicate Valid
- reads this, Repr;
- {
- this in Repr && null !in Repr
- }
- constructor Init()
- modifies this;
- ensures N == 0;
- ensures Valid && fresh(Repr - {this});
- {
- N, Repr := 0, {this};
- }
- method Inc()
- requires Valid;
- modifies Repr;
- ensures N == old(N) + 1;
- ensures Valid && fresh(Repr - old(Repr));
- {
- N := N + 1;
- }
- method Get() returns (n: int)
- requires Valid;
- ensures n == N;
- {
- var k; assume k == N;
- n := k;
- }
- }
-}
-
-module Concrete refines Abstract {
- class MyNumber {
- var a: int;
- var b: int;
- predicate Valid
- {
- N == a - b
- }
- constructor Init()
- {
- a := b;
- }
- method Inc()
- {
- if (*) { a := a + 1; } else { b := b - 1; }
- }
- method Get() returns (n: int)
- {
- var k := a - b;
- assert ...;
- }
- }
-}
-
-module Client {
- import C = Concrete;
- class TheClient {
- method Main() {
- var n := new C.MyNumber.Init();
- n.Inc();
- n.Inc();
- var k := n.Get();
- assert k == 2;
- }
- }
-}
-
-module IncorrectConcrete refines Abstract {
- class MyNumber {
- var a: int;
- var b: int;
- predicate Valid
- {
- N == 2*a - b
- }
- constructor Init()
- { // error: postcondition violation
- a := b;
- }
- method Inc()
- { // error: postcondition violation
- if (*) { a := a + 1; } else { b := b - 1; }
- }
- method Get() returns (n: int)
- {
- var k := a - b;
- assert ...; // error: assertion violation
- }
- }
-}
diff --git a/Test/dafny0/RefinementErrors.dfy b/Test/dafny0/RefinementErrors.dfy
deleted file mode 100644
index df6f1a71..00000000
--- a/Test/dafny0/RefinementErrors.dfy
+++ /dev/null
@@ -1,58 +0,0 @@
-module A {
- class C {
- method M(y: int) returns (x: int)
- {
- x := 6;
- }
-
- var abc: bool;
- var xyz: bool;
-
- function method F<A,B,C>(x: int, y: A, z: set<C>, b: bool): B
-
- function G(): int // uninterpreted for now
- function H(): int // uninterpreted for now
-
- method BodyLess(y: bool, k: seq<set<object>>) returns (x: int)
- method FullBodied(x: int) returns (y: bool, k: seq<set<object>>)
- {
- }
- }
-}
-
-module B refines A {
- class C {
- var k: int;
- method M(y: int) returns (x: int)
- requires 0 <= y; // error: cannot add a precondition
- modifies this; // error: cannot add a modifies clause
- ensures 0 <= x; // fine
-
- predicate abc // error: cannot replace a field with a predicate
- var xyz: bool; // error: ...or even with another field
-
- function F // error: cannot replace a "function method" with a "function"
- <C,A,B> // error: different list of type parameters
- (x: int, y: A, z: seq<C>, // error: different type of parameter z
- k: bool) // error: different parameter name
- : B
-
- function G(): int
- { 12 } // allowed to add a body
-
- method BodyLess(y: bool, k: seq<set<object>>) returns (x: int)
- { // yes, can give it a body
- }
- method FullBodied(x: int) returns (y: bool, k: seq<set<object>>)
- {
- }
- }
-}
-
-module BB refines B {
- class C {
- function method G(): int // error: allowed to make a function into a function method
- function method H(): int // ...unless this is where the function body is given
- { 10 }
- }
-}
diff --git a/Test/dafny0/RefinementModificationChecking.dfy b/Test/dafny0/RefinementModificationChecking.dfy
deleted file mode 100644
index dbf39106..00000000
--- a/Test/dafny0/RefinementModificationChecking.dfy
+++ /dev/null
@@ -1,23 +0,0 @@
-
-ghost module R1 {
- var f: int;
- method m(y: set<int>) returns (r: int)
- modifies this;
- {
- var t := y;
- }
-}
-
-ghost module R2 refines R1 {
- var g: nat;
- method m ...
- {
- ...;
- var x := 3;
- t := {1}; // error: previous local
- r := 3; // error: out parameter
- f := 4; // fine: all fields, will cause re-verification
- x := 6; // fine: new local
- g := 34;// fine: new field
- }
-}
diff --git a/Test/dafny0/ResolutionErrors.dfy b/Test/dafny0/ResolutionErrors.dfy
deleted file mode 100644
index c615c5ec..00000000
--- a/Test/dafny0/ResolutionErrors.dfy
+++ /dev/null
@@ -1,385 +0,0 @@
-
-//Should not verify, as ghost loops should not be allowed to diverge.
-method GhostDivergentLoop()
-{
- var a := new int [2];
- a[0] := 1;
- a[1] := -1;
- ghost var i := 0;
- while (i < 2)
- decreases *; // error: not allowed on a ghost loop
- invariant i <= 2;
- invariant (forall j :: 0 <= j && j < i ==> a[j] > 0);
- {
- i := 0;
- }
- assert a[1] != a[1]; // ...for then this would incorrectly verify
-}
-
-method ManyIndices<T>(a: array3<T>, b: array<T>, m: int, n: int)
-{
- // the following invalid expressions were once incorrectly resolved:
- var x := a[m, n]; // error
- var y := a[m]; // error
- var z := b[m, n, m, n]; // error
-}
-
-method SB(b: array2<int>, s: int) returns (x: int, y: int)
- requires b != null;
-{
- while
- {
- case b[x,y] == s =>
- }
-}
-
-// -------- name resolution
-
-class Global {
- var X: int;
- function method F(x: int): int { x }
- static function method G(x: int): int { x }
- method M(x: int) returns (r: int)
- {
- r := x + X;
- }
- static method N(x: int) returns (r: int)
- {
- r := x + X; // error: cannot access instance field X from static method
- }
-}
-
-method TestNameResolution0() {
- var z: int;
- z := Global.X; // error: X is an instance field
- z := F(2); // error: cannot resolve F
- z := Global.F(2); // error: invocation of instance function requires an instance
- z := G(2); // error: cannot resolve G
- z := Global.G(2);
- z := M(2); // error: cannot resolve M
- z := Global.M(2); // error: call to instance method requires an instance
- z := N(1); // error: cannot resolve N
- z := Global.N(1);
-
- z := z(5); // error: using local as if it were a function
- z := Global.z; // error: class Global does not have a member z
-
- var Global: Global; // a local variable with the name 'Global'
- z := Global.X; // this means the instance field X of the object stored in the local variable 'Global'
- var gg: Global := null;
- var y := gg.G(5);
- y := gg.N(5);
-}
-
-datatype Abc = Abel | Benny | Cecilia(y: int) | David(x: int) | Eleanor;
-datatype Xyz = Alberta | Benny | Constantine(y: int) | David(x: int);
-datatype Rst = David(x: int, y: int);
-
-function Tuv(arg0: Abc, arg1: bool): int { 10 }
-var Eleanor: bool;
-
-method TestNameResolution1() {
- var a0 := Abel;
- var a1 := Alberta;
- var b0 := Benny; // error: there's more than one constructor with the name Benny; needs qualification
- var b1 := Abc.Benny;
- var b2 := Xyz.Benny;
- var Benny := 15; // introduce a local variable with the name 'Benny'
- var b3 := Benny;
- var d0 := David(20); // error: constructor name David is ambiguous
- var d1 := David; // error: constructor name David is ambiguous (never mind that the signature does
- // not match either of them)
- var d2 := David(20, 40); // error: constructor name Davis is ambiguous (never mind that the given
- // parameters match the signature of only one of those constructors)
- var d3 := Abc.David(20, 40); // error: wrong number of parameters
- var d4 := Rst.David(20, 40);
- var e := Eleanor;
- assert Tuv(e, this.Eleanor) == 10;
-}
-
-// --------------- ghost tests -------------------------------------
-
-datatype GhostDt =
- Nil(ghost extraInfo: int) |
- Cons(data: int, tail: GhostDt, ghost moreInfo: int);
-
-class GhostTests {
- method M(dt: GhostDt) returns (r: int) {
- ghost var g := 5;
- r := g; // error: RHS is ghost, LHS is not
- r := F(18, g); // error: RHS is a ghost and will not be available at run time
- r := G(20, g); // it's fine to pass a ghost as a parameter to a non-ghost, because
- // only the ghost goes away during compilation
- r := N(22, g); // ditto
- r := N(g, 22); // error: passing in 'g' as non-ghost parameter
- r := P(24, 22); // error: 'P' is ghost, but its result is assigned to a non-ghost
-
- match (dt) {
- case Nil(gg) =>
- case Cons(dd, tt, gg) =>
- r := G(dd, dd); // fine
- r := G(dd, gg); // fine
- r := G(gg, gg); // error: cannot pass ghost 'gg' as non-ghost parameter to 'G'
- }
- var dd;
- dd := GhostDt.Nil(g); // fine
- dd := GhostDt.Cons(g, dt, 2); // error: cannot pass 'g' as non-ghost parameter
- ghost var dtg := GhostDt.Cons(g, dt, 2); // fine, since result is ghost
- }
- function F(x: int, y: int): int {
- y
- }
- function method G(x: int, ghost y: int): int {
- y // error: cannot return a ghost from a non-ghost function
- }
- function method H(dt: GhostDt): int {
- match dt
- case Nil(gg) => gg // error: cannot return a ghost from a non-ghost function
- case Cons(dd, tt, gg) => dd + gg // error: ditto
- }
- method N(x: int, ghost y: int) returns (r: int) {
- r := x;
- }
- ghost method P(x: int, y: int) returns (r: int) {
- ghost var g := 5;
- r := y; // allowed, since the entire method is ghost
- r := r + g; // fine, for the same reason
- r := N(20, 20); // error: call to non-ghost method from ghost method is not okay
- }
- ghost method NiceTry()
- ensures false;
- {
- while (true)
- decreases *; // error: not allowed in ghost context
- {
- }
- }
- ghost method BreaksAreFineHere(t: int)
- {
- var n := 0;
- ghost var k := 0;
- while (true)
- invariant n <= 112;
- decreases 112 - n;
- {
- label MyStructure: {
- if (k % 17 == 0) { break MyStructure; } // this is fine, because it's a ghost method
- k := k + 1;
- }
- label MyOtherStructure:
- if (k % 17 == 0) {
- break MyOtherStructure;
- } else {
- k := k + 1;
- }
-
- if (n == 112) {
- break;
- } else if (n == t) {
- return;
- }
- n := n + 1;
- }
- }
- method BreakMayNotBeFineHere(ghost t: int)
- {
- var n := 0;
- ghost var k := 0;
- var p := 0;
- while (true)
- invariant n <= 112;
- decreases 112 - n;
- {
- label MyStructure: {
- if (k % 17 == 0) { break MyStructure; } // error: break from ghost to non-ghost point
- k := k + 1;
- }
- label MyOtherStructure:
- if (k % 17 == 0) {
- break MyOtherStructure; // this break is fine
- } else {
- k := k + 1;
- }
-
- var dontKnow;
- if (n == 112) {
- ghost var m := 0;
- label LoopLabel0:
- label LoopLabel1:
- while (m < 200) {
- if (m % 103 == 0) {
- if {
- case true => break; // fine, since this breaks out of the enclosing ghost loop
- case true => break LoopLabel0; // fine
- case true => break LoopLabel1; // fine
- }
- } else if (m % 101 == 0) {
- break break; // error: break out of non-ghost loop from ghost context
- }
- m := m + 3;
- }
- break;
- } else if (dontKnow == 708) {
- var q := 0;
- while (q < 1) {
- label IfNest:
- if (p == 67) {
- break break; // fine, since this is not a ghost context
- } else if (*) {
- break break break; // error: tries to break out of more loop levels than there are
- } else if (*) {
- break break; // fine, since this is not a ghost context
- } else if (k == 67) {
- break break; // error, because this is a ghost context
- }
- q := q + 1;
- }
- } else if (n == t) {
- return; // error: this is a ghost context trying to return from a non-ghost method
- }
- n := n + 1;
- p := p + 1;
- }
- }
-}
-
-method DuplicateLabels(n: int) {
- var x;
- if (n < 7) {
- label DuplicateLabel: x := x + 1;
- } else {
- label DuplicateLabel: x := x + 1;
- }
- label DuplicateLabel: x := x + 1;
- label DuplicateLabel: {
- label AnotherLabel:
- label DuplicateLabel: // error: duplicate label
- label OneMoreTime:
- x := x + 1;
- }
- label DuplicateLabel:
- label DuplicateLabel: // error: duplicate label
- x := x + 1;
- label DuplicateLabel: x := x + 1;
-}
-
-// --------------- constructors -------------------------------------
-
-class ClassWithConstructor {
- var y: int;
- method NotTheOne() { }
- constructor InitA() { }
- constructor InitB() modifies this; { y := 20; }
-}
-
-class ClassWithoutConstructor {
- method Init() modifies this; { }
-}
-
-method ConstructorTests()
-{
- var o := new object; // fine: does not have any constructors
-
- o := new ClassWithoutConstructor; // fine: don't need to call anything particular method
- o := new ClassWithoutConstructor.Init(); // this is also fine
-
- var c := new ClassWithConstructor.InitA();
- c := new ClassWithConstructor; // error: must call a constructor
- c := new ClassWithConstructor.NotTheOne(); // error: must call a constructor, not an arbitrary method
- c := new ClassWithConstructor.InitB();
- c.InitB(); // error: not allowed to call constructors except during allocation
-}
-
-// ------------------- datatype destructors ---------------------------------------
-
-datatype DTD_List = DTD_Nil | DTD_Cons(Car: int, Cdr: DTD_List, ghost g: int);
-
-method DatatypeDestructors(d: DTD_List) {
- if {
- case d.DTD_Nil? =>
- assert d == DTD_Nil;
- case d.DTD_Cons? =>
- var hd := d.Car;
- var tl := d.Cdr;
- assert hd == d.Cdr; // type error
- assert tl == d.Car; // type error
- assert d.DTD_Cons? == d.Car; // type error
- assert d == DTD_Cons(hd, tl, 5);
- ghost var g0 := d.g; // fine
- var g1 := d.g; // error: cannot use ghost member in non-ghost code
- }
-}
-
-// ------------------- print statements ---------------------------------------
-
-method PrintOnlyNonGhosts(a: int, ghost b: int)
-{
- print "a: ", a, "\n";
- print "b: ", b, "\n"; // error: print statement cannot take ghosts
-}
-
-// ------------------- auto-added type arguments ------------------------------
-
-class GenericClass<T> { var data: T; }
-
-method MG0(a: GenericClass, b: GenericClass)
- requires a != null && b != null;
- modifies a;
-{
- a.data := b.data; // allowed, since both a and b get the same auto type argument
-}
-
-method G_Caller()
-{
- var x := new GenericClass;
- MG0(x, x); // fine
- var y := new GenericClass;
- MG0(x, y); // also fine (and now y's type argument is constrained to be that of x's)
- var z := new GenericClass<int>;
- y.data := z.data; // this will have the effect of unifying all type args so far to be 'int'
- assert x.data == 5; // this is type correct
-
- var w := new GenericClass<bool>;
- MG0(x, w); // error: types don't match up
-}
-
-datatype GList<T> = GNil | GCons(hd: T, tl: GList);
-
-method MG1(l: GList, n: nat)
-{
- if (n != 0) {
- MG1(l, n-1);
- MG1(GCons(12, GCons(20, GNil)), n-1);
- }
- var t := GCons(100, GNil);
- t := GCons(120, l); // error: types don't match up (List<T$0> versus List<int>)
-}
-
-// ------------------- calc statements ------------------------------
-
-method TestCalc(m: int, n: int, a: bool, b: bool)
-{
- calc {
- a + b; // error: invalid line
- n + m;
- }
- calc {
- a && b;
- n + m; // error: all lines must have the same type
- }
- calc ==> {
- n + m; // error: ==> operator requires boolean lines
- n + m + 1;
- n + m + 2;
- }
- calc {
- n + m;
- n + m + 1;
- ==> n + m + 2; // error: ==> operator requires boolean lines
- }
- calc {
- n + m;
- { print n + m; } // error: non-ghost statements are not allowed in hints
- m + n;
- }
-}
diff --git a/Test/dafny0/ReturnErrors.dfy b/Test/dafny0/ReturnErrors.dfy
deleted file mode 100644
index 7f1c2948..00000000
--- a/Test/dafny0/ReturnErrors.dfy
+++ /dev/null
@@ -1,42 +0,0 @@
-
-class N
-{
- var i: int;
- method newN(n: N)
- requires n != null;
- modifies this, n;
- {
- n.i := 1;
- i := 1;
- }
- method safe(n: N)
- requires n != null;
- modifies this;
- {
- i := n.i;
- }
-}
-
-method m(v: int, n: N) returns (r: int)
- modifies n;
- ensures r == v;
-{
- r := v;
-}
-method testing1() returns (s: int)
- ensures s == 3;
-{
- var n := new N;
- return m(3, n); // ERROR: methods disallowed.
-}
-method testing2() returns (s: int, b: int)
- ensures s == 3;
-{
- var n := new N;
- return m(3, n), 2; // ERROR: methods disallowed.
-}
-
-method testing3() returns (n: N)
-{
- return new N.newN(n); // ERROR: disallowed, as newN() modifies n
-} \ No newline at end of file
diff --git a/Test/dafny0/ReturnTests.dfy b/Test/dafny0/ReturnTests.dfy
deleted file mode 100644
index ee60bc72..00000000
--- a/Test/dafny0/ReturnTests.dfy
+++ /dev/null
@@ -1,59 +0,0 @@
-
-class N
-{
- var i: int;
- method newN(n: N)
- requires n != null;
- modifies this, n;
- {
- n.i := 1;
- i := 1;
- }
- method safe(n: N)
- requires n != null;
- modifies this;
- {
- i := n.i;
- }
-}
-
-method m(v: int, n: N) returns (r: int)
- modifies n;
- ensures r == v;
-{
- r := v; // implict return still works.
-}
-
-method testing1() returns (a: int, b: set<int>)
-{
- return 1, {1, 2, 3}; // type checking
-}
-method testing2() returns (a: int, b: int)
- ensures a == 1 && b == 2;
-{
- a, b := 2, 1;
- return b, a; // test of parallel assignment.
-}
-method testing3() returns (a: int, b: int)
- ensures a == 1 && b == 2;
-{
- a, b := 2, 1; // these are wrong
- if (true)
- {
- var a, b := 3, 4;
- return 1, 2;// return updates non-shadowed, formal parameters correctly
- }
-}
-
-method testing4(nnn: N) returns (n: N)
- requires nnn != null;
-{
- return new N.safe(nnn); // only modifies 'this', which is the fresh N
-}
-
-method testing5() returns (r: int)
- ensures r == 2;
-{
- r := 2;
- return; // sanity check.
-} \ No newline at end of file
diff --git a/Test/dafny0/Simple.dfy b/Test/dafny0/Simple.dfy
deleted file mode 100644
index ac3a4792..00000000
--- a/Test/dafny0/Simple.dfy
+++ /dev/null
@@ -1,52 +0,0 @@
-// My first Dafny program
-// Rustan Leino, 27 January 2008
-
-class MyClass<T,U> {
- var x: int;
-
- method M(s: bool, lotsaObjects: set<object>) returns (t: object, u: set<int>, v: seq<MyClass<bool,U>>)
- requires s;
- modifies this, lotsaObjects;
- ensures t == t;
- ensures old(null) != this;
- {
- x := 12;
- while (x < 100)
- invariant x <= 100;
- {
- x := x + 17;
- if (x % 20 == 3) {
- x := this.x + 1;
- } else {
- this.x := x + 0;
- }
- t, u, v := M(true, lotsaObjects);
- var to: MyClass<T,U>;
- to, u, v := this.M(true, lotsaObjects);
- to, u, v := to.M(true, lotsaObjects);
- assert v[x] != null ==> null !in v[2..x][1..][5 := v[this.x]][..10];
- }
- }
-
- function F(x: int, y: int, h: WildData, k: WildData): WildData
- {
- if x < 0 then h else
- if (x == 0) then
- if if h==k then true else false then h else if y == 0 then k else h
- else k
- }
-}
-
-// some datatype stuff:
-
-datatype List<T> = Nil | Cons(T, List<T>);
-
-datatype WildData =
- Something() |
- JustAboutAnything(bool, myName: set<int>, int, WildData) |
- More(List<int>);
-
-class C {
- var w: WildData;
- var list: List<bool>;
-}
diff --git a/Test/dafny0/Skeletons.dfy b/Test/dafny0/Skeletons.dfy
deleted file mode 100644
index e9fef946..00000000
--- a/Test/dafny0/Skeletons.dfy
+++ /dev/null
@@ -1,63 +0,0 @@
-module A {
- method M(p: int) returns (y: int)
- requires p <= 30;
- {
- assume p < 100;
- var x;
- assume x == p + 20;
- x := x + 1;
- while (*)
- invariant x <= 120;
- decreases 120 - x;
- {
- if (x == 120) { break; }
- x := x + 1;
- }
- y := x;
- }
-}
-
-module B refines A {
- method M ...
- {
- assert p < 50;
- assert ...;
- var x := p + 20;
- assert ...;
- var k := x + 1;
- ...;
- while ...
- invariant k == x;
- {
- k := k + 1;
- }
- assert k == x || k == x + 1; // there are two exits from the loop
- }
-}
-
-
-module C0 refines B {
- method M ...
- ensures y == 120; // error: this holds only if the loop does not end early
- {
- }
-}
-
-module C1 refines B {
- method M ...
- ensures y <= 120;
- {
- }
-}
-
-module C2 refines B {
- method M ...
- ensures y == 120;
- {
- ...;
- while (true)
- ...
- assert k == x + 1; // only one loop exit remains
- ...;
- }
-}
diff --git a/Test/dafny0/SmallTests.dfy b/Test/dafny0/SmallTests.dfy
deleted file mode 100644
index 7b409a67..00000000
--- a/Test/dafny0/SmallTests.dfy
+++ /dev/null
@@ -1,589 +0,0 @@
-class Node {
- var next: Node;
-
- function IsList(r: set<Node>): bool
- reads r;
- {
- this in r &&
- (next != null ==> next.IsList(r - {this}))
- }
-
- method Test(n: Node, nodes: set<Node>)
- {
- assume nodes == nodes - {n};
- // the next line needs the Set extensionality axiom, the antecedent of
- // which is supplied by the previous line
- assert IsList(nodes) == IsList(nodes - {n});
- }
-
- method Create()
- modifies this;
- {
- next := null;
- var tmp: Node;
- tmp := new Node;
- assert tmp != this; // was once a bug in the Dafny checker
- }
-
- method SequenceUpdateOutOfBounds(s: seq<set<int>>, j: int) returns (t: seq<set<int>>)
- {
- t := s[j := {}]; // error: j is possibly out of bounds
- }
-
- method Sequence(s: seq<bool>, j: int, b: bool, c: bool) returns (t: seq<bool>)
- requires 10 <= |s|;
- requires 8 <= j && j < |s|;
- ensures |t| == |s|;
- ensures t[8] == s[8] || t[9] == s[9];
- ensures t[j] == b;
- {
- if (c) {
- t := s[j := b];
- } else {
- t := s[..j] + [b] + s[j+1..];
- }
- }
-
- method Max0(x: int, y: int) returns (r: int)
- ensures r == (if x < y then y else x);
- {
- if (x < y) { r := y; } else { r := x; }
- }
-
- method Max1(x: int, y: int) returns (r: int)
- ensures r == x || r == y;
- ensures x <= r && y <= r;
- {
- r := if x < y then y else x;
- }
-
- function PoorlyDefined(x: int): int
- requires if next == null then 5/x < 20 else true; // error: ill-defined then branch
- requires if next == null then true else 0 <= 5/x; // error: ill-defined then branch
- requires if next.next == null then true else true; // error: ill-defined guard
- requires 10/x != 8; // this is well-defined, because we get here only if x is non-0
- reads this;
- {
- 12
- }
-}
-
-// ------------------ modifies clause tests ------------------------
-
-class Modifies {
- var x: int;
- var next: Modifies;
-
- method A(p: Modifies)
- modifies this, p;
- {
- x := x + 1;
- while (p != null && p.x < 75)
- decreases 75 - p.x; // error: not defined (null deref) at top of each iteration (there's good reason
- { // to insist on this; for example, the decrement check could not be performed
- p.x := p.x + 1; // at the end of the loop body if p were set to null in the loop body)
- }
- }
-
- method Aprime(p: Modifies)
- modifies this, p;
- {
- x := x + 1;
- while (p != null && p.x < 75)
- decreases if p != null then 75 - p.x else 0; // given explicitly (but see Adoubleprime below)
- {
- p.x := p.x + 1;
- }
- }
-
- method Adoubleprime(p: Modifies)
- modifies this, p;
- {
- x := x + 1;
- while (p != null && p.x < 75) // here, the decreases clause is heuristically inferred (to be the
- { // same as the one in Aprime above)
- p.x := p.x + 1;
- }
- }
-
- method B(p: Modifies)
- modifies this;
- {
- A(this);
- if (p == this) {
- p.A(p);
- }
- A(p); // error: may violate modifies clause
- }
-
- method C(b: bool)
- modifies this;
- ensures !b ==> x == old(x) && next == old(next);
- {
- }
-
- method D(p: Modifies, y: int)
- requires p != null;
- {
- if (y == 3) {
- p.C(true); // error: may violate modifies clause
- } else {
- p.C(false); // error: may violation modifies clause (the check is done without regard
- // for the postcondition, which also makes sense, since there may, in
- // principle, be other fields of the object that are not constrained by the
- // postcondition)
- }
- }
-
- method E()
- modifies this;
- {
- A(null); // allowed
- }
-
- method F(s: set<Modifies>)
- modifies s;
- {
- parallel (m | m in s && m != null && 2 <= m.x) {
- m.x := m.x + 1;
- }
- if (this in s) {
- x := 2 * x;
- }
- }
-
- method G(s: set<Modifies>)
- modifies this;
- {
- var m := 3; // this is a different m
-
- parallel (m | m in s && m == this) {
- m.x := m.x + 1;
- }
- if (s <= {this}) {
- parallel (m | m in s) {
- m.x := m.x + 1;
- }
- F(s);
- }
- parallel (m | m in s) ensures true; { assert m == null || m.x < m.x + 10; }
- parallel (m | m != null && m in s) {
- m.x := m.x + 1; // error: may violate modifies clause
- }
- }
-
- method SetConstruction() {
- var s := {1};
- assert s != {};
- if (*) {
- assert s != {0,1};
- } else {
- assert s != {1,0};
- }
- }
-}
-
-// ------------------ allocated --------------------------------------------------
-
-class AllocatedTests {
- method M(r: AllocatedTests, k: Node, S: set<Node>, d: Lindgren)
- {
- var n := new Node;
- var t := S + {n};
-
- if (*) {
- assert !fresh(n); // error: n was not allocated in the initial state
- } else {
- assert fresh(n); // correct
- }
-
- var U := {k,n};
- if (*) {
- assert !fresh(U); // error: n was not allocated initially
- } else {
- assert fresh(U); // correct (note, the assertion does NOT say: everything was unallocated in the initial state)
- }
- }
-}
-
-datatype Lindgren =
- Pippi(Node) |
- Longstocking(seq<object>, Lindgren) |
- HerrNilsson;
-
-// --------------------------------------------------
-
-class InitCalls {
- var z: int;
- var p: InitCalls;
-
- method Init(y: int)
- modifies this;
- ensures z == y;
- {
- z := y;
- }
-
- method InitFromReference(q: InitCalls)
- requires q != null && 15 <= q.z;
- modifies this;
- ensures p == q;
- {
- p := q;
- }
-
- method TestDriver()
- {
- var c: InitCalls;
- c := new InitCalls.Init(15);
- var d := new InitCalls.Init(17);
- var e: InitCalls := new InitCalls.Init(18);
- var f: object := new InitCalls.Init(19);
- assert c.z + d.z + e.z == 50;
- // poor man's type cast:
- ghost var g: InitCalls;
- assert f == g ==> g.z == 19;
-
- // test that the call is done before the assignment to the LHS
- var r := c;
- r := new InitCalls.InitFromReference(r); // fine, since r.z==15
- r := new InitCalls.InitFromReference(r); // error, since r.z is unknown
- }
-}
-
-// --------------- some tests with quantifiers and ranges ----------------------
-
-method QuantifierRange0<T>(a: seq<T>, x: T, y: T, N: int)
- requires 0 <= N && N <= |a|;
- requires forall k | 0 <= k && k < N :: a[k] != x;
- requires exists k | 0 <= k && k < N :: a[k] == y;
- ensures forall k :: 0 <= k && k < N ==> a[k] != x; // same as the precondition, but using ==> instead of |
- ensures exists k :: 0 <= k && k < N && a[k] == y; // same as the precondition, but using && instead of |
-{
- assert x != y;
-}
-
-method QuantifierRange1<T>(a: seq<T>, x: T, y: T, N: int)
- requires 0 <= N && N <= |a|;
- requires forall k :: 0 <= k && k < N ==> a[k] != x;
- requires exists k :: 0 <= k && k < N && a[k] == y;
- ensures forall k | 0 <= k && k < N :: a[k] != x; // same as the precondition, but using | instead of ==>
- ensures exists k | 0 <= k && k < N :: a[k] == y; // same as the precondition, but using | instead of &&
-{
- assert x != y;
-}
-
-method QuantifierRange2<T(==)>(a: seq<T>, x: T, y: T, N: int)
- requires 0 <= N && N <= |a|;
- requires exists k | 0 <= k && k < N :: a[k] == y;
- ensures forall k | 0 <= k && k < N :: a[k] == y; // error
-{
- assert N != 0;
- if (N == 1) {
- assert forall k | a[if 0 <= k && k < N then k else 0] != y :: k < 0 || N <= k; // in this case, the precondition holds trivially
- }
- if (forall k | 0 <= k && k < N :: a[k] == x) {
- assert x == y;
- }
-}
-
-// ----------------------- tests that involve sequences of boxes --------
-
-ghost method M(zeros: seq<bool>, Z: bool)
- requires 1 <= |zeros| && Z == false;
- requires forall k :: 0 <= k && k < |zeros| ==> zeros[k] == Z;
-{
- var x := [Z];
- assert zeros[0..1] == [Z];
-}
-
-class SomeType
-{
- var x: int;
- method DoIt(stack: seq<SomeType>)
- requires null !in stack;
- modifies stack;
- {
- parallel (n | n in stack) {
- n.x := 10;
- }
- }
-}
-
-// ----------------------- tests of some theory axioms --------
-
-method TestSequences0()
-{
- var s := [0, 2, 4];
- if (*) {
- assert 4 in s;
- assert 0 in s;
- assert 1 !in s;
- } else {
- assert 2 in s;
- assert exists n :: n in s && -3 <= n && n < 2;
- }
- assert 7 in s; // error
-}
-
-// ----------------------- test attributes on methods and constructors --------
-
-method test0()
-{
- assert false; // error
-}
-
-method {:verify false} test1()
-{
- assert false;
-}
-
-function test2() : bool
-{
- !test2() // error
-}
-
-function {:verify false} test3() : bool
-{
- !test3()
-}
-
-class Test {
-
- method test0()
- {
- assert false; // error
- }
-
- method {:verify false} test1()
- {
- assert false;
- }
-
- constructor init0()
- {
- assert false; // error
- }
-
- constructor {:verify false} init1()
- {
- assert false;
- }
-
- function test2() : bool
- {
- !test2() // error
- }
-
- function {:verify false} test3() : bool
- {
- !test3()
- }
-
-}
-
-// ------ an if-then-else regression test
-
-function F(b: bool): int
- // The if-then-else in the following line was once translated incorrectly,
- // incorrectly causing the postcondition to verify
- ensures if b then F(b) == 5 else F(b) == 6;
-{
- 5
-}
-
-// ----------------------- test attributes on method specification constructs (assert, ensures, modifies, decreases, invariant) --------
-
-class AttributeTests {
- var f: int;
-
- method m0()
- {
-
- }
-
- method m1() returns (r: bool)
- {
- r := false;
- }
-
- function method m2() : bool
- {
- true
- }
-
- constructor C()
- {
-
- }
-
- method testAttributes0() returns (r: AttributeTests)
- ensures {:boolAttr true} true;
- ensures {:boolAttr false} true;
- ensures {:intAttr 0} true;
- ensures {:intAttr 1} true;
- free ensures {:boolAttr true} true;
- free ensures {:boolAttr false} true;
- free ensures {:intAttr 0} true;
- free ensures {:intAttr 1} true;
- modifies {:boolAttr true} this`f;
- modifies {:boolAttr false} this`f;
- modifies {:intAttr 0} this`f;
- modifies {:intAttr 1} this`f;
- modifies {:boolAttr true} this;
- modifies {:boolAttr false} this;
- modifies {:intAttr 0} this;
- modifies {:intAttr 1} this;
- decreases {:boolAttr true} f;
- decreases {:boolAttr false} f;
- decreases {:intAttr 0} f;
- decreases {:intAttr 1} f;
- {
- assert {:boolAttr true} true;
- assert {:boolAttr false} true;
- assert {:intAttr 0} true;
- assert {:intAttr 1} true;
-
- while (false)
- invariant {:boolAttr true} true;
- invariant {:boolAttr false} true;
- invariant {:intAttr 0} true;
- invariant {:intAttr 1} true;
- free invariant {:boolAttr true} true;
- free invariant {:boolAttr false} true;
- free invariant {:intAttr 0} true;
- free invariant {:intAttr 1} true;
- modifies {:boolAttr true} this`f;
- modifies {:boolAttr false} this`f;
- modifies {:intAttr 0} this`f;
- modifies {:intAttr 1} this`f;
- decreases {:boolAttr true} f;
- decreases {:boolAttr false} f;
- decreases {:intAttr 0} f;
- decreases {:intAttr 1} f;
- {
-
- }
-
- m0() {:boolAttr true};
- m0() {:boolAttr false};
- m0() {:intAttr 0};
- m0() {:intAttr 1};
-
- this.m0() {:boolAttr true};
- this.m0() {:boolAttr false};
- this.m0() {:intAttr 0};
- this.m0() {:intAttr 1};
-
- var b1 := m1() {:boolAttr true};
- b1 := m1() {:boolAttr false};
- b1 := m1() {:intAttr 0};
- b1 := m1() {:intAttr 1};
-
- var b2, b2' := m2() {:boolAttr true}, m2() {:boolAttr true};
- b2, b2' := m2() {:boolAttr false}, m2() {:boolAttr false};
- b2, b2' := m2() {:intAttr 0}, m2() {:boolAttr false};
- b2, b2' := m2() {:intAttr 1}, m2() {:boolAttr false};
-
- var c := new AttributeTests.C() {:boolAttr true};
- c := new AttributeTests.C() {:boolAttr false};
- c := new AttributeTests.C() {:intAttr 0};
- c := new AttributeTests.C() {:intAttr 1};
-
- if (*) {
- return new AttributeTests.C() {:boolAttr true};
- } else {
- return new AttributeTests.C() {:intAttr 0};
- }
- }
-}
-
-// ----------------------- Pretty printing of !(!expr) --------
-
-static method TestNotNot()
-{
- assert !(!true); // Shouldn't pretty print as "!!true".
-
- assert !(true == false);
-
- assert !(if true then false else false);
-
- assert !if true then false else false;
-
- assert !if !(!true) then false else false;
-
- assert true == !(!true);
-}
-
-// ----------------------- Assign-such-that statements -------
-
-method AssignSuchThat0(a: int, b: int) returns (x: int, y: int)
- ensures x == a && y == b;
-{
- if (*) {
- x, y :| a <= x < a + 1 && b + a <= y + a && y <= b;
- } else {
- var xx, yy :| a <= xx < a + 1 && b + a <= yy + a && yy <= b;
- x, y := xx, yy;
- }
-}
-
-method AssignSuchThat1(a: int, b: int) returns (x: int, y: int)
-{
- var k :| assume 0 <= k < a - b; // this acts like an 'assume 0 < a - b;'
- assert b < a;
- k :| k == old(2*k); // note, the 'old' has no effect on local variables like k
- assert k == 0;
- var S := {2, 4, 7};
- var T :| T <= S;
- assert 3 !in T;
- assert T == {}; // error: T may be larger
-}
-
-method AssignSuchThat2(i: int, j: int, ghost S: set<Node>)
- modifies S;
-{
- var n := new Node;
- var a := new int[25];
- var t;
- if (0 <= i < j < 25) {
- a[i], t, a[j], n.next, n :| assume true;
- }
- if (n != null && n.next != null) {
- assume n in S && n.next in S;
- n.next.next, n.next :| assume n != null && n.next != null && n.next.next == n.next; // error: n.next may equal n (thus aliasing n.next.next and n.next)
- } else if (0 <= i < 25 && 0 <= j < 25) {
- t, a[i], a[j] :| assume t < a[i] < a[j]; // error: i may equal j (thus aliasing a[i] and a[j])
- }
-}
-
-method AssignSuchThat3()
-{
- var n := new Node;
- n, n.next :| assume n.next == n; // error: RHS is not well defined (RHS is evaluated after the havocking of the LHS)
-}
-
-method AssignSuchThat4()
-{
- var n := new Node;
- n, n.next :| assume n != null && n.next == n; // that's the ticket
-}
-
-method AssignSuchThat5()
-{
- var n := new Node;
- n :| fresh(n); // fine
- assert false; // error
-}
-
-method AssignSuchThat6()
-{
- var n: Node;
- n :| assume n != null && fresh(n); // there is no non-null fresh object, so this amounts to 'assume false;'
- assert false; // no problemo
-}
-
-method AssignSuchThat7<T>(A: set<T>, x: T) {
- var B :| A <= B;
- assert x in A ==> x in B;
-}
diff --git a/Test/dafny0/SplitExpr.dfy b/Test/dafny0/SplitExpr.dfy
deleted file mode 100644
index 80b67c10..00000000
--- a/Test/dafny0/SplitExpr.dfy
+++ /dev/null
@@ -1,56 +0,0 @@
-class UnboundedStack<T> {
- var top: Node<T>;
- ghost var footprint: set<object>;
- ghost var content: seq<T>;
-
- function IsUnboundedStack(): bool
- reads {this} + footprint;
- {
- this in footprint &&
- (top == null ==> content == []) &&
- (top != null ==> top in footprint && top.footprint <= footprint &&
- top.prev == null && content == top.content && top.Valid())
- }
-
- function IsEmpty(): bool
- reads {this};
- { content == [] }
-
- method Pop() returns (result: T)
- requires IsUnboundedStack() && !IsEmpty();
- modifies footprint;
- ensures IsUnboundedStack() && content == old(content)[1..];
- {
- result := top.val;
- // The following assert does the trick, because it gets inlined and thus
- // exposes top.next.Valid() (if top.next != null):
- footprint := footprint - top.footprint; top := top.next;
- // In a previous version of the implementation of the SplitExpr transformation, the
- // following assert did not have the intended effect of being used as a lemma:
- assert top != null ==> top.Valid();
- if (top != null) {
- footprint := footprint + top.footprint; top.prev := null;
- }
- content := content[1..];
-} }
-
-class Node<T> {
- var val: T;
- var next: Node<T>;
- var prev: Node<T>;
- var footprint: set<Node<T>>;
- var content: seq<T>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in footprint && !(null in footprint) &&
- (next == null ==> content == [val]) &&
- (next != null ==> next in footprint &&
- next.footprint < footprint &&
- !(this in next.footprint) &&
- next.prev == this &&
- content == [val] + next.content &&
- next.Valid())
- }
-}
diff --git a/Test/dafny0/Superposition.dfy b/Test/dafny0/Superposition.dfy
deleted file mode 100644
index c4e74871..00000000
--- a/Test/dafny0/Superposition.dfy
+++ /dev/null
@@ -1,56 +0,0 @@
-module M0 {
- class C {
- method M(c: C, x: int, y: int) returns (r: int)
- requires 0 <= x && 0 <= y;
- ensures r < 100;
- {
- if (c == null) {
- assert c == null;
- } else if (*) {
- assert 0 <= x;
- } else {
- assert 0 <= y;
- }
- r := 8;
- }
-
- predicate P(x: int)
- ensures true; // this postcondition will not be re-checked in refinements, because it does not mention P itself (or anything else that may change in the refinement)
- ensures x < 60 ==> P(x);
- {
- true
- }
-
- predicate Q(x: int)
- ensures Q(x) ==> x < 60; // error: postcondition violation
- {
- true
- }
-
- predicate R(x: int)
- ensures R(x) ==> x < 60; // error: postcondition violation
- {
- true
- }
- }
-}
-
-module M1 refines M0 {
- class C {
- method M... // no further proof obligations for M, which is just making M0.M more deterministic
- {
- if ... {}
- else if (x == y) {}
- else {}
- }
-
- predicate P... // error: inherited postcondition 'x < 60 ==> P(x)' is violated by this strengthening of P()
- {
- false // with this strengthening of P(), the postcondition fails (still, note that only one of the postconditions is re-checked)
- }
-
- predicate Q... // we don't want another error about Q's body here (because it should not be re-checked here)
- // Ditto for R
- }
-}
-
diff --git a/Test/dafny0/TailCalls.dfy b/Test/dafny0/TailCalls.dfy
deleted file mode 100644
index 0aa46348..00000000
--- a/Test/dafny0/TailCalls.dfy
+++ /dev/null
@@ -1,74 +0,0 @@
-method {:tailrecursion} A(q: int) returns (x: int, ghost y: bool, z: nat)
-{
- if (q < 10) {
- x, y, z := 15, true, 20;
- } else {
- ghost var u;
- x, u, z := A(q-1);
- y := !u;
- }
-}
-
-method {:tailrecursion} B(q: int) returns (x: int, ghost y: bool, z: nat)
-{
- if (q < 10) {
- x, y, z := 15, true, 20;
- } else {
- ghost var u;
- x, u, z := B(q-1); // error: not a tail call, because it is followed by an increment to x
- y, x := !u, x + 1;
- }
-}
-
-method C(q: int) returns (x: int)
- decreases *;
-{
- x := C(q-1);
-}
-
-method D(q: int) returns (x: int)
- decreases *; // error: not allowed, because the method is not tail recursive
-{
- x := D(q-1);
- x := x + 1;
-}
-
-method E0(q: int) returns (x: int)
- decreases *; // error: not allowed, because the method is not tail recursive (since mutually recursive methods are currently not recognized as being tail recursive)
-{
- x := E1(q-1);
-}
-method E1(q: int) returns (x: int)
- decreases *; // error: not allowed, because the method is not tail recursive (since mutually recursive methods are currently not recognized as being tail recursive)
-{
- x := E0(q);
-}
-
-method F0(q: int) returns (x: int)
- decreases *; // fine, but no 'decreases' spec is needed at all here
-{
- x := D(q);
-}
-method F1(q: int) returns (x: int)
- decreases 5; // since this is okay (that is, you can--for no particular reason--add a 'decreases' clause to a non-recursive method), the 'decreases *' above is also allowed
-{
- x := D(q);
-}
-
-method {:tailrecursion} G0(q: int) returns (x: int)
- decreases *;
-{
- x := D(q);
-}
-method {:tailrecursion false} G1(q: int) returns (x: int)
- decreases *; // error: even though there is no recursion in this method's body, the annotation specifically says "not tail recursive", so (the easiest thing to do in the Resolver was to) generate an error
-{
- x := D(q);
-}
-
-method H0(q: int) returns (x: int)
- decreases *; // fine, but no 'decreases' spec is needed at all here
-method {:tailrecursion} H1(q: int) returns (x: int)
- decreases *; // fine, but no 'decreases' spec is needed at all here
-method H2(q: int) returns (x: int)
- decreases 5; // fine, but no 'decreases' spec is needed at all here
diff --git a/Test/dafny0/Termination.dfy b/Test/dafny0/Termination.dfy
deleted file mode 100644
index bf3702ae..00000000
--- a/Test/dafny0/Termination.dfy
+++ /dev/null
@@ -1,331 +0,0 @@
-class Termination {
- method A(N: int)
- requires 0 <= N;
- {
- var i := 0;
- while (i < N)
- invariant i <= N;
- // this will be heuristically inferred: decreases N - i;
- {
- i := i + 1;
- }
- }
-
- method B(N: int)
- requires 0 <= N;
- {
- var i := N;
- while (true)
- invariant 0 <= i;
- decreases i;
- {
- i := i - 1;
- if (!(0 <= i)) {
- break;
- }
- }
- assert i == -1;
- }
-
- method Lex() {
- var x := Update();
- var y := Update();
- while (!(x == 0 && y == 0))
- invariant 0 <= x && 0 <= y;
- decreases x, y;
- {
- if (0 < y) {
- y := y - 1;
- } else {
- x := x - 1;
- y := Update();
- }
- }
- }
-
- method Update() returns (r: int)
- ensures 0 <= r;
- {
- r := 8;
- }
-
- method M() {
- var b := true;
- var i := 500;
- var r := new Termination;
- var s := {12, 200};
- var q := [5, 8, 13];
- while (true)
- decreases b, i, r;
-// invariant b ==> 0 <= i;
- decreases s, q;
- {
- if (12 in s) {
- s := s - {12};
- } else if (b) {
- b := !b;
- i := i + 1;
- } else if (20 <= i) {
- i := i - 20;
- } else if (r != null) {
- r := null;
- } else if (|q| != 0) {
- q := q[1..];
- } else {
- break;
- }
- }
- }
-
- method Q<T>(list: List<T>) {
- var l := list;
- while (l != List.Nil)
- decreases l;
- {
- var x;
- x, l := Traverse(l);
- }
- }
-
- method Traverse<T>(a: List<T>) returns (val: T, b: List<T>)
- requires a != List.Nil;
- ensures a == List.Cons(val, b);
- {
- match a {
- case Cons(v, r) => val := v; b := r;
- }
- }
-}
-
-datatype List<T> = Nil | Cons(T, List<T>);
-
-method FailureToProveTermination0(N: int)
-{
- var n := N;
- while (n < 100) { // error: may not terminate
- n := n - 1;
- }
-}
-
-method FailureToProveTermination1(x: int, y: int, N: int)
-{
- var n := N;
- while (x < y && n < 100) // error: cannot prove termination from the heuristically chosen termination metric
- {
- n := n + 1;
- }
-}
-
-method FailureToProveTermination2(x: int, y: int, N: int)
-{
- var n := N;
- while (x < y && n < 100) // error: cannot prove termination from the given (bad) termination metric
- decreases n - x;
- {
- n := n + 1;
- }
-}
-
-method FailureToProveTermination3(x: int, y: int, N: int)
-{
- var n := N;
- while (x < y && n < 100)
- decreases 100 - n;
- {
- n := n + 1;
- }
-}
-
-method FailureToProveTermination4(x: int, y: int, N: int)
-{
- var n := N;
- while (n < 100 && x < y)
- decreases 100 - n;
- {
- n := n + 1;
- }
-}
-
-method FailureToProveTermination5(b: bool, N: int)
-{
- var n := N;
- while (b && n < 100) // here, the heuristics are good enough to prove termination
- {
- n := n + 1;
- }
-}
-
-class Node {
- var next: Node;
- var footprint: set<Node>;
-
- function Valid(): bool
- reads this, footprint;
- // In a previous (and weaker) axiomatization of sets, there had been two problems
- // with trying to prove the termination of this function. First, the default
- // decreases clause (derived from the reads clause) had been done incorrectly for
- // a list of expressions. Second, the set axiomatization had not been strong enough.
- {
- this in footprint && !(null in footprint) &&
- (next != null ==> next in footprint &&
- next.footprint < footprint &&
- this !in next.footprint &&
- next.Valid())
- }
-}
-
-method DecreasesYieldsAnInvariant(z: int) {
- var x := 100;
- var y := 1;
- var z := z; // make parameter into a local variable
- while (x != y)
- // inferred: decreases |x - y|;
- invariant (0 < x && 0 < y) || (x < 0 && y < 0);
- {
- if (z == 52) {
- break;
- } else if (x < y) {
- y := y - 1;
- } else {
- x := x - 1;
- }
- x := -x;
- y := -y;
- z := z + 1;
- }
- assert x - y < 100; // follows from the fact that no loop iteration increases what's in the 'decreases' clause
-}
-
-// ----------------------- top elements --------------------------------------
-
-var count: int;
-
-// Here is the old way that this had to be specified:
-
-method OuterOld(a: int)
- modifies this;
- decreases a, true;
-{
- count := count + 1;
- InnerOld(a, count);
-}
-
-method InnerOld(a: int, b: int)
- modifies this;
- decreases a, false, b;
-{
- count := count + 1;
- if (b == 0 && 1 <= a) {
- OuterOld(a - 1);
- } else if (1 <= b) {
- InnerOld(a, b - 1);
- }
-}
-
-// Now the default specifications ("decreases a;" and "decreases a, b;") suffice:
-
-method Outer(a: int)
- modifies this;
-{
- count := count + 1;
- Inner(a, count);
-}
-
-method Inner(a: int, b: int)
- modifies this;
-{
- count := count + 1;
- if (b == 0 && 1 <= a) {
- Outer(a - 1);
- } else if (1 <= b) {
- Inner(a, b - 1);
- }
-}
-
-// -------------------------- decrease either datatype value -----------------
-
-function Zipper0<T>(a: List<T>, b: List<T>): List<T>
-{
- match a
- case Nil => b
- case Cons(x, c) => List.Cons(x, Zipper0(b, c)) // error: cannot prove termination
-}
-
-function Zipper1<T>(a: List<T>, b: List<T>, k: bool): List<T>
- decreases if k then a else b, if k then b else a;
-{
- match a
- case Nil => b
- case Cons(x, c) => List.Cons(x, Zipper1(b, c, !k))
-}
-
-function Zipper2<T>(a: List<T>, b: List<T>): List<T>
- decreases /* max(a,b) */ if a < b then b else a,
- /* min(a,b) */ if a < b then a else b;
-{
- match a
- case Nil => b
- case Cons(x, c) => List.Cons(x, Zipper2(b, c))
-}
-
-// -------------------------- test translation of while (*) -----------------
-
-method WhileStar0(n: int)
- requires 2 <= n;
-{
- var m := n;
- var k := 0;
- while (*)
- invariant 0 <= k && 0 <= m;
- decreases *;
- {
- k := k + m;
- m := m + k;
- }
- assert 0 <= k;
-}
-
-method WhileStar1()
-{
- var k := 0;
- while (*) // error: failure to prove termination
- {
- k := k + 1;
- if (k == 17) { break; }
- }
-}
-
-method WhileStar2()
-{
- var k := 0;
- while (*)
- invariant k < 17;
- decreases 17 - k;
- {
- k := k + 1;
- if (k == 17) { break; }
- }
-}
-
-// -----------------
-
-function ReachBack(n: int): bool
- requires 0 <= n;
- ensures ReachBack(n);
-{
- // Turn off induction for this test, since that's not the point of
- // the test case.
- (forall m {:induction false} :: 0 <= m && m < n ==> ReachBack(m))
-}
-
-function ReachBack_Alt(n: int): bool
- requires 0 <= n;
-{
- n == 0 || ReachBack_Alt(n-1)
-}
-
-ghost method Lemma_ReachBack()
-{
- assert (forall m :: 0 <= m ==> ReachBack_Alt(m));
-}
-
diff --git a/Test/dafny0/TypeAntecedents.dfy b/Test/dafny0/TypeAntecedents.dfy
deleted file mode 100644
index b6ef0d68..00000000
--- a/Test/dafny0/TypeAntecedents.dfy
+++ /dev/null
@@ -1,97 +0,0 @@
-// -------- This is an example of what was once logically (although not trigger-ly) unsound ---
-
-datatype Wrapper<T> = Wrap(T);
-datatype Unit = It;
-datatype Color = Yellow | Blue;
-
-function F(a: Wrapper<Unit>): bool
- ensures a == Wrapper.Wrap(Unit.It);
-{
- match a
- case Wrap(u) => G(u)
-}
-
-function G(u: Unit): bool
- ensures u == Unit.It;
-{
- match u
- case It => true
-}
-
-method BadLemma(c0: Color, c1: Color)
- ensures c0 == c1;
-{
- var w0 := Wrapper.Wrap(c0);
- var w1 := Wrapper.Wrap(c1);
-
- // Manually, add the following assertions in Boogie. (These would
- // be ill-typed in Dafny.)
- // assert _default.F($Heap, this, w#06);
- // assert _default.F($Heap, this, w#17);
-
- assert w0 == w1; // this would be bad news (it should be reported as an error)
-}
-
-method Main() {
- BadLemma(Color.Yellow, Color.Blue);
- assert false; // this shows how things can really go wrong if BadLemma verified successfully
-}
-
-// ---------------
-
-class MyClass {
- var x: int;
- // The function axiom has "DType(this) == class.MyClass" in its antecedent. Hence, it
- // is possible to prove the various asserts below only if the receiver is known by the
- // verifier to be of type MyClass.
- function H(): int { 5 }
-}
-
-datatype List = Nil | Cons(MyClass, List);
-
-method M(list: List, S: set<MyClass>) returns (ret: int)
- modifies S;
- ensures ret == 7;
-{ // error: postcondition violation (this postcondition tests that control does flow to the end)
- match (list) {
- case Nil =>
- case Cons(r,tail) =>
- if (r != null) {
- ghost var h := r.H();
- assert h == 5;
- } else {
- assert false; // error
- }
- }
- var k := N();
- assert k.H() == 5;
- ghost var l := NF();
- assert l != null ==> l.H() == 5;
-
- parallel (s | s in S) ensures true; { assert s == null || s.H() == 5; }
- parallel (s | s != null && s in S) {
- s.x := 0;
- }
-
- assert (forall t: MyClass :: t == null || t.H() == 5);
- // note, the definedness problem in the next line sits inside an unreachable branch
- assert (forall t: MyClass :: t != null ==> (if t.H() == 5 then true else 10 / 0 == 3));
-
- assert TakesADatatype(List.Nil) == 12;
- assert TakesADatatype(List.Cons(null, List.Nil)) == 12;
- assert AlsoTakesADatatype(GenData.Pair(false, true)) == 17;
-}
-
-method N() returns (k: MyClass)
- ensures k != null;
-{
- k := new MyClass;
-}
-var a: MyClass;
-function NF(): MyClass reads this; { a }
-
-function TakesADatatype(a: List): int { 12 }
-
-datatype GenData<T> = Pair(T, T);
-
-function AlsoTakesADatatype<U>(p: GenData<U>): int { 17 }
diff --git a/Test/dafny0/TypeParameters.dfy b/Test/dafny0/TypeParameters.dfy
deleted file mode 100644
index cb9b5660..00000000
--- a/Test/dafny0/TypeParameters.dfy
+++ /dev/null
@@ -1,191 +0,0 @@
-class C<U(==)> {
- method M<T>(x: T, u: U) returns (y: T)
- ensures x == y && u == u;
- {
- y := x;
- }
-
- function method F<X(==)>(x: X, u: U): bool
- {
- x == x && u == u
- }
-
- method Main(u: U)
- {
- var t := F(3,u) && F(this,u);
- var kz := M(t,u);
- var a := G();
- assert kz && (a || !a);
- }
- method G<Y>() returns (a: Y)
- {
-
- }
-}
-
-class SetTest {
- method Add<T>(s: set<T>, x: T) returns (t: set<T>)
- ensures t == s + {x};
- {
- t := s + {x};
- }
-
- method Good()
- {
- var s := {2, 5, 3};
- var t := Add(s, 7);
- assert {5,7,2,3} == t;
- }
-
- method Bad()
- {
- var s := {2, 50, 3};
- var t := Add(s, 7);
- assert {5,7,2,3} == t; // error
- }
-}
-
-class SequenceTest {
- method Add<T>(s: seq<T>, x: T) returns (t: seq<T>)
- ensures t == s + [x];
- {
- t := s + [x];
- }
-
- method Good()
- {
- var s := [2, 5, 3];
- var t := Add(s, 7);
- assert [2,5,3,7] == t;
- }
-
- method Bad()
- {
- var s := [2, 5, 3];
- var t := Add(s, 7);
- assert [2,5,7,3] == t || [2,5,3] == t; // error
- }
-}
-
-// -------------------------
-
-class CC<T> {
- var x: T;
- method M(c: CC<T>, z: T) returns (y: T)
- requires c != null;
- modifies this;
- ensures y == c.x && x == z;
- {
- x := c.x;
- x := z;
- y := c.x;
- }
-}
-
-class CClient {
- method Main() {
- var c := new CC<int>;
- var k := c.x + 3;
- if (c.x == c.x) {
- k := k + 1;
- }
- var m := c.x;
- if (m == c.x) {
- k := k + 1;
- }
- c.x := 5;
- c.x := c.x;
- var z := c.M(c, 17);
- assert z == c.x;
- }
-}
-
-// -------------------------
-
-static function IsCelebrity<Person>(c: Person, people: set<Person>): bool
- requires c == c || c in people;
-{
- false
-}
-
-method FindCelebrity3(people: set<int>, ghost c: int)
- requires IsCelebrity(c, people); // once upon a time, this caused the translator to produce bad Boogie
-{
- 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);
-{
- false
-}
-function RogerThat<G>(g: G): G
-{
- g
-}
-
-function Cool(b: bool): bool
-{
- b
-}
-
-method IsRogerCool(n: int)
- requires RogerThat(true); // once upon a time, this caused the translator to produce bad Boogie
-{
- if (*) {
- assert Cool(2 < 3 && n < n && n < n+1); // the error message here will peek into the argument of Cool
- } else if (*) {
- assert RogerThat(2 < 3 && n < n && n < n+1); // same here; cool, huh?
- }
-}
-
-method LoopyRoger(n: int)
-{
- var i := 0;
- while (i < n)
- invariant RogerThat(0 <= n ==> i <= n);
- {
- i := i + 1;
- }
- i := 0;
- while (i < n)
- invariant RogerThat(0 <= n ==> i <= n); // error: failure to maintain loop invariant
- {
- i := i + 2;
- }
-}
-
-// ----------------------
-
-class TyKn_C<T> {
- var x: T;
- function G(): T
- reads this;
- {
- x
- }
- method M() returns (t: T)
- {
-
- }
-}
-
-class TyKn_K {
- function F(): int { 176 }
-}
-
-method TyKn_Main(k0: TyKn_K) {
- var c := new TyKn_C<TyKn_K>;
- var k1: TyKn_K;
-
- assert k0 != null ==> k0.F() == 176;
- assert k1 != null ==> k1.F() == 176;
-
- assert c.x != null ==> c.x.F() == 176; // the Dafny encoding needs the canCall mechanism to verify this
- assert c.G() != null ==> c.G().F() == 176; // ditto
- var k2 := c.M();
- assert k2 != null ==> k2.F() == 176; // the canCall mechanism does the trick here, but so does the encoding
- // via k2's where clause
-}
diff --git a/Test/dafny0/TypeTests.dfy b/Test/dafny0/TypeTests.dfy
deleted file mode 100644
index 2dea7a52..00000000
--- a/Test/dafny0/TypeTests.dfy
+++ /dev/null
@@ -1,120 +0,0 @@
-class C {
- function F(c: C, d: D): bool { true }
- method M(x: int) returns (y: int, c: C)
- requires F(D.A, this); // 2 errors
- requires F(4, 5); // 2 errors
- requires F(this, D.A); // good
- { }
-
- method Caller()
- {
- var m,n := M(true); // error on in-parameter
- n,m := M(m); // 2 errors on out-parameters
- }
-}
-
-datatype D = A;
-
-datatype NeverendingList = Cons(int, NeverendingList); // error: no grounding constructor
-
-datatype MutuallyRecursiveDataType<T> =
- FromANumber(int) | // this is the base case
- Else(TheCounterpart<T>, C);
-
-datatype TheCounterpart<T> =
- TreeLike(TheCounterpart<T>, TheCounterpart<T>) |
- More(MutuallyRecursiveDataType<T>);
-
-// these 'ReverseOrder_' order tests may be called white-box unit tests
-datatype ReverseOrder_MutuallyRecursiveDataType<T> =
- FromANumber(int) | // this is the base case
- Else(ReverseOrder_TheCounterpart<T>, C);
-
-datatype ReverseOrder_TheCounterpart<T> =
- TreeLike(ReverseOrder_TheCounterpart<T>, ReverseOrder_TheCounterpart<T>) |
- More(ReverseOrder_MutuallyRecursiveDataType<T>);
-
-// ---------------------
-
-class ArrayTests {
- ghost method G(a: array<int>)
- requires a != null && 10 <= a.Length;
- modifies a;
- {
- a[7] := 13; // error: array elements are not ghost locations
- }
-}
-
-// ---------------------
-
-method DuplicateVarName(x: int) returns (y: int)
-{
- var z: int;
- var z: int; // error: redeclaration of local
- var x := x; // redeclaration of in-parameter is fine
- var x := x; // error: but a redeclaration of that local is not fine
- {
- var x := x; // an inner local variable of the same name is fine
- var x := x; // error: but a redeclaration thereof is not okay
- var y := y; // duplicating an out-parameter here is fine
- }
- var y := y; // error: redeclaration of an out-parameter is not allowed (it is
- // treated like an outermost-scoped local in this regard)
-}
-
-// ---------------------
-
-method InitCalls() {
- var c := new C.F(null, null); // error: F is not a method
- var d := new C.M(8); // error: M has out parameters
- var e := new C.Caller();
-}
-
-// ---------------------
-
-method ArrayRangeAssignments(a: array<C>, c: C)
- requires a != null && 10 <= a.Length;
-{
- a[0..5] := new C; // error: this is not allowed
- a[1..4] := *; // error: this is not allowed
- a[2..3] := c; // error: this is not allowed
- var s: seq<C> := [null,null,null,null,null];
- s[0..5] := new C; // error: this is not allowed
- s[1..4] := *; // error: this is not allowed
- s[2..3] := c; // error: this is not allowed
-}
-
-// --------------------- tests of restrictions on subranges (nat)
-
-method K() {
- var s: set<nat>; // error: not allowed to instantiate 'set' with 'nat'
- var d: MutuallyRecursiveDataType<nat>; // error: not allowed to instantiate with 'nat'
- var a := new nat[100]; // error: not allowed the type array<nat>
- var b := new nat[100,200]; // error: not allowed the type array2<nat>
-}
-
-// --------------------- more ghost tests, for assign-such-that statements
-
-method M()
-{
- ghost var b: bool;
- ghost var k: int, l: int;
- var m: int;
-
- // These three statements are allowed by the resolver, but the compiler will complain
- // if it ever gets them.
- k :| k < 10;
- k, m :| 0 <= k < m;
- m :| m < 10;
-
- // Because of the ghost guard, these 'if' statements are ghost contexts, so only
- // assignments to ghosts are allowed.
- if (b) {
- k :| k < 10; // should be allowed
- k, l :| 0 <= k < l; // ditto
- }
- if (b) {
- m :| m < 10; // error: not allowed in ghost context
- k, m :| 0 <= k < m; // error: not allowed in ghost context
- }
-}
diff --git a/Test/dafny0/runtest.bat b/Test/dafny0/runtest.bat
deleted file mode 100644
index 9118e388..00000000
--- a/Test/dafny0/runtest.bat
+++ /dev/null
@@ -1,46 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-for %%f in (Simple.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% %* /dprint:- /env:0 /noVerify %%f
-)
-
-for %%f in (TypeTests.dfy NatTypes.dfy SmallTests.dfy Definedness.dfy
- FunctionSpecifications.dfy ResolutionErrors.dfy ParseErrors.dfy
- Array.dfy MultiDimArray.dfy NonGhostQuantifiers.dfy AdvancedLHS.dfy
- ModulesCycle.dfy Modules0.dfy Modules1.dfy Modules2.dfy BadFunction.dfy
- Comprehensions.dfy Basics.dfy ControlStructures.dfy
- Termination.dfy DTypes.dfy ParallelResolveErrors.dfy Parallel.dfy
- TypeParameters.dfy Datatypes.dfy
- Coinductive.dfy Corecursion.dfy CoPredicates.dfy
- TypeAntecedents.dfy NoTypeArgs.dfy EqualityTypes.dfy SplitExpr.dfy
- LoopModifies.dfy Refinement.dfy RefinementErrors.dfy
- ReturnErrors.dfy ReturnTests.dfy ChainingDisjointTests.dfy
- CallStmtTests.dfy MultiSets.dfy PredExpr.dfy LetExpr.dfy
- Predicates.dfy Skeletons.dfy Maps.dfy LiberalEquality.dfy
- RefinementModificationChecking.dfy TailCalls.dfy
- Calculations.dfy IteratorResolution.dfy Iterators.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 /print:out.bpl.tmp /dprint:out.dfy.tmp %* %%f
-)
-
-for %%f in (Superposition.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 /print:out.bpl.tmp /dprint:out.dfy.tmp /tracePOs %* %%f
-)
-
-for %%f in (SmallTests.dfy LetExpr.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 /dprint:out.tmp.dfy %* %%f
- %DAFNY_EXE% /compile:0 %* out.tmp.dfy
-)
-
-%DAFNY_EXE% %* Compilation.dfy
diff --git a/Test/dafny1/Answer b/Test/dafny1/Answer
deleted file mode 100644
index 06cac03b..00000000
--- a/Test/dafny1/Answer
+++ /dev/null
@@ -1,124 +0,0 @@
-
--------------------- Queue.dfy --------------------
-
-Dafny program verifier finished with 22 verified, 0 errors
-
--------------------- PriorityQueue.dfy --------------------
-
-Dafny program verifier finished with 24 verified, 0 errors
-
--------------------- ExtensibleArray.dfy --------------------
-
-Dafny program verifier finished with 11 verified, 0 errors
-
--------------------- ExtensibleArrayAuto.dfy --------------------
-
-Dafny program verifier finished with 11 verified, 0 errors
-
--------------------- BinaryTree.dfy --------------------
-
-Dafny program verifier finished with 24 verified, 0 errors
-
--------------------- UnboundedStack.dfy --------------------
-
-Dafny program verifier finished with 12 verified, 0 errors
-
--------------------- SeparationLogicList.dfy --------------------
-
-Dafny program verifier finished with 16 verified, 0 errors
-
--------------------- ListCopy.dfy --------------------
-
-Dafny program verifier finished with 4 verified, 0 errors
-
--------------------- ListReverse.dfy --------------------
-
-Dafny program verifier finished with 2 verified, 0 errors
-
--------------------- ListContents.dfy --------------------
-
-Dafny program verifier finished with 9 verified, 0 errors
-
--------------------- MatrixFun.dfy --------------------
-
-Dafny program verifier finished with 8 verified, 0 errors
-
--------------------- pow2.dfy --------------------
-
-Dafny program verifier finished with 8 verified, 0 errors
-
--------------------- SchorrWaite.dfy --------------------
-
-Dafny program verifier finished with 10 verified, 0 errors
-
--------------------- SchorrWaite-stages.dfy --------------------
-
-Dafny program verifier finished with 16 verified, 0 errors
-
--------------------- Cubes.dfy --------------------
-
-Dafny program verifier finished with 2 verified, 0 errors
-
--------------------- SumOfCubes.dfy --------------------
-
-Dafny program verifier finished with 17 verified, 0 errors
-
--------------------- FindZero.dfy --------------------
-
-Dafny program verifier finished with 8 verified, 0 errors
-
--------------------- TerminationDemos.dfy --------------------
-
-Dafny program verifier finished with 14 verified, 0 errors
-
--------------------- Substitution.dfy --------------------
-
-Dafny program verifier finished with 12 verified, 0 errors
-
--------------------- TreeDatatype.dfy --------------------
-
-Dafny program verifier finished with 10 verified, 0 errors
-
--------------------- KatzManna.dfy --------------------
-
-Dafny program verifier finished with 6 verified, 0 errors
-
--------------------- Induction.dfy --------------------
-
-Dafny program verifier finished with 33 verified, 0 errors
-
--------------------- Rippling.dfy --------------------
-
-Dafny program verifier finished with 141 verified, 0 errors
-
--------------------- MoreInduction.dfy --------------------
-MoreInduction.dfy(75,1): Error BP5003: A postcondition might not hold on this return path.
-MoreInduction.dfy(74,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-MoreInduction.dfy(80,1): Error BP5003: A postcondition might not hold on this return path.
-MoreInduction.dfy(79,21): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-MoreInduction.dfy(85,1): Error BP5003: A postcondition might not hold on this return path.
-MoreInduction.dfy(84,11): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-MoreInduction.dfy(90,1): Error BP5003: A postcondition might not hold on this return path.
-MoreInduction.dfy(89,22): Related location: This is the postcondition that might not hold.
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 15 verified, 4 errors
-
--------------------- Celebrity.dfy --------------------
-
-Dafny program verifier finished with 10 verified, 0 errors
-
--------------------- BDD.dfy --------------------
-
-Dafny program verifier finished with 5 verified, 0 errors
-
--------------------- UltraFilter.dfy --------------------
-
-Dafny program verifier finished with 19 verified, 0 errors
diff --git a/Test/dafny1/BDD.dfy b/Test/dafny1/BDD.dfy
deleted file mode 100644
index 3b6e478c..00000000
--- a/Test/dafny1/BDD.dfy
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-module SimpleBDD
-{
- class BDDNode
- {
- static predicate bitfunc(f: map<seq<bool>, bool>, n: nat)
- {
- forall i:seq<bool> :: i in f <==> |i| == n
- }
- ghost var Contents: map<seq<bool>, bool>;
- ghost var Repr: set<object>;
- ghost var n: nat;
- var f: BDDNode, t: BDDNode;
- var b: bool;
- predicate valid()
- reads this, Repr;
- {
- bitfunc(Contents,n) &&
- (0 == n ==> (b <==> Contents[[]])) &&
- (0 < n ==> this in Repr && f != null && t != null && t in Repr && f in Repr && t.Repr <= Repr && f.Repr <= Repr && this !in f.Repr && this !in t.Repr && t.valid() && f.valid() &&
- t.n == f.n == n-1 &&
- (forall s | s in t.Contents :: Contents[[true] + s] <==> t.Contents[s]) &&
- (forall s | s in f.Contents :: Contents[[false] + s] <==> f.Contents[s]))
- }
- }
- class BDD
- {
- var root: BDDNode;
- predicate valid()
- reads this, Repr;
- {
- root != null && root in Repr && root.Repr <= Repr && root.valid() &&
- n == root.n && Contents == root.Contents
- }
-
- ghost var Contents: map<seq<bool>, bool>;
- var n: nat;
- ghost var Repr: set<object>;
-
- method Eval(s: seq<bool>) returns(b: bool)
- requires valid() && |s| == n;
- ensures b == Contents[s];
- {
- var node: BDDNode := root;
- var i := n;
- assert s[n-i..] == s;
- while(i > 0)
- invariant node != null && node.valid();
- invariant 0 <= i == node.n <= n;
- invariant Contents[s] == node.Contents[s[n-i..]];
- {
- assert s[n-i..] == [s[n-i]] + s[n-i+1..];
- node := if s[n-i] then node.t else node.f;
- i := i - 1;
- }
- b := node.b;
- }
- }
-} \ No newline at end of file
diff --git a/Test/dafny1/BinaryTree.dfy b/Test/dafny1/BinaryTree.dfy
deleted file mode 100644
index 88b06605..00000000
--- a/Test/dafny1/BinaryTree.dfy
+++ /dev/null
@@ -1,243 +0,0 @@
-class IntSet {
- ghost var Contents: set<int>;
- ghost var Repr: set<object>;
-
- var root: Node;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- (root == null ==> Contents == {}) &&
- (root != null ==>
- root in Repr && root.Repr <= Repr && this !in root.Repr &&
- root.Valid() &&
- Contents == root.Contents)
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- ensures Contents == {};
- {
- root := null;
- Repr := {this};
- Contents := {};
- }
-
- method Find(x: int) returns (present: bool)
- requires Valid();
- ensures present <==> x in Contents;
- {
- if (root == null) {
- present := false;
- } else {
- present := root.Find(x);
- }
- }
-
- method Insert(x: int)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents) + {x};
- {
- var t := InsertHelper(x, root);
- root := t;
- Contents := root.Contents;
- Repr := root.Repr + {this};
- }
-
- static method InsertHelper(x: int, n: Node) returns (m: Node)
- requires n == null || n.Valid();
- modifies n.Repr;
- ensures m != null && m.Valid();
- ensures n == null ==> fresh(m.Repr) && m.Contents == {x};
- ensures n != null ==> m == n && n.Contents == old(n.Contents) + {x};
- ensures n != null ==> fresh(n.Repr - old(n.Repr));
- decreases if n == null then {} else n.Repr;
- {
- if (n == null) {
- m := new Node.Init(x);
- } else if (x == n.data) {
- m := n;
- } else {
- if (x < n.data) {
- assert n.right == null || n.right.Valid();
- var t := InsertHelper(x, n.left);
- n.left := t;
- n.Repr := n.Repr + n.left.Repr;
- } else {
- assert n.left == null || n.left.Valid();
- var t := InsertHelper(x, n.right);
- n.right := t;
- n.Repr := n.Repr + n.right.Repr;
- }
- n.Contents := n.Contents + {x};
- m := n;
- }
- }
-
- method Remove(x: int)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents) - {x};
- {
- if (root != null) {
- var newRoot := root.Remove(x);
- root := newRoot;
- if (root == null) {
- Contents := {};
- Repr := {this};
- } else {
- Contents := root.Contents;
- Repr := root.Repr + {this};
- }
- }
- }
-}
-
-class Node {
- ghost var Contents: set<int>;
- ghost var Repr: set<object>;
-
- var data: int;
- var left: Node;
- var right: Node;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- null !in Repr &&
- (left != null ==>
- left in Repr &&
- left.Repr <= Repr && this !in left.Repr &&
- left.Valid() &&
- (forall y :: y in left.Contents ==> y < data)) &&
- (right != null ==>
- right in Repr &&
- right.Repr <= Repr && this !in right.Repr &&
- right.Valid() &&
- (forall y :: y in right.Contents ==> data < y)) &&
- (left == null && right == null ==>
- Contents == {data}) &&
- (left != null && right == null ==>
- Contents == left.Contents + {data}) &&
- (left == null && right != null ==>
- Contents == {data} + right.Contents) &&
- (left != null && right != null ==>
- left.Repr !! right.Repr &&
- Contents == left.Contents + {data} + right.Contents)
- }
-
- method Init(x: int)
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- ensures Contents == {x};
- {
- data := x;
- left := null;
- right := null;
- Contents := {x};
- Repr := {this};
- }
-
- method Find(x: int) returns (present: bool)
- requires Valid();
- ensures present <==> x in Contents;
- decreases Repr;
- {
- if (x == data) {
- present := true;
- } else if (left != null && x < data) {
- present := left.Find(x);
- } else if (right != null && data < x) {
- present := right.Find(x);
- } else {
- present := false;
- }
- }
-
- method Remove(x: int) returns (node: Node)
- requires Valid();
- modifies Repr;
- ensures fresh(Repr - old(Repr));
- ensures node != null ==> node.Valid();
- ensures node == null ==> old(Contents) <= {x};
- ensures node != null ==> node.Repr <= Repr && node.Contents == old(Contents) - {x};
- decreases Repr;
- {
- node := this;
- if (left != null && x < data) {
- var t := left.Remove(x);
- left := t;
- Contents := Contents - {x};
- if (left != null) { Repr := Repr + left.Repr; }
- } else if (right != null && data < x) {
- var t := right.Remove(x);
- right := t;
- Contents := Contents - {x};
- if (right != null) { Repr := Repr + right.Repr; }
- } else if (x == data) {
- if (left == null && right == null) {
- node := null;
- } else if (left == null) {
- node := right;
- } else if (right == null) {
- node := left;
- } else {
- // rotate
- var min, r := right.RemoveMin();
- data := min; right := r;
- Contents := Contents - {x};
- if (right != null) { Repr := Repr + right.Repr; }
- }
- }
- }
-
- method RemoveMin() returns (min: int, node: Node)
- requires Valid();
- modifies Repr;
- ensures fresh(Repr - old(Repr));
- ensures node != null ==> node.Valid();
- ensures node == null ==> old(Contents) == {min};
- ensures node != null ==> node.Repr <= Repr && node.Contents == old(Contents) - {min};
- ensures min in old(Contents) && (forall x :: x in old(Contents) ==> min <= x);
- decreases Repr;
- {
- if (left == null) {
- min := data;
- node := right;
- } else {
- var t;
- min, t := left.RemoveMin();
- left := t;
- node := this;
- Contents := Contents - {min};
- if (left != null) { Repr := Repr + left.Repr; }
- }
- }
-}
-
-class Main {
- method Client0(x: int)
- {
- var s := new IntSet.Init();
-
- s.Insert(12);
- s.Insert(24);
- var present := s.Find(x);
- assert present <==> x == 12 || x == 24;
- }
-
- method Client1(s: IntSet, x: int)
- requires s != null && s.Valid();
- modifies s.Repr;
- {
- s.Insert(x);
- s.Insert(24);
- assert old(s.Contents) - {x,24} == s.Contents - {x,24};
- }
-}
diff --git a/Test/dafny1/Celebrity.dfy b/Test/dafny1/Celebrity.dfy
deleted file mode 100644
index 4c761671..00000000
--- a/Test/dafny1/Celebrity.dfy
+++ /dev/null
@@ -1,90 +0,0 @@
-// Celebrity example, inspired by the Rodin tutorial
-
-static function method 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;
- var x := choose 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;
- {
- var y := choose Q - {x};
- if (Knows(x, y)) {
- Q := Q - {x}; // remove_1
- } else {
- Q := Q - {y}; assert x in Q; // remove_2
- }
- x := choose Q;
- }
- r := x;
-}
-
-method FindCelebrity2<Person>(people: set<Person>, ghost c: Person) returns (r: Person)
- requires IsCelebrity(c, people);
- ensures r == c;
-{
- var b := choose 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;
- {
- var x := choose 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);
- 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/dafny1/Cubes.dfy b/Test/dafny1/Cubes.dfy
deleted file mode 100644
index 1ada79fa..00000000
--- a/Test/dafny1/Cubes.dfy
+++ /dev/null
@@ -1,23 +0,0 @@
-method Cubes(a: array<int>)
- requires a != null;
- modifies a;
- ensures (forall i :: 0 <= i && i < a.Length ==> a[i] == i*i*i);
-{
- var n := 0;
- var c := 0;
- var k := 1;
- var m := 6;
- while (n < a.Length)
- invariant n <= a.Length;
- invariant (forall i :: 0 <= i && i < n ==> a[i] == i*i*i);
- invariant c == n*n*n;
- invariant k == 3*n*n + 3*n + 1;
- invariant m == 6*n + 6;
- {
- a[n] := c;
- c := c + k;
- k := k + m;
- m := m + 6;
- n := n + 1;
- }
-}
diff --git a/Test/dafny1/ExtensibleArray.dfy b/Test/dafny1/ExtensibleArray.dfy
deleted file mode 100644
index 405f3e15..00000000
--- a/Test/dafny1/ExtensibleArray.dfy
+++ /dev/null
@@ -1,126 +0,0 @@
-class ExtensibleArray<T> {
- ghost var Contents: seq<T>;
- ghost var Repr: set<object>;
-
- var elements: array<T>;
- var more: ExtensibleArray<array<T>>;
- var length: int;
- var M: int; // shorthand for: if more == null then 0 else 256 * |more.Contents|
-
- function Valid(): bool
- reads this, Repr;
- {
- // shape of data structure
- this in Repr &&
- elements != null && elements.Length == 256 && elements in Repr &&
- (more != null ==>
- more in Repr && more.Repr <= Repr && this !in more.Repr && elements !in more.Repr &&
- more.Valid() &&
- |more.Contents| != 0 &&
- forall j :: 0 <= j && j < |more.Contents| ==>
- more.Contents[j] != null && more.Contents[j].Length == 256 &&
- more.Contents[j] in Repr && more.Contents[j] !in more.Repr &&
- more.Contents[j] != elements &&
- forall k :: 0 <= k && k < |more.Contents| && k != j ==> more.Contents[j] != more.Contents[k]) &&
-
- // length
- M == (if more == null then 0 else 256 * |more.Contents|) &&
- 0 <= length && length <= M + 256 &&
- (more != null ==> M < length) &&
-
- // Contents
- length == |Contents| &&
- (forall i :: 0 <= i && i < M ==> Contents[i] == more.Contents[i / 256][i % 256]) &&
- (forall i :: M <= i && i < length ==> Contents[i] == elements[i - M])
- }
-
- constructor Init()
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- ensures Contents == [];
- {
- elements := new T[256];
- more := null;
- length := 0;
- M := 0;
-
- Contents := [];
- Repr := {this}; Repr := Repr + {elements};
- }
-
- method Get(i: int) returns (t: T)
- requires Valid();
- requires 0 <= i && i < |Contents|;
- ensures t == Contents[i];
- decreases Repr;
- {
- if (M <= i) {
- t := elements[i - M];
- } else {
- var arr := more.Get(i / 256);
- t := arr[i % 256];
- }
- }
-
- method Set(i: int, t: T)
- requires Valid();
- requires 0 <= i && i < |Contents|;
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents)[i := t];
- {
- if (M <= i) {
- elements[i - M] := t;
- } else {
- var arr := more.Get(i / 256);
- arr[i % 256] := t;
- }
- Contents := Contents[i := t];
- }
-
- method Append(t: T)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents) + [t];
- decreases Repr;
- {
- if (length == 0 || length % 256 != 0) {
- // there is room in "elements"
- elements[length - M] := t;
- } else {
- if (more == null) {
- more := new ExtensibleArray<array<T>>.Init();
- Repr := Repr + {more} + more.Repr;
- }
- // "elements" is full, so move it into "more" and allocate a new array
- more.Append(elements);
- Repr := Repr + more.Repr;
- M := M + 256;
- elements := new T[256];
- Repr := Repr + {elements};
- elements[0] := t;
- }
- length := length + 1;
- Contents := Contents + [t];
- }
-}
-
-method Main() {
- var a := new ExtensibleArray<int>.Init();
- var n := 0;
- while (n < 256*256+600)
- invariant a.Valid() && fresh(a.Repr);
- invariant |a.Contents| == n;
- {
- a.Append(n);
- n := n + 1;
- }
- var k := a.Get(570); print k, "\n";
- k := a.Get(0); print k, "\n";
- k := a.Get(1000); print k, "\n";
- a.Set(1000, 23);
- k := a.Get(0); print k, "\n";
- k := a.Get(1000); print k, "\n";
- k := a.Get(66000); print k, "\n";
-}
diff --git a/Test/dafny1/ExtensibleArrayAuto.dfy b/Test/dafny1/ExtensibleArrayAuto.dfy
deleted file mode 100644
index f7f97deb..00000000
--- a/Test/dafny1/ExtensibleArrayAuto.dfy
+++ /dev/null
@@ -1,113 +0,0 @@
-class {:autocontracts} ExtensibleArray<T> {
- ghost var Contents: seq<T>;
-
- var elements: array<T>;
- var more: ExtensibleArray<array<T>>;
- var length: int;
- var M: int; // shorthand for: if more == null then 0 else 256 * |more.Contents|
-
- function Valid(): bool
- {
- // shape of data structure
- elements != null && elements.Length == 256 &&
- (more != null ==>
- elements !in more.Repr &&
- more.Valid() &&
- |more.Contents| != 0 &&
- forall j :: 0 <= j && j < |more.Contents| ==>
- more.Contents[j] != null && more.Contents[j].Length == 256 &&
- more.Contents[j] in Repr && more.Contents[j] !in more.Repr &&
- more.Contents[j] != elements &&
- forall k :: 0 <= k && k < |more.Contents| && k != j ==> more.Contents[j] != more.Contents[k]) &&
-
- // length
- M == (if more == null then 0 else 256 * |more.Contents|) &&
- 0 <= length && length <= M + 256 &&
- (more != null ==> M < length) &&
-
- // Contents
- length == |Contents| &&
- (forall i :: 0 <= i && i < M ==> Contents[i] == more.Contents[i / 256][i % 256]) &&
- (forall i :: M <= i && i < length ==> Contents[i] == elements[i - M])
- }
-
- constructor Init()
- ensures Contents == [];
- {
- elements := new T[256];
- more := null;
- length := 0;
- M := 0;
-
- Contents := [];
- }
-
- method Get(i: int) returns (t: T)
- requires 0 <= i && i < |Contents|;
- ensures t == Contents[i];
- decreases Repr;
- {
- if (M <= i) {
- t := elements[i - M];
- } else {
- var arr := more.Get(i / 256);
- t := arr[i % 256];
- }
- }
-
- method Set(i: int, t: T)
- requires 0 <= i && i < |Contents|;
- ensures Contents == old(Contents)[i := t];
- {
- if (M <= i) {
- elements[i - M] := t;
- } else {
- var arr := more.Get(i / 256);
- arr[i % 256] := t;
- }
- Contents := Contents[i := t];
- }
-
- method Append(t: T)
- ensures Contents == old(Contents) + [t];
- decreases Repr;
- {
- if (length == 0 || length % 256 != 0) {
- // there is room in "elements"
- elements[length - M] := t;
- } else {
- if (more == null) {
- more := new ExtensibleArray<array<T>>.Init();
- Repr := Repr + {more} + more.Repr;
- }
- // "elements" is full, so move it into "more" and allocate a new array
- more.Append(elements);
- Repr := Repr + more.Repr;
- M := M + 256;
- elements := new T[256];
- Repr := Repr + {elements};
- elements[0] := t;
- }
- length := length + 1;
- Contents := Contents + [t];
- }
-}
-
-method Main() {
- var a := new ExtensibleArray<int>.Init();
- var n := 0;
- while (n < 256*256+600)
- invariant a.Valid() && fresh(a.Repr);
- invariant |a.Contents| == n;
- {
- a.Append(n);
- n := n + 1;
- }
- var k := a.Get(570); print k, "\n";
- k := a.Get(0); print k, "\n";
- k := a.Get(1000); print k, "\n";
- a.Set(1000, 23);
- k := a.Get(0); print k, "\n";
- k := a.Get(1000); print k, "\n";
- k := a.Get(66000); print k, "\n";
-}
diff --git a/Test/dafny1/FindZero.dfy b/Test/dafny1/FindZero.dfy
deleted file mode 100644
index c92dd065..00000000
--- a/Test/dafny1/FindZero.dfy
+++ /dev/null
@@ -1,76 +0,0 @@
-method FindZero(a: array<int>) returns (r: int)
- requires a != null && forall i :: 0 <= i < a.Length ==> 0 <= a[i];
- requires forall i :: 0 <= i && i+1 < a.Length ==> a[i]-1 <= a[i+1];
- ensures 0 <= r ==> r < a.Length && a[r] == 0;
- ensures r < 0 ==> forall i :: 0 <= i < a.Length ==> a[i] != 0;
-{
- var n := 0;
- while (n < a.Length)
- invariant forall i :: 0 <= i < n && i < a.Length ==> a[i] != 0;
- {
- if (a[n] == 0) { r := n; return; }
- Lemma(a, n, a[n]);
- n := n + a[n];
- }
- r := -1;
-}
-
-ghost method Lemma(a: array<int>, k: int, m: int)
- requires a != null && forall i :: 0 <= i < a.Length ==> 0 <= a[i];
- requires forall i :: 0 <= i && i+1 < a.Length ==> a[i]-1 <= a[i+1];
- requires 0 <= k;
- requires k < a.Length ==> m <= a[k];
- ensures forall i :: k <= i < k+m && i < a.Length ==> a[i] != 0;
- decreases m;
-{
- if (0 < m && k < a.Length) {
- assert a[k] != 0;
- Lemma(a, k+1, m-1);
- }
-}
-
-// -----------------------------------------------------------------
-
-method FindZero_GhostLoop(a: array<int>) returns (r: int)
- requires a != null && forall i :: 0 <= i < a.Length ==> 0 <= a[i];
- requires forall i :: 0 <= i && i+1 < a.Length ==> a[i]-1 <= a[i+1];
- ensures 0 <= r ==> r < a.Length && a[r] == 0;
- ensures r < 0 ==> forall i :: 0 <= i < a.Length ==> a[i] != 0;
-{
- var n := 0;
- while (n < a.Length)
- invariant forall i :: 0 <= i < n && i < a.Length ==> a[i] != 0;
- {
- if (a[n] == 0) { return n; }
- ghost var m := n;
- while (m < n + a[n])
- invariant m <= n + a[n] && m < a.Length;
- invariant n + a[n] - m <= a[m];
- invariant forall i :: 0 <= i < m && i < a.Length ==> a[i] != 0;
- {
- m := m + 1;
- if (m == a.Length) { break; }
- }
- n := n + a[n];
- }
- return -1;
-}
-
-// -----------------------------------------------------------------
-
-method FindZero_Assert(a: array<int>) returns (r: int)
- requires a != null && forall i :: 0 <= i < a.Length ==> 0 <= a[i];
- requires forall i :: 0 <= i-1 && i < a.Length ==> a[i-1]-1 <= a[i];
- ensures 0 <= r ==> r < a.Length && a[r] == 0;
- ensures r < 0 ==> forall i :: 0 <= i < a.Length ==> a[i] != 0;
-{
- var n := 0;
- while (n < a.Length)
- invariant forall i :: 0 <= i < n && i < a.Length ==> a[i] != 0;
- {
- if (a[n] == 0) { return n; }
- assert forall m {:induction} :: n <= m < n + a[n] && m < a.Length ==> n+a[n]-m <= a[m];
- n := n + a[n];
- }
- return -1;
-}
diff --git a/Test/dafny1/Induction.dfy b/Test/dafny1/Induction.dfy
deleted file mode 100644
index 3585dde6..00000000
--- a/Test/dafny1/Induction.dfy
+++ /dev/null
@@ -1,202 +0,0 @@
-class IntegerInduction {
- // This class considers different ways of proving, for any natural n:
- // (SUM i in [0, n] :: i^3) == (SUM i in [0, n] :: i)^2
-
- // In terms of Dafny functions, the theorem to be proved is:
- // SumOfCubes(n) == Gauss(n) * Gauss(n)
-
- function SumOfCubes(n: int): int
- requires 0 <= n;
- {
- if n == 0 then 0 else SumOfCubes(n-1) + n*n*n
- }
-
- function Gauss(n: int): int
- requires 0 <= n;
- {
- if n == 0 then 0 else Gauss(n-1) + n
- }
-
- // Here is one proof. It uses a lemma, which is proved separately.
-
- ghost method Theorem0(n: int)
- requires 0 <= n;
- ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
- {
- if (n != 0) {
- Theorem0(n-1);
- Lemma(n-1);
- }
- }
-
- ghost method Lemma(n: int)
- requires 0 <= n;
- ensures 2 * Gauss(n) == n*(n+1);
- {
- if (n != 0) { Lemma(n-1); }
- }
-
- // Here is another proof. It states the lemma as part of the theorem, and
- // thus proves the two together.
-
- ghost method Theorem1(n: int)
- requires 0 <= n;
- ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
- ensures 2 * Gauss(n) == n*(n+1);
- {
- if (n != 0) {
- Theorem1(n-1);
- }
- }
-
- ghost method DoItAllInOneGo()
- ensures (forall n :: 0 <= n ==>
- SumOfCubes(n) == Gauss(n) * Gauss(n) &&
- 2 * Gauss(n) == n*(n+1));
- {
- }
-
- // The following two ghost methods are the same as the previous two, but
- // here no body is given--and the proof still goes through (thanks to
- // Dafny's ghost-method induction tactic).
-
- ghost method Lemma_Auto(n: int)
- requires 0 <= n;
- ensures 2 * Gauss(n) == n*(n+1);
- {
- }
-
- ghost method Theorem1_Auto(n: int)
- requires 0 <= n;
- ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
- ensures 2 * Gauss(n) == n*(n+1);
- {
- }
-
- // Here is another proof. It makes use of Dafny's induction heuristics to
- // prove the lemma.
-
- ghost method Theorem2(n: int)
- requires 0 <= n;
- ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
- {
- if (n != 0) {
- Theorem2(n-1);
-
- assert (forall m :: 0 <= m ==> 2 * Gauss(m) == m*(m+1));
- }
- }
-
- ghost method M(n: int)
- requires 0 <= n;
- {
- assume (forall k :: 0 <= k && k < n ==> 2 * Gauss(k) == k*(k+1)); // manually assume the induction hypothesis
- assert 2 * Gauss(n) == n*(n+1);
- }
-
- // Another way to prove the lemma is to supply a postcondition on the Gauss function
-
- ghost method Theorem3(n: int)
- requires 0 <= n;
- ensures SumOfCubes(n) == GaussWithPost(n) * GaussWithPost(n);
- {
- if (n != 0) {
- Theorem3(n-1);
- }
- }
-
- function GaussWithPost(n: int): int
- requires 0 <= n;
- ensures 2 * GaussWithPost(n) == n*(n+1);
- {
- if n == 0 then 0 else GaussWithPost(n-1) + n
- }
-
- // Finally, with the postcondition of GaussWithPost, one can prove the entire theorem by induction
-
- ghost method Theorem4()
- ensures (forall n :: 0 <= n ==>
- SumOfCubes(n) == GaussWithPost(n) * GaussWithPost(n));
- {
- // look ma, no hints!
- }
-
- ghost method Theorem5(n: int)
- requires 0 <= n;
- ensures SumOfCubes(n) == GaussWithPost(n) * GaussWithPost(n);
- {
- // the postcondition is a simple consequence of these quantified versions of the theorem:
- if (*) {
- assert (forall m :: 0 <= m ==> SumOfCubes(m) == GaussWithPost(m) * GaussWithPost(m));
- } else {
- Theorem4();
- }
- }
-
- // The body of this function method gives a single quantifier, which leads to an efficient
- // way to check sortedness at run time. However, an alternative, and ostensibly more general,
- // way to express sortedness is given in the function's postcondition. The alternative
- // formulation may be easier to understand for a human and may also be more readily applicable
- // for the program verifier. Dafny will show that postcondition holds, which ensures the
- // equivalence of the two formulations.
- // The proof of the postcondition requires induction. It would have been nicer to state it
- // as one formula of the form "IsSorted(s) <==> ...", but then Dafny would never consider the
- // possibility of applying induction. Instead, the "==>" and "<==" cases are given separately.
- // Proving the "<==" case is simple; it's the "==>" case that requires induction.
- // The example uses an attribute that requests induction on just "j". However, the proof also
- // goes through by applying induction on both bound variables.
- function method IsSorted(s: seq<int>): bool
- ensures IsSorted(s) ==> (forall i,j {:induction j} :: 0 <= i && i < j && j < |s| ==> s[i] <= s[j]);
- ensures (forall i,j :: 0 <= i && i < j && j < |s| ==> s[i] <= s[j]) ==> IsSorted(s);
- {
- (forall i :: 1 <= i && i < |s| ==> s[i-1] <= s[i])
- }
-}
-
-datatype Tree<T> = Leaf(T) | Branch(Tree<T>, Tree<T>);
-
-class DatatypeInduction<T> {
- function LeafCount<T>(tree: Tree<T>): int
- {
- match tree
- case Leaf(t) => 1
- case Branch(left, right) => LeafCount(left) + LeafCount(right)
- }
-
- method Theorem0(tree: Tree<T>)
- ensures 1 <= LeafCount(tree);
- {
- assert (forall t: Tree<T> :: 1 <= LeafCount(t));
- }
-
- // see also Test/dafny0/DTypes.dfy for more variations of this example
-
- function OccurrenceCount<T>(tree: Tree<T>, x: T): int
- {
- match tree
- case Leaf(t) => if x == t then 1 else 0
- case Branch(left, right) => OccurrenceCount(left, x) + OccurrenceCount(right, x)
- }
- method RegressionTest(tree: Tree<T>)
- // the translation of the following line once crashed Dafny
- requires forall y :: 0 <= OccurrenceCount(tree, y);
- {
- }
-
-}
-
-// ----------------------- Induction and case splits -----------------
-// This is a simple example where the induction hypothesis and the
-// case splits are decoupled.
-
-datatype D = Nothing | Something(D);
-
-function FooD(n: nat, d: D): int
- ensures 10 <= FooD(n, d);
-{
- match d
- case Nothing =>
- if n == 0 then 10 else FooD(n-1, D.Something(d))
- case Something(next) =>
- if n < 100 then n + 12 else FooD(n-13, next)
-}
diff --git a/Test/dafny1/KatzManna.dfy b/Test/dafny1/KatzManna.dfy
deleted file mode 100644
index 38b2963e..00000000
--- a/Test/dafny1/KatzManna.dfy
+++ /dev/null
@@ -1,76 +0,0 @@
-method NinetyOne(x: int) returns (z: int)
- requires 0 <= x;
-// ensures z == (if x > 101 then x-10 else 91);
-{
- var y1 := x;
- var y2 := 1;
- while (true)
- invariant (y1 <= 111 && y2 >= 1) || (y1 == x && y2 == 1);
- decreases -2*y1 + 21*y2 + 2*(if x < 111 then 111 else x);
- {
- if (y1 > 100) {
- if (y2 == 1) {
- break;
- } else {
- y1 := y1 - 10;
- y2 := y2 - 1;
- }
- } else {
- y1 := y1 + 11;
- y2 := y2 + 1;
- }
- }
- z := y1 - 10;
-}
-
-method Gcd(x1: int, x2: int)
- requires 1 <= x1 && 1 <= x2;
-{
- var y1 := x1;
- var y2 := x2;
- while (y1 != y2)
- invariant 1 <= y1 && 1 <= y2;
- decreases y1 + y2;
- {
- while (y1 > y2)
- invariant 1 <= y1 && 1 <= y2;
- {
- y1 := y1 - y2;
- }
- while (y2 > y1)
- invariant 1 <= y1 && 1 <= y2;
- {
- y2 := y2 - y1;
- }
- }
-}
-
-method Determinant(X: array2<int>, M: int) returns (z: int)
- requires 1 <= M;
- requires X != null && M == X.Length0 && M == X.Length1;
- modifies X;
-{
- var y := X[1-1,1-1];
- var a := 1;
- while (a != M)
- invariant 1 <= a && a <= M;
- {
- var b := a + 1;
- while (b != M+1)
- invariant a+1 <= b && b <= M+1;
- {
- var c := M;
- while (c != a)
- invariant a <= c && c <= M;
- {
- assume X[a-1,a-1] != 0;
- X[b-1, c-1] := X[b-1,c-1] - X[b-1,a-1] / X[a-1,a-1] * X[a-1,c-1];
- c := c - 1;
- }
- b := b + 1;
- }
- a := a + 1;
- y := y * X[a-1,a-1];
- }
- z := y;
-}
diff --git a/Test/dafny1/ListContents.dfy b/Test/dafny1/ListContents.dfy
deleted file mode 100644
index a8b4861d..00000000
--- a/Test/dafny1/ListContents.dfy
+++ /dev/null
@@ -1,91 +0,0 @@
-class Node<T> {
- var list: seq<T>;
- var footprint: set<Node<T>>;
-
- var data: T;
- var next: Node<T>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in this.footprint && null !in this.footprint &&
- (next == null ==> list == [data]) &&
- (next != null ==>
- next in footprint && next.footprint <= footprint &&
- this !in next.footprint &&
- list == [data] + next.list &&
- next.Valid())
- }
-
- method Init(d: T)
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- ensures list == [d];
- {
- data := d;
- next := null;
- list := [d];
- footprint := {this};
- }
-
- method SkipHead() returns (r: Node<T>)
- requires Valid();
- ensures r == null ==> |list| == 1;
- ensures r != null ==> r.Valid() && r.footprint <= footprint;
- ensures r != null ==> r.list == list[1..];
- {
- r := next;
- }
-
- method Prepend(d: T) returns (r: Node<T>)
- requires Valid();
- ensures r != null && r.Valid() && fresh(r.footprint - old(footprint));
- ensures r.list == [d] + list;
- {
- r := new Node<T>;
- r.data := d;
- r.next := this;
- r.footprint := {r} + this.footprint;
- r.list := [r.data] + this.list;
- }
-
- method ReverseInPlace() returns (reverse: Node<T>)
- requires Valid();
- modifies footprint;
- ensures reverse != null && reverse.Valid();
- ensures fresh(reverse.footprint - old(footprint));
- ensures |reverse.list| == |old(list)|;
- ensures (forall i :: 0 <= i && i < |old(list)| ==> old(list)[i] == reverse.list[|old(list)|-1-i]);
- {
- var current := next;
- reverse := this;
- reverse.next := null;
- reverse.footprint := {reverse};
- reverse.list := [data];
-
- while (current != null)
- invariant reverse != null && reverse.Valid();
- invariant reverse.footprint <= old(footprint);
- invariant current == null ==> |old(list)| == |reverse.list|;
- invariant current != null ==>
- current.Valid() &&
- current in old(footprint) && current.footprint <= old(footprint) &&
- current.footprint !! reverse.footprint &&
- |old(list)| == |reverse.list| + |current.list|;
- invariant current != null ==> current.list == old(list)[|reverse.list|..];
- invariant
- (forall i :: 0 <= i && i < |reverse.list| ==> old(list)[i] == reverse.list[|reverse.list|-1-i]);
- decreases if current != null then |current.list| else -1;
- {
- var nx := current.next;
-
- // ..., reverse, current, nx, ...
- current.next := reverse;
- current.footprint := {current} + reverse.footprint;
- current.list := [current.data] + reverse.list;
-
- reverse := current;
- current := nx;
- }
- }
-}
diff --git a/Test/dafny1/ListCopy.dfy b/Test/dafny1/ListCopy.dfy
deleted file mode 100644
index d5febfe0..00000000
--- a/Test/dafny1/ListCopy.dfy
+++ /dev/null
@@ -1,53 +0,0 @@
-class Node {
- var nxt: Node;
-
- method Init()
- modifies this;
- ensures nxt == null;
- {
- nxt := null;
- }
-
- method Copy(root: Node) returns (result: Node)
- {
- var existingRegion: set<Node>;
- assume root == null || root in existingRegion;
- assume (forall o: Node :: o != null && o in existingRegion && o.nxt != null ==> o.nxt in existingRegion);
-
- var newRoot := null;
- var oldListPtr := root;
- var newRegion: set<Node> := {};
-
- if (oldListPtr != null) {
- newRoot := new Node.Init();
- newRegion := newRegion + {newRoot};
- var prev := newRoot;
-
- while (oldListPtr != null)
- invariant newRoot in newRegion;
- invariant (forall o: Node :: o in newRegion ==> o != null);
- invariant (forall o: Node :: o in newRegion && o.nxt != null ==> o.nxt in newRegion);
- invariant prev in newRegion;
- invariant fresh(newRegion);
- invariant newRegion !! existingRegion;
- decreases *; // omit loop termination check
- {
- var tmp := new Node.Init();
-
- newRegion := newRegion + {tmp};
- prev.nxt := tmp;
-
- prev := tmp;
- oldListPtr := oldListPtr.nxt;
- }
- }
- result := newRoot;
- assert result == null || result in newRegion;
-
- // everything in newRegion is fresh
- assert fresh(newRegion);
-
- // newRegion # exisitingRegion
- assert newRegion !! existingRegion;
- }
-}
diff --git a/Test/dafny1/ListReverse.dfy b/Test/dafny1/ListReverse.dfy
deleted file mode 100644
index ef029b88..00000000
--- a/Test/dafny1/ListReverse.dfy
+++ /dev/null
@@ -1,27 +0,0 @@
-
-class Node {
- var nxt: Node;
-
- method ReverseInPlace(x: Node, r: set<Node>) returns (reverse: Node)
- requires null !in r;
- requires x == null || x in r;
- requires (forall y :: y in r ==> y.nxt == null || y.nxt in r); // region closure
- modifies r;
- ensures reverse == null || reverse in r;
- ensures (forall y :: y in r ==> y.nxt == null || y.nxt in r); // region closure
- {
- var current := x;
- reverse := null;
- while (current != null)
- invariant current == null || current in r;
- invariant reverse == null || reverse in r;
- invariant (forall y :: y in r ==> y.nxt == null || y.nxt in r); // region closure
- decreases *; // omit loop termination check
- {
- var tmp := current.nxt;
- current.nxt := reverse;
- reverse := current;
- current := tmp;
- }
- }
-}
diff --git a/Test/dafny1/MatrixFun.dfy b/Test/dafny1/MatrixFun.dfy
deleted file mode 100644
index 8f9d87ed..00000000
--- a/Test/dafny1/MatrixFun.dfy
+++ /dev/null
@@ -1,98 +0,0 @@
-method MirrorImage<T>(m: array2<T>)
- requires m != null;
- modifies m;
- ensures (forall i,j :: 0 <= i && i < m.Length0 && 0 <= j && j < m.Length1 ==>
- m[i,j] == old(m[i, m.Length1-1-j]));
-{
- var a := 0;
- while (a < m.Length0)
- invariant a <= m.Length0;
- invariant (forall i,j :: 0 <= i && i < a && 0 <= j && j < m.Length1 ==>
- m[i,j] == old(m[i, m.Length1-1-j]));
- invariant (forall i,j :: a <= i && i < m.Length0 && 0 <= j && j < m.Length1 ==>
- m[i,j] == old(m[i,j]));
- {
- var b := 0;
- while (b < m.Length1 / 2)
- invariant b <= m.Length1 / 2;
- invariant (forall i,j :: 0 <= i && i < a && 0 <= j && j < m.Length1 ==>
- m[i,j] == old(m[i, m.Length1-1-j]));
- invariant (forall j :: 0 <= j && j < b ==>
- m[a,j] == old(m[a, m.Length1-1-j]) &&
- old(m[a,j]) == m[a, m.Length1-1-j]);
- invariant (forall j :: b <= j && j < m.Length1-b ==> m[a,j] == old(m[a,j]));
- invariant (forall i,j :: a+1 <= i && i < m.Length0 && 0 <= j && j < m.Length1 ==>
- m[i,j] == old(m[i,j]));
- {
- m[a, m.Length1-1-b], m[a, b] := m[a, b], m[a, m.Length1-1-b];
- b := b + 1;
- }
- a := a + 1;
- }
-}
-
-method Flip<T>(m: array2<T>)
- requires m != null && m.Length0 == m.Length1;
- modifies m;
- ensures (forall i,j :: 0 <= i < m.Length0 && 0 <= j < m.Length1 ==> m[i,j] == old(m[j,i]));
-{
- var N := m.Length0;
- var a := 0;
- var b := 1;
- while (a != N)
- invariant a < b <= N || (a == N && b == N+1);
- invariant (forall i,j :: 0 <= i <= j < N ==>
- (if i < a || (i == a && j < b)
- then m[i,j] == old(m[j,i]) && m[j,i] == old(m[i,j])
- else m[i,j] == old(m[i,j]) && m[j,i] == old(m[j,i])));
- decreases N-a, N-b;
- {
- if (b < N) {
- m[a,b], m[b,a] := m[b,a], m[a,b];
- b := b + 1;
- } else {
- a := a + 1; b := a + 1;
- }
- }
-}
-
-method Main()
-{
- var B := new bool[2,5];
- B[0,0] := true; B[0,1] := false; B[0,2] := false; B[0,3] := true; B[0,4] := false;
- B[1,0] := true; B[1,1] := true; B[1,2] := true; B[1,3] := true; B[1,4] := false;
- print "Before:\n";
- PrintMatrix(B);
- MirrorImage(B);
- print "Mirror image:\n";
- PrintMatrix(B);
-
- var A := new int[3,3];
- A[0,0] := 5; A[0,1] := 7; A[0,2] := 9;
- A[1,0] := 6; A[1,1] := 2; A[1,2] := 3;
- A[2,0] := 7; A[2,1] := 1; A[2,2] := 0;
- print "Before:\n";
- PrintMatrix(A);
- Flip(A);
- print "Flip:\n";
- PrintMatrix(A);
-}
-
-method PrintMatrix<T>(m: array2<T>)
- requires m != null;
-{
- var i := 0;
- while (i < m.Length0) {
- var j := 0;
- while (j < m.Length1) {
- print m[i,j];
- j := j + 1;
- if (j == m.Length1) {
- print "\n";
- } else {
- print ", ";
- }
- }
- i := i + 1;
- }
-}
diff --git a/Test/dafny1/MoreInduction.dfy b/Test/dafny1/MoreInduction.dfy
deleted file mode 100644
index 84c32fb3..00000000
--- a/Test/dafny1/MoreInduction.dfy
+++ /dev/null
@@ -1,97 +0,0 @@
-datatype List<X> = Nil | Cons(Node<X>, List<X>);
-datatype Node<X> = Element(X) | Nary(List<X>);
-
-function FlattenMain<X>(list: List<X>): List<X>
- ensures IsFlat(FlattenMain(list));
-{
- Flatten(list, Nil)
-}
-
-function Flatten<X>(list: List<X>, ext: List<X>): List<X>
- requires IsFlat(ext);
- ensures IsFlat(Flatten(list, ext));
-{
- match list
- case Nil => ext
- case Cons(n, rest) =>
- match n
- case Element(x) => Cons(n, Flatten(rest, ext))
- case Nary(nn) => Flatten(nn, Flatten(rest, ext))
-}
-
-function IsFlat<X>(list: List<X>): bool
-{
- match list
- case Nil => true
- case Cons(n, rest) =>
- match n
- case Element(x) => IsFlat(rest)
- case Nary(nn) => false
-}
-
-function ToSeq<X>(list: List<X>): seq<X>
-{
- match list
- case Nil => []
- case Cons(n, rest) =>
- match n
- case Element(x) => [x] + ToSeq(rest)
- case Nary(nn) => ToSeq(nn) + ToSeq(rest)
-}
-
-ghost method Theorem<X>(list: List<X>)
- ensures ToSeq(list) == ToSeq(FlattenMain(list));
-{
- Lemma(list, Nil);
-}
-
-ghost method Lemma<X>(list: List<X>, ext: List<X>)
- requires IsFlat(ext);
- ensures ToSeq(list) + ToSeq(ext) == ToSeq(Flatten(list, ext));
-{
- match (list) {
- case Nil =>
- case Cons(n, rest) =>
- match (n) {
- case Element(x) =>
- Lemma(rest, ext);
- case Nary(nn) =>
- Lemma(nn, Flatten(rest, ext));
- Lemma(rest, ext);
- }
- }
-}
-
-// ---------------------------------------------
-
-function NegFac(n: int): int
- decreases -n;
-{
- if -1 <= n then -1 else - NegFac(n+1) * n
-}
-
-ghost method LemmaAll()
- ensures forall n :: NegFac(n) <= -1; // error: induction heuristic does not give a useful well-founded order, and thus this fails to verify
-{
-}
-
-ghost method LemmaOne(n: int)
- ensures NegFac(n) <= -1; // error: induction heuristic does not give a useful well-founded order, and thus this fails to verify
-{
-}
-
-ghost method LemmaAll_Neg()
- ensures forall n :: NegFac(-n) <= -1; // error: fails to verify because of the minus in the trigger
-{
-}
-
-ghost method LemmaOne_Neg(n: int)
- ensures NegFac(-n) <= -1; // error: fails to verify because of the minus in the trigger
-{
-}
-
-ghost method LemmaOneWithDecreases(n: int)
- ensures NegFac(n) <= -1; // here, the programmer gives a good well-founded order, so this verifies
- decreases -n;
-{
-}
diff --git a/Test/dafny1/PriorityQueue.dfy b/Test/dafny1/PriorityQueue.dfy
deleted file mode 100644
index 0343cb07..00000000
--- a/Test/dafny1/PriorityQueue.dfy
+++ /dev/null
@@ -1,221 +0,0 @@
-class PriorityQueue {
- var N: int; // capacity
- var n: int; // current size
- ghost var Repr: set<object>; // set of objects that make up the representation of a PriorityQueue
-
- var a: array<int>; // private implementation of PriorityQueue
-
- predicate Valid
- reads this, Repr;
- {
- MostlyValid &&
- (forall j :: 2 <= j && j <= n ==> a[j/2] <= a[j])
- }
-
- predicate MostlyValid
- reads this, Repr;
- {
- this in Repr && a in Repr &&
- a != null && a.Length == N+1 &&
- 0 <= n && n <= N
- }
-
- method Init(capacity: int)
- requires 0 <= capacity;
- modifies this;
- ensures Valid && fresh(Repr - {this});
- ensures N == capacity;
- {
- N := capacity;
- a := new int[N+1];
- n := 0;
- Repr := {this};
- Repr := Repr + {a};
- }
-
- method Insert(x: int)
- requires Valid && n < N;
- modifies this, a;
- ensures Valid && fresh(Repr - old(Repr));
- ensures n == old(n) + 1 && N == old(N);
- {
- n := n + 1;
- a[n] := x;
- SiftUp(n);
- }
-
- method SiftUp(k: int)
- requires 1 <= k && k <= n;
- requires MostlyValid;
- requires (forall j :: 2 <= j && j <= n && j != k ==> a[j/2] <= a[j]);
- requires (forall j :: 1 <= j && j <= n ==> j/2 != k); // k is a leaf
- modifies a;
- ensures Valid;
- {
- var i := k;
- assert MostlyValid;
- while (1 < i)
- invariant i <= k && MostlyValid;
- invariant (forall j :: 2 <= j && j <= n && j != i ==> a[j/2] <= a[j]);
- invariant (forall j :: 1 <= j/2/2 && j/2 == i && j <= n ==> a[j/2/2] <= a[j]);
- {
- if (a[i/2] <= a[i]) {
- return;
- }
- a[i/2], a[i] := a[i], a[i/2];
- i := i / 2;
- }
- }
-
- method RemoveMin() returns (x: int)
- requires Valid && 1 <= n;
- modifies this, a;
- ensures Valid && fresh(Repr - old(Repr));
- ensures n == old(n) - 1;
- {
- x := a[1];
- a[1] := a[n];
- n := n - 1;
- SiftDown(1);
- }
-
- method SiftDown(k: int)
- requires 1 <= k;
- requires MostlyValid;
- requires (forall j :: 2 <= j && j <= n && j/2 != k ==> a[j/2] <= a[j]);
- requires (forall j :: 2 <= j && j <= n && 1 <= j/2/2 && j/2/2 != k ==> a[j/2/2] <= a[j]);
- // Alternatively, the line above can be expressed as:
- // requires (forall j :: 1 <= k/2 && j/2 == k && j <= n ==> a[j/2/2] <= a[j]);
- modifies a;
- ensures Valid;
- {
- var i := k;
- while (2*i <= n) // while i is not a leaf
- invariant 1 <= i && MostlyValid;
- invariant (forall j :: 2 <= j && j <= n && j/2 != i ==> a[j/2] <= a[j]);
- invariant (forall j :: 2 <= j && j <= n && 1 <= j/2/2 && j/2/2 != i ==> a[j/2/2] <= a[j]);
- {
- var smallestChild;
- if (2*i + 1 <= n && a[2*i + 1] < a[2*i]) {
- smallestChild := 2*i + 1;
- } else {
- smallestChild := 2*i;
- }
- if (a[i] <= a[smallestChild]) {
- return;
- }
- a[smallestChild], a[i] := a[i], a[smallestChild];
- i := smallestChild;
- assert 1 <= i/2/2 ==> a[i/2/2] <= a[i];
- }
- }
-}
-
-// ---------- Alternative specifications ----------
-
-class PriorityQueue_Alternative {
- var N: int; // capacity
- var n: int; // current size
- ghost var Repr: set<object>; // set of objects that make up the representation of a PriorityQueue
-
- var a: array<int>; // private implementation of PriorityQueue
-
- predicate Valid
- reads this, Repr;
- {
- MostlyValid &&
- (forall j :: 2 <= j && j <= n ==> a[j/2] <= a[j])
- }
-
- predicate MostlyValid
- reads this, Repr;
- {
- this in Repr && a in Repr &&
- a != null && a.Length == N+1 &&
- 0 <= n && n <= N
- }
-
- method Init(capacity: int)
- requires 0 <= capacity;
- modifies this;
- ensures Valid && fresh(Repr - {this});
- ensures N == capacity;
- {
- N := capacity;
- a := new int[N+1];
- n := 0;
- Repr := {this};
- Repr := Repr + {a};
- }
-
- method Insert(x: int)
- requires Valid && n < N;
- modifies this, a;
- ensures Valid && fresh(Repr - old(Repr));
- ensures n == old(n) + 1 && N == old(N);
- {
- n := n + 1;
- a[n] := x;
- SiftUp();
- }
-
- method SiftUp()
- requires MostlyValid;
- requires (forall j :: 2 <= j && j <= n && j != n ==> a[j/2] <= a[j]);
- modifies a;
- ensures Valid;
- {
- var i := n;
- assert MostlyValid;
- while (1 < i)
- invariant i <= n && MostlyValid;
- invariant (forall j :: 2 <= j && j <= n && j != i ==> a[j/2] <= a[j]);
- invariant (forall j :: 1 <= j/2/2 && j/2 == i && j <= n ==> a[j/2/2] <= a[j]);
- {
- if (a[i/2] <= a[i]) {
- return;
- }
- a[i/2], a[i] := a[i], a[i/2];
- i := i / 2;
- }
- }
-
- method RemoveMin() returns (x: int)
- requires Valid && 1 <= n;
- modifies this, a;
- ensures Valid && fresh(Repr - old(Repr));
- ensures n == old(n) - 1;
- {
- x := a[1];
- a[1] := a[n];
- n := n - 1;
- SiftDown();
- }
-
- method SiftDown()
- requires MostlyValid;
- requires (forall j :: 4 <= j && j <= n ==> a[j/2] <= a[j]);
- modifies a;
- ensures Valid;
- {
- var i := 1;
- while (2*i <= n) // while i is not a leaf
- invariant 1 <= i && MostlyValid;
- invariant (forall j :: 2 <= j && j <= n && j/2 != i ==> a[j/2] <= a[j]);
- invariant (forall j :: 1 <= j/2/2 && j/2 == i && j <= n ==> a[j/2/2] <= a[j]);
- {
- var smallestChild;
- if (2*i + 1 <= n && a[2*i + 1] < a[2*i]) {
- smallestChild := 2*i + 1;
- } else {
- smallestChild := 2*i;
- }
- if (a[i] <= a[smallestChild]) {
- return;
- }
- a[smallestChild], a[i] := a[i], a[smallestChild];
- i := smallestChild;
- assert 1 <= i/2/2 ==> a[i/2/2] <= a[i];
- }
- }
-}
diff --git a/Test/dafny1/Queue.dfy b/Test/dafny1/Queue.dfy
deleted file mode 100644
index 0edfab81..00000000
--- a/Test/dafny1/Queue.dfy
+++ /dev/null
@@ -1,199 +0,0 @@
-// Queue.dfy
-// Dafny version of Queue.bpl
-// Rustan Leino, 2008
-
-class Queue<T> {
- var head: Node<T>;
- var tail: Node<T>;
-
- ghost var contents: seq<T>;
- ghost var footprint: set<object>;
- ghost var spine: set<Node<T>>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in footprint && spine <= footprint &&
- head != null && head in spine &&
- tail != null && tail in spine &&
- tail.next == null &&
- (forall n ::
- n in spine ==>
- n != null && n.footprint <= footprint && this !in n.footprint &&
- n.Valid() &&
- (n.next == null ==> n == tail)) &&
- (forall n ::
- n in spine ==>
- n.next != null ==> n.next in spine) &&
- contents == head.tailContents
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- ensures |contents| == 0;
- {
- var n := new Node<T>.Init();
- head := n;
- tail := n;
- contents := n.tailContents;
- footprint := {this} + n.footprint;
- spine := {n};
- }
-
- method Rotate()
- requires Valid();
- requires 0 < |contents|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures contents == old(contents)[1..] + old(contents)[..1];
- {
- var t := Front();
- Dequeue();
- Enqueue(t);
- }
-
- method RotateAny()
- requires Valid();
- requires 0 < |contents|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures |contents| == |old(contents)|;
- ensures (exists i :: 0 <= i && i <= |contents| &&
- contents == old(contents)[i..] + old(contents)[..i]);
- {
- var t := Front();
- Dequeue();
- Enqueue(t);
- }
-
- method IsEmpty() returns (isEmpty: bool)
- requires Valid();
- ensures isEmpty <==> |contents| == 0;
- {
- isEmpty := head == tail;
- }
-
- method Enqueue(t: T)
- requires Valid();
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures contents == old(contents) + [t];
- {
- var n := new Node<T>.Init();
- n.data := t;
- tail.next := n;
- tail := n;
-
- parallel (m | m in spine) {
- m.tailContents := m.tailContents + [t];
- }
- contents := head.tailContents;
-
- parallel (m | m in spine) {
- m.footprint := m.footprint + n.footprint;
- }
- footprint := footprint + n.footprint;
-
- spine := spine + {n};
- }
-
- method Front() returns (t: T)
- requires Valid();
- requires 0 < |contents|;
- ensures t == contents[0];
- {
- t := head.next.data;
- }
-
- method Dequeue()
- requires Valid();
- requires 0 < |contents|;
- modifies footprint;
- ensures Valid() && fresh(footprint - old(footprint));
- ensures contents == old(contents)[1..];
- {
- var n := head.next;
- head := n;
- contents := n.tailContents;
- }
-}
-
-class Node<T> {
- var data: T;
- var next: Node<T>;
-
- ghost var tailContents: seq<T>;
- ghost var footprint: set<object>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in footprint &&
- (next != null ==> next in footprint && next.footprint <= footprint) &&
- (next == null ==> tailContents == []) &&
- (next != null ==> tailContents == [next.data] + next.tailContents)
- }
-
- method Init()
- modifies this;
- ensures Valid() && fresh(footprint - {this});
- ensures next == null;
- {
- next := null;
- tailContents := [];
- footprint := {this};
- }
-}
-
-class Main<U> {
- method A<T>(t: T, u: T, v: T)
- {
- var q0 := new Queue<T>.Init();
- var q1 := new Queue<T>.Init();
-
- q0.Enqueue(t);
- q0.Enqueue(u);
-
- q1.Enqueue(v);
-
- assert |q0.contents| == 2;
-
- var w := q0.Front();
- assert w == t;
- q0.Dequeue();
-
- w := q0.Front();
- assert w == u;
-
- assert |q0.contents| == 1;
- assert |q1.contents| == 1;
- }
-
- method Main2(t: U, u: U, v: U, q0: Queue<U>, q1: Queue<U>)
- requires q0 != null && q0.Valid();
- requires q1 != null && q1.Valid();
- requires q0.footprint !! q1.footprint;
- requires |q0.contents| == 0;
- modifies q0.footprint, q1.footprint;
- ensures fresh(q0.footprint - old(q0.footprint));
- ensures fresh(q1.footprint - old(q1.footprint));
- {
- q0.Enqueue(t);
- q0.Enqueue(u);
-
- q1.Enqueue(v);
-
- assert |q0.contents| == 2;
-
- var w := q0.Front();
- assert w == t;
- q0.Dequeue();
-
- w := q0.Front();
- assert w == u;
-
- assert |q0.contents| == 1;
- assert |q1.contents| == old(|q1.contents|) + 1;
- }
-}
diff --git a/Test/dafny1/Rippling.dfy b/Test/dafny1/Rippling.dfy
deleted file mode 100644
index 835c3043..00000000
--- a/Test/dafny1/Rippling.dfy
+++ /dev/null
@@ -1,617 +0,0 @@
-// Datatypes
-
-datatype Bool = False | True;
-
-datatype Nat = Zero | Suc(Nat);
-
-datatype List = Nil | Cons(Nat, List);
-
-datatype Pair = Pair(Nat, Nat);
-
-datatype PList = PNil | PCons(Pair, PList);
-
-datatype Tree = Leaf | Node(Tree, Nat, Tree);
-
-// Boolean functions
-
-function not(b: Bool): Bool
-{
- match b
- case False => True
- case True => False
-}
-
-function and(a: Bool, b: Bool): Bool
-{
- if a == True && b == True then True else False
-}
-
-// Natural number functions
-
-function add(x: Nat, y: Nat): Nat
-{
- match x
- case Zero => y
- case Suc(w) => Suc(add(w, y))
-}
-
-function minus(x: Nat, y: Nat): Nat
-{
- match x
- case Zero => Zero
- case Suc(a) => match y
- case Zero => x
- case Suc(b) => minus(a, b)
-}
-
-function eq(x: Nat, y: Nat): Bool
-{
- match x
- case Zero => (match y
- case Zero => True
- case Suc(b) => False)
- case Suc(a) => (match y
- case Zero => False
- case Suc(b) => eq(a, b))
-}
-
-function leq(x: Nat, y: Nat): Bool
-{
- match x
- case Zero => True
- case Suc(a) => match y
- case Zero => False
- case Suc(b) => leq(a, b)
-}
-
-function less(x: Nat, y: Nat): Bool
-{
- match y
- case Zero => False
- case Suc(b) => match x
- case Zero => True
- case Suc(a) => less(a, b)
-}
-
-function min(x: Nat, y: Nat): Nat
-{
- match x
- case Zero => Zero
- case Suc(a) => match y
- case Zero => Zero
- case Suc(b) => Suc(min(a, b))
-}
-
-function max(x: Nat, y: Nat): Nat
-{
- match x
- case Zero => y
- case Suc(a) => match y
- case Zero => x
- case Suc(b) => Suc(max(a, b))
-}
-
-// List functions
-
-function concat(xs: List, ys: List): List
-{
- match xs
- case Nil => ys
- case Cons(x,tail) => Cons(x, concat(tail, ys))
-}
-
-function mem(x: Nat, xs: List): Bool
-{
- match xs
- case Nil => False
- case Cons(y, ys) => if x == y then True else mem(x, ys)
-}
-
-function delete(n: Nat, xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(y, ys) =>
- if y == n then delete(n, ys) else Cons(y, delete(n, ys))
-}
-
-function drop(n: Nat, xs: List): List
-{
- match n
- case Zero => xs
- case Suc(m) => match xs
- case Nil => Nil
- case Cons(x, tail) => drop(m, tail)
-}
-
-function take(n: Nat, xs: List): List
-{
- match n
- case Zero => Nil
- case Suc(m) => match xs
- case Nil => Nil
- case Cons(x, tail) => Cons(x, take(m, tail))
-}
-
-function len(xs: List): Nat
-{
- match xs
- case Nil => Zero
- case Cons(y, ys) => Suc(len(ys))
-}
-
-function count(x: Nat, xs: List): Nat
-{
- match xs
- case Nil => Zero
- case Cons(y, ys) =>
- if x == y then Suc(count(x, ys)) else count(x, ys)
-}
-
-function last(xs: List): Nat
-{
- match xs
- case Nil => Zero
- case Cons(y, ys) => match ys
- case Nil => y
- case Cons(z, zs) => last(ys)
-}
-
-function apply(f: FunctionValue, xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(y, ys) => Cons(Apply(f, y), apply(f, ys))
-}
-
-// In the following two functions, parameter "p" stands for a predicate: applying p and
-// getting Zero means "false" and getting anything else means "true".
-
-function takeWhileAlways(p: FunctionValue, xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(y, ys) =>
- if Apply(p, y) != Zero
- then Cons(y, takeWhileAlways(p, ys))
- else Nil
-}
-
-function dropWhileAlways(p: FunctionValue, xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(y, ys) =>
- if Apply(p, y) != Zero
- then dropWhileAlways(p, ys)
- else Cons(y, ys)
-}
-
-function filter(p: FunctionValue, xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(y, ys) =>
- if Apply(p, y) != Zero
- then Cons(y, filter(p, ys))
- else filter(p, ys)
-}
-
-function insort(n: Nat, xs: List): List
-{
- match xs
- case Nil => Cons(n, Nil)
- case Cons(y, ys) =>
- if leq(n, y) == True
- then Cons(n, Cons(y, ys))
- else Cons(y, ins(n, ys))
-}
-
-function ins(n: Nat, xs: List): List
-{
- match xs
- case Nil => Cons(n, Nil)
- case Cons(y, ys) =>
- if less(n, y) == True
- then Cons(n, Cons(y, ys))
- else Cons(y, ins(n, ys))
-}
-
-function ins1(n: Nat, xs: List): List
-{
- match xs
- case Nil => Cons(n, Nil)
- case Cons(y, ys) =>
- if n == y
- then Cons(y, ys)
- else Cons(y, ins1(n, ys))
-}
-
-function sort(xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(y, ys) => insort(y, sort(ys))
-}
-
-function reverse(xs: List): List
-{
- match xs
- case Nil => Nil
- case Cons(t, rest) => concat(reverse(rest), Cons(t, Nil))
-}
-
-// Pair list functions
-
-function zip(a: List, b: List): PList
-{
- match a
- case Nil => PNil
- case Cons(x, xs) => match b
- case Nil => PNil
- case Cons(y, ys) => PCons(Pair.Pair(x, y), zip(xs, ys))
-}
-
-function zipConcat(x: Nat, xs: List, more: List): PList
-{
- match more
- case Nil => PNil
- case Cons(y, ys) => PCons(Pair.Pair(x, y), zip(xs, ys))
-}
-
-// Binary tree functions
-
-function height(t: Tree): Nat
-{
- match t
- case Leaf => Zero
- case Node(l, x, r) => Suc(max(height(l), height(r)))
-}
-
-function mirror(t: Tree): Tree
-{
- match t
- case Leaf => Leaf
- case Node(l, x, r) => Node(mirror(r), x, mirror(l))
-}
-
-// Function parameters
-
-// Dafny currently does not support passing functions as arguments. To simulate
-// arbitrary functions, the following type and Apply function play the role of
-// applying some prescribed function (here, a value of the type)
-// to some argument.
-
-type FunctionValue;
-function Apply(f: FunctionValue, x: Nat): Nat // this function is left uninterpreted
-
-// The following functions stand for the constant "false" and "true" functions,
-// respectively.
-
-function AlwaysFalseFunction(): FunctionValue
- ensures forall n :: Apply(AlwaysFalseFunction(), n) == Zero;
-function AlwaysTrueFunction(): FunctionValue
- ensures forall n :: Apply(AlwaysTrueFunction(), n) != Zero;
-
-// -----------------------------------------------------------------------------------
-// The theorems to be proved
-// -----------------------------------------------------------------------------------
-
-ghost method P1()
- ensures forall n, xs :: concat(take(n, xs), drop(n, xs)) == xs;
-{
-}
-
-ghost method P2()
- ensures forall n, xs, ys :: add(count(n, xs), count(n, ys)) == count(n, concat(xs, ys));
-{
-}
-
-ghost method P3()
- ensures forall n, xs, ys :: leq(count(n, xs), count(n, concat(xs, ys))) == True;
-{
-}
-
-ghost method P4()
- ensures forall n, xs :: add(Suc(Zero), count(n, xs)) == count(n, Cons(n, xs));
-{
-}
-
-ghost method P5()
- ensures forall n, xs, x ::
- add(Suc(Zero), count(n, xs)) == count(n, Cons(x, xs))
- ==> n == x;
-{
-}
-
-ghost method P6()
- ensures forall m, n :: minus(n, add(n, m)) == Zero;
-{
-}
-
-ghost method P7()
- ensures forall m, n :: minus(add(n, m), n) == m;
-{
-}
-
-ghost method P8()
- ensures forall k, m, n :: minus(add(k, m), add(k, n)) == minus(m, n);
-{
-}
-
-ghost method P9()
- ensures forall i, j, k :: minus(minus(i, j), k) == minus(i, add(j, k));
-{
-}
-
-ghost method P10()
- ensures forall m :: minus(m, m) == Zero;
-{
-}
-
-ghost method P11()
- ensures forall xs :: drop(Zero, xs) == xs;
-{
-}
-
-ghost method P12()
- ensures forall n, xs, f :: drop(n, apply(f, xs)) == apply(f, drop(n, xs));
-{
-}
-
-ghost method P13()
- ensures forall n, x, xs :: drop(Suc(n), Cons(x, xs)) == drop(n, xs);
-{
-}
-
-ghost method P14()
- ensures forall xs, ys, p :: filter(p, concat(xs, ys)) == concat(filter(p, xs), filter(p, ys));
-{
-}
-
-ghost method P15()
- ensures forall x, xs :: len(ins(x, xs)) == Suc(len(xs));
-{
-}
-
-ghost method P16()
- ensures forall x, xs :: xs == Nil ==> last(Cons(x, xs)) == x;
-{
-}
-
-ghost method P17()
- ensures forall n :: leq(n, Zero) == True <==> n == Zero;
-{
-}
-
-ghost method P18()
- ensures forall i, m :: less(i, Suc(add(i, m))) == True;
-{
-}
-
-ghost method P19()
- ensures forall n, xs :: len(drop(n, xs)) == minus(len(xs), n);
-{
-}
-
-ghost method P20()
- ensures forall xs :: len(sort(xs)) == len(xs);
-{
- P15(); // use the statement of problem 15 as a lemma
- // ... and manually introduce a case distinction:
- assert forall ys ::
- sort(ys) == Nil ||
- exists z, zs :: sort(ys) == Cons(z, zs);
-}
-
-ghost method P21()
- ensures forall n, m :: leq(n, add(n, m)) == True;
-{
-}
-
-ghost method P22()
- ensures forall a, b, c :: max(max(a, b), c) == max(a, max(b, c));
-{
-}
-
-ghost method P23()
- ensures forall a, b :: max(a, b) == max(b, a);
-{
-}
-
-ghost method P24()
- ensures forall a, b :: max(a, b) == a <==> leq(b, a) == True;
-{
-}
-
-ghost method P25()
- ensures forall a, b :: max(a, b) == b <==> leq(a, b) == True;
-{
-}
-
-ghost method P26()
- ensures forall x, xs, ys :: mem(x, xs) == True ==> mem(x, concat(xs, ys)) == True;
-{
-}
-
-ghost method P27()
- ensures forall x, xs, ys :: mem(x, ys) == True ==> mem(x, concat(xs, ys)) == True;
-{
-}
-
-ghost method P28()
- ensures forall x, xs :: mem(x, concat(xs, Cons(x, Nil))) == True;
-{
-}
-
-ghost method P29()
- ensures forall x, xs :: mem(x, ins1(x, xs)) == True;
-{
-}
-
-ghost method P30()
- ensures forall x, xs :: mem(x, ins(x, xs)) == True;
-{
-}
-
-ghost method P31()
- ensures forall a, b, c :: min(min(a, b), c) == min(a, min(b, c));
-{
-}
-
-ghost method P32()
- ensures forall a, b :: min(a, b) == min(b, a);
-{
-}
-
-ghost method P33()
- ensures forall a, b :: min(a, b) == a <==> leq(a, b) == True;
-{
-}
-
-ghost method P34()
- ensures forall a, b :: min(a, b) == b <==> leq(b, a) == True;
-{
-}
-
-ghost method P35()
- ensures forall xs :: dropWhileAlways(AlwaysFalseFunction(), xs) == xs;
-{
-}
-
-ghost method P36()
- ensures forall xs :: takeWhileAlways(AlwaysTrueFunction(), xs) == xs;
-{
-}
-
-ghost method P37()
- ensures forall x, xs :: not(mem(x, delete(x, xs))) == True;
-{
-}
-
-ghost method P38()
- ensures forall n, xs :: count(n, concat(xs, Cons(n, Nil))) == Suc(count(n, xs));
-{
-}
-
-ghost method P39()
- ensures forall n, x, xs ::
- add(count(n, Cons(x, Nil)), count(n, xs)) == count(n, Cons(x, xs));
-{
-}
-
-ghost method P40()
- ensures forall xs :: take(Zero, xs) == Nil;
-{
-}
-
-ghost method P41()
- ensures forall n, xs, f :: take(n, apply(f, xs)) == apply(f, take(n, xs));
-{
-}
-
-ghost method P42()
- ensures forall n, x, xs :: take(Suc(n), Cons(x, xs)) == Cons(x, take(n, xs));
-{
-}
-
-ghost method P43(p: FunctionValue)
- ensures forall xs :: concat(takeWhileAlways(p, xs), dropWhileAlways(p, xs)) == xs;
-{
-}
-
-ghost method P44()
- ensures forall x, xs, ys :: zip(Cons(x, xs), ys) == zipConcat(x, xs, ys);
-{
-}
-
-ghost method P45()
- ensures forall x, xs, y, ys ::
- zip(Cons(x, xs), Cons(y, ys)) ==
- PCons(Pair.Pair(x, y), zip(xs, ys));
-{
-}
-
-ghost method P46()
- ensures forall ys :: zip(Nil, ys) == PNil;
-{
-}
-
-ghost method P47()
- ensures forall a :: height(mirror(a)) == height(a);
-{
- // proving this theorem requires a previously proved lemma:
- P23();
-}
-
-// ...
-
-ghost method P54()
- ensures forall m, n :: minus(add(m, n), n) == m;
-{
- // the proof of this theorem follows from two lemmas:
- assert forall m, n :: minus(add(n, m), n) == m;
- assert forall m, n :: add(m, n) == add(n, m);
-}
-
-ghost method P65()
- ensures forall i, m :: less(i, Suc(add(m, i))) == True;
-{
- if (*) {
- // the proof of this theorem follows from two lemmas:
- assert forall i, m :: less(i, Suc(add(i, m))) == True;
- assert forall m, n :: add(m, n) == add(n, m);
- } else {
- // a different way to prove it uses the following lemma:
- assert forall x,y :: add(x, Suc(y)) == Suc(add(x,y));
- }
-}
-
-ghost method P67()
- ensures forall m, n :: leq(n, add(m, n)) == True;
-{
- if (*) {
- // the proof of this theorem follows from two lemmas:
- assert forall m, n :: leq(n, add(n, m)) == True;
- assert forall m, n :: add(m, n) == add(n, m);
- } else {
- // a different way to prove it uses the following lemma:
- assert forall x,y :: add(x, Suc(y)) == Suc(add(x,y));
- }
-}
-
-// ---------
-// Here is a alternate way of writing down the proof obligations:
-
-ghost method P1_alt(n: Nat, xs: List)
- ensures concat(take(n, xs), drop(n, xs)) == xs;
-{
-}
-
-ghost method P2_alt(n: Nat, xs: List, ys: List)
- ensures add(count(n, xs), count(n, ys)) == count(n, (concat(xs, ys)));
-{
-}
-
-// ---------
-
-ghost method Lemma_RevConcat(xs: List, ys: List)
- ensures reverse(concat(xs, ys)) == concat(reverse(ys), reverse(xs));
-{
- match (xs) {
- case Nil =>
- assert forall ws :: concat(ws, Nil) == ws;
- case Cons(t, rest) =>
- assert forall a, b, c :: concat(a, concat(b, c)) == concat(concat(a, b), c);
- }
-}
-
-ghost method Theorem(xs: List)
- ensures reverse(reverse(xs)) == xs;
-{
- match (xs) {
- case Nil =>
- case Cons(t, rest) =>
- Lemma_RevConcat(reverse(rest), Cons(t, Nil));
- }
-}
diff --git a/Test/dafny1/SchorrWaite-stages.dfy b/Test/dafny1/SchorrWaite-stages.dfy
deleted file mode 100644
index 094e7be7..00000000
--- a/Test/dafny1/SchorrWaite-stages.dfy
+++ /dev/null
@@ -1,267 +0,0 @@
-// Schorr-Waite algorithms, written and verified in Dafny.
-// Rustan Leino
-// Original version: 7 November 2008
-// Version with proof divided into stages: June 2012.
-// Copyright (c) 2008-2012 Microsoft.
-
-ghost module M0 {
- // In this module, we declare the Node class, the definition of Reachability, and the specification
- // and implementation of the Schorr-Waite algorithm.
-
- class Node {
- var children: seq<Node>;
- var marked: bool;
- var childrenVisited: nat;
- }
-
- datatype Path = Empty | Extend(Path, Node);
-
- function Reachable(source: Node, sink: Node, S: set<Node>): bool
- requires null !in S;
- reads S;
- {
- exists via: Path :: ReachableVia(source, via, sink, S)
- }
-
- function ReachableVia(source: Node, p: Path, sink: Node, S: set<Node>): bool
- requires null !in S;
- reads S;
- decreases p;
- {
- match p
- case Empty => source == sink
- case Extend(prefix, n) => n in S && sink in n.children && ReachableVia(source, prefix, n, S)
- }
-
- method SchorrWaite(root: Node, ghost S: set<Node>)
- requires root in S;
- // S is closed under 'children':
- requires forall n :: n in S ==> n != null &&
- forall ch :: ch in n.children ==> ch == null || ch in S;
- // the graph starts off with nothing marked and nothing being indicated as currently being visited:
- requires forall n :: n in S ==> !n.marked && n.childrenVisited == 0;
- modifies S;
- // nodes reachable from 'root' are marked:
- ensures root.marked;
- ensures forall n :: n in S && n.marked ==>
- forall ch :: ch in n.children && ch != null ==> ch.marked;
- // every marked node was reachable from 'root' in the pre-state:
- ensures forall n :: n in S && n.marked ==> old(Reachable(root, n, S));
- // the structure of the graph has not changed:
- ensures forall n :: n in S ==>
- n.childrenVisited == old(n.childrenVisited) &&
- n.children == old(n.children);
- {
- root.marked := true;
- var t, p := root, null;
- ghost var stackNodes := [];
- while (true)
- // stackNodes is a sequence of nodes from S:
- invariant forall n :: n in stackNodes ==> n in S;
-
- // The current node, t, is not included in stackNodes. Rather, t is just above the top of stackNodes.
- // We say that the stack stackNodes+[t] are the "active" nodes.
- invariant t in S && t !in stackNodes;
-
- // p points to the parent of the current node, that is, the node through which t was encountered in the
- // depth-first traversal. This amounts to being the top of stackNodes, or null if stackNodes is empty.
- // Note, it may seem like the variable p is redundant, since it holds a value that can be computed
- // from stackNodes. But note that stackNodes is a ghost variable and won't be present at run
- // time, where p is a physical variable that will be present at run time.
- invariant p == if |stackNodes| == 0 then null else stackNodes[|stackNodes|-1];
-
- // The .childrenVisited field is the extra information that the Schorr-Waite algorithm needs. It
- // is used only for the active nodes, where it keeps track of how many of a node's children have been
- // processed. For the nodes on stackNodes, .childrenVisited is less than the number of children, so
- // it is an index of a child. For t, .childrenVisited may be as large as all of the children, which
- // indicates that the node is ready to be popped off the stack of active nodes. For all other nodes,
- // .childrenVisited is the original value, which is 0.
- invariant forall n :: n in stackNodes ==> n.childrenVisited < |n.children|;
- invariant t.childrenVisited <= |t.children|;
- invariant forall n :: n in S && n !in stackNodes && n != t ==> n.childrenVisited == 0;
-
- // To represent the stackNodes, the algorithm reverses children pointers. It never changes the number
- // of children a node has. The only nodes with children pointers different than the original values are
- // the nodes on stackNodes; moreover, only the index of the currently active child of a node is different.
- invariant forall n :: n in stackNodes ==>
- |n.children| == old(|n.children|) &&
- forall j :: 0 <= j < |n.children| ==> j == n.childrenVisited || n.children[j] == old(n.children[j]);
- invariant forall n :: n in S && n !in stackNodes ==> n.children == old(n.children);
-
- // The children pointers that have been changed form a stack. That is, the active child of stackNodes[k]
- // points to stackNodes[k-1], with the end case pointing to null.
- invariant 0 < |stackNodes| ==>
- stackNodes[0].children[stackNodes[0].childrenVisited] == null;
- invariant forall k :: 0 < k < |stackNodes| ==>
- stackNodes[k].children[stackNodes[k].childrenVisited] == stackNodes[k-1];
- // We also need to keep track of what the original values of the children pointers had been. Here, we
- // have that the active child of stackNodes[k] used to be stackNodes[k+1], with the end case pointing
- // to t.
- invariant forall k :: 0 <= k < |stackNodes|-1 ==>
- old(stackNodes[k].children)[stackNodes[k].childrenVisited] == stackNodes[k+1];
- invariant 0 < |stackNodes| ==>
- old(stackNodes[|stackNodes|-1].children)[stackNodes[|stackNodes|-1].childrenVisited] == t;
-
- decreases *; // leave termination checking for a later refinement
- {
- if (t.childrenVisited == |t.children|) {
- // pop
- t.childrenVisited := 0;
- if (p == null) { break; }
-
- t, p, p.children := p, p.children[p.childrenVisited], p.children[p.childrenVisited := t];
- stackNodes := stackNodes[..|stackNodes| - 1];
- t.childrenVisited := t.childrenVisited + 1;
-
- } else if (t.children[t.childrenVisited] == null || t.children[t.childrenVisited].marked) {
- // just advance to next child
- t.childrenVisited := t.childrenVisited + 1;
-
- } else {
- // push
- stackNodes := stackNodes + [t];
- t, p, t.children := t.children[t.childrenVisited], t, t.children[t.childrenVisited := p];
- t.marked := true;
-
- // To prove that this "if" branch maintains the invariant "t !in stackNodes" will require
- // some more properties about the loop. Therefore, we just assume the property here and
- // prove it in a separate refinement.
- assume t !in stackNodes;
- }
- }
- // From the loop invariant, it now follows that all children pointers have been restored,
- // and so have all .childrenVisited fields. Thus, the last postcondition (the one that says
- // the structure of the graph has not been changed) has been established.
- // Eventually, we also need to prove that exactly the right nodes have been marked,
- // but let's just assume those properties for now and prove them in later refinements:
- assume root.marked && forall n :: n in S && n.marked ==>
- forall ch :: ch in n.children && ch != null ==> ch.marked;
- assume forall n :: n in S && n.marked ==> old(Reachable(root, n, S));
- }
-}
-
-ghost module M1 refines M0 {
- // In this superposition, we start reasoning about the marks. In particular, we prove that the method
- // marks all reachable nodes.
- method SchorrWaite...
- {
- ...;
- while ...
- // The loop keeps marking nodes: The root is always marked. All children of any marked non-active
- // node are marked. Active nodes are marked, and the first .childrenVisited of every active node
- // are marked.
- invariant root.marked;
- invariant forall n :: n in S && n.marked && n !in stackNodes && n != t ==>
- forall ch :: ch in n.children && ch != null ==> ch.marked;
- invariant forall n :: n in stackNodes || n == t ==>
- n.marked &&
- forall j :: 0 <= j < n.childrenVisited ==> n.children[j] == null || n.children[j].marked;
-
- decreases *; // keep postponing termination checking
- {
- if ... { // pop
- } else if ... { // next child
- } else { // push
- ...;
- // With the new loop invariants, we know that all active nodes are marked. Since the new value
- // of "t" was not marked at the beginning of this iteration, we can now prove that the invariant
- // "t !in stackNodes" is maintained, so we'll refine the assume from above with an assert.
- assert ...;
- }
- }
- // The new loop invariants give us a lower bound on which nodes are marked. Hence, we can now
- // discharge the "everything reachable is marked" postcondition, whose proof we postponed above
- // by supplying an assume statement. Here, we refine that assume statement into an assert.
- assert ...;
- }
-}
-
-ghost module M2 refines M1 {
- // In this superposition, we prove that only reachable nodes are marked. Essentially, we want
- // to add a loop invariant that says t is reachable from root, because then the loop invariant
- // that marked nodes are reachable follows. More precisely, we need to say that the node
- // referenced by t is *in the initial state* reachable from root--because as we change
- // children pointers during the course of the algorithm, what is reachable at some point in
- // time may be different from what was reachable initially.
-
- // To do our proof, which involves establishing reachability between various nodes, we need
- // some additional bookkeeping. In particular, we keep track of the path from root to t,
- // and we associate with every marked node the path to it from root. The former is easily
- // maintained in a local ghost variable; the latter is most easily represented as a ghost
- // field in each node (an alternative would be to have a local variable that is a map from
- // nodes to paths). So, we add a field declaration to the Node class:
- class Node {
- ghost var pathFromRoot: Path;
- }
-
- method SchorrWaite...
- {
- ghost var path := Path.Empty;
- root.pathFromRoot := path;
- ...;
- while ...
- // There's a subtle complication when we speak of old(ReachableVia(... P ...)) for a path
- // P. The expression old(...) says to evaluate the expression "..." in the pre-state of
- // the method. So, old(ReachableVia(...)) says to evaluate ReachableVia(...) in the pre-
- // state of the method. But in order for the "old(...)" expression to be well-formed,
- // the subexpressions of the "..." must only refer to values that existed in the pre-state
- // of the method. This incurs the proof obligation that any objects referenced by the
- // parameters of ReachableVia(...) must have been allocated in the pre-state of the
- // method. The proof obligation is easy to establish for root, t, and S (since root and
- // S were given as in-parameters to the method, and we have "t in S"). But what about
- // the path argument to ReachableVia? Since datatype values of type Path contain object
- // references, we need to make sure we can deal with the proof obligation for the path
- // argument. For this reason, we add invariants that say that "path" and the .pathFromRoot
- // field of all marked nodes contain values that make sense in the pre-state.
- invariant !fresh(path) && old(ReachableVia(root, path, t, S));
- invariant forall n :: n in S && n.marked ==> var pth := n.pathFromRoot;
- !fresh(pth) && old(ReachableVia(root, pth, n, S));
- invariant forall n :: n in S && n.marked ==> old(Reachable(root, n, S));
-
- decreases *; // keep postponing termination checking
- {
- if ... {
- // pop
- ...;
- path := t.pathFromRoot;
- } else if ... {
- // advance to next child
- } else {
- // push
- path := Path.Extend(path, t);
- ...;
- t.pathFromRoot := path;
- }
- }
- // In M0 above, we placed two assume statements here. In M1, we refined the first of these
- // into an assert. We repeat that assert here:
- assert ...;
- // And now we we refine the second assume into an assert, proving that only reachable nodes
- // have been marked.
- assert ...;
- }
-}
-
-module M3 refines M2 {
- // In this final superposition, we prove termination of the loop.
- method SchorrWaite...
- {
- // The loop variant is a lexicographic triple, consisting of (0) the set of unmarked
- // nodes, (1) the (length of the) stackNodes sequence, and (2) the number children of
- // the current node that are still to be investigated. We introduce a ghost variable
- // to keep track of the set of unmarked nodes.
- ghost var unmarkedNodes := S - {root};
- ...;
- while ...
- invariant forall n :: n in S && !n.marked ==> n in unmarkedNodes;
- decreases unmarkedNodes, stackNodes, |t.children| - t.childrenVisited;
- {
- if ... { // pop
- } else if ... { // next child
- } else { // push
- ...;
- unmarkedNodes := unmarkedNodes - {t};
- }
- }
- }
-}
diff --git a/Test/dafny1/SchorrWaite.dfy b/Test/dafny1/SchorrWaite.dfy
deleted file mode 100644
index 18adf491..00000000
--- a/Test/dafny1/SchorrWaite.dfy
+++ /dev/null
@@ -1,270 +0,0 @@
-// Rustan Leino
-// 7 November 2008
-// Schorr-Waite and other marking algorithms, written and verified in Dafny.
-// Copyright (c) 2008, Microsoft.
-
-class Node {
- var children: seq<Node>;
- var marked: bool;
- var childrenVisited: int;
- ghost var pathFromRoot: Path;
-}
-
-datatype Path = Empty | Extend(Path, Node);
-
-
-class Main {
- method RecursiveMark(root: Node, ghost S: set<Node>)
- requires root in S;
- // S is closed under 'children':
- requires (forall n :: n in S ==> n != null &&
- (forall ch :: ch in n.children ==> ch == null || ch in S));
- requires (forall n :: n in S ==> ! n.marked && n.childrenVisited == 0);
- modifies S;
- ensures root.marked;
- // nodes reachable from 'root' are marked:
- ensures (forall n :: n in S && n.marked ==>
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- ensures (forall n :: n in S ==>
- n.childrenVisited == old(n.childrenVisited) &&
- n.children == old(n.children));
- {
- RecursiveMarkWorker(root, S, {});
- }
-
- method RecursiveMarkWorker(root: Node, ghost S: set<Node>, ghost stackNodes: set<Node>)
- requires root != null && root in S;
- requires (forall n :: n in S ==> n != null &&
- (forall ch :: ch in n.children ==> ch == null || ch in S));
- requires (forall n :: n in S && n.marked ==>
- n in stackNodes ||
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- requires (forall n :: n in stackNodes ==> n != null && n.marked);
- modifies S;
- ensures root.marked;
- // nodes reachable from 'root' are marked:
- ensures (forall n :: n in S && n.marked ==>
- n in stackNodes ||
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- ensures (forall n: Node :: n in S && old(n.marked) ==> n.marked);
- ensures (forall n :: n in S ==>
- n.childrenVisited == old(n.childrenVisited) &&
- n.children == old(n.children));
- decreases S - stackNodes;
- {
- if (! root.marked) {
- root.marked := true;
- var i := 0;
- while (i < |root.children|)
- invariant root.marked && i <= |root.children|;
- invariant (forall n :: n in S && n.marked ==>
- n == root ||
- n in stackNodes ||
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- invariant (forall j :: 0 <= j && j < i ==>
- root.children[j] == null || root.children[j].marked);
- invariant (forall n: Node :: n in S && old(n.marked) ==> n.marked);
- invariant (forall n :: n in S ==>
- n.childrenVisited == old(n.childrenVisited) &&
- n.children == old(n.children));
- {
- var c := root.children[i];
- if (c != null) {
- RecursiveMarkWorker(c, S, stackNodes + {root});
- }
- i := i + 1;
- }
- }
- }
-
- // ---------------------------------------------------------------------------------
-
- method IterativeMark(root: Node, ghost S: set<Node>)
- requires root in S;
- // S is closed under 'children':
- requires (forall n :: n in S ==> n != null &&
- (forall ch :: ch in n.children ==> ch == null || ch in S));
- requires (forall n :: n in S ==> ! n.marked && n.childrenVisited == 0);
- modifies S;
- ensures root.marked;
- // nodes reachable from 'root' are marked:
- ensures (forall n :: n in S && n.marked ==>
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- ensures (forall n :: n in S ==>
- n.childrenVisited == old(n.childrenVisited) &&
- n.children == old(n.children));
- {
- var t := root;
- t.marked := true;
- var stackNodes := [];
- ghost var unmarkedNodes := S - {t};
- while (true)
- invariant root.marked && t in S && t !in stackNodes;
- // stackNodes has no duplicates:
- invariant (forall i, j :: 0 <= i && i < j && j < |stackNodes| ==>
- stackNodes[i] != stackNodes[j]);
- invariant (forall n :: n in stackNodes ==> n in S);
- invariant (forall n :: n in stackNodes || n == t ==>
- n.marked &&
- 0 <= n.childrenVisited && n.childrenVisited <= |n.children| &&
- (forall j :: 0 <= j && j < n.childrenVisited ==>
- n.children[j] == null || n.children[j].marked));
- invariant (forall n :: n in stackNodes ==> n.childrenVisited < |n.children|);
- // nodes on the stack are linked:
- invariant (forall j :: 0 <= j && j+1 < |stackNodes| ==>
- stackNodes[j].children[stackNodes[j].childrenVisited] == stackNodes[j+1]);
- invariant 0 < |stackNodes| ==>
- stackNodes[|stackNodes|-1].children[stackNodes[|stackNodes|-1].childrenVisited] == t;
- invariant (forall n :: n in S && n.marked && n !in stackNodes && n != t ==>
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- invariant (forall n :: n in S && n !in stackNodes && n != t ==>
- n.childrenVisited == old(n.childrenVisited));
- invariant (forall n: Node :: n in S ==> n.children == old(n.children));
- invariant (forall n :: n in S && !n.marked ==> n in unmarkedNodes);
- decreases unmarkedNodes, stackNodes, |t.children| - t.childrenVisited;
- {
- if (t.childrenVisited == |t.children|) {
- // pop
- t.childrenVisited := 0;
- if (|stackNodes| == 0) {
- return;
- }
- t := stackNodes[|stackNodes| - 1];
- stackNodes := stackNodes[..|stackNodes| - 1];
- t.childrenVisited := t.childrenVisited + 1;
- } else if (t.children[t.childrenVisited] == null || t.children[t.childrenVisited].marked) {
- // just advance to next child
- t.childrenVisited := t.childrenVisited + 1;
- } else {
- // push
- stackNodes := stackNodes + [t];
- t := t.children[t.childrenVisited];
- t.marked := true;
- unmarkedNodes := unmarkedNodes - {t};
- }
- }
- }
-
- // ---------------------------------------------------------------------------------
-
- function Reachable(from: Node, to: Node, S: set<Node>): bool
- requires null !in S;
- reads S;
- {
- (exists via: Path :: ReachableVia(from, via, to, S))
- }
-
- function ReachableVia(from: Node, via: Path, to: Node, S: set<Node>): bool
- requires null !in S;
- reads S;
- decreases via;
- {
- match via
- case Empty => from == to
- case Extend(prefix, n) => n in S && to in n.children && ReachableVia(from, prefix, n, S)
- }
-
- method SchorrWaite(root: Node, ghost S: set<Node>)
- requires root in S;
- // S is closed under 'children':
- requires (forall n :: n in S ==> n != null &&
- (forall ch :: ch in n.children ==> ch == null || ch in S));
- // the graph starts off with nothing marked and nothing being indicated as currently being visited:
- requires (forall n :: n in S ==> ! n.marked && n.childrenVisited == 0);
- modifies S;
- // nodes reachable from 'root' are marked:
- ensures root.marked;
- ensures (forall n :: n in S && n.marked ==>
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- // every marked node was reachable from 'root' in the pre-state:
- ensures (forall n :: n in S && n.marked ==> old(Reachable(root, n, S)));
- // the structure of the graph has not changed:
- ensures (forall n :: n in S ==>
- n.childrenVisited == old(n.childrenVisited) &&
- n.children == old(n.children));
- {
- var t := root;
- var p: Node := null; // parent of t in original graph
- ghost var path := Path.Empty;
- t.marked := true;
- t.pathFromRoot := path;
- ghost var stackNodes := [];
- ghost var unmarkedNodes := S - {t};
- while (true)
- invariant root.marked && t != null && t in S && t !in stackNodes;
- invariant |stackNodes| == 0 <==> p == null;
- invariant 0 < |stackNodes| ==> p == stackNodes[|stackNodes|-1];
- // stackNodes has no duplicates:
- invariant (forall i, j :: 0 <= i && i < j && j < |stackNodes| ==>
- stackNodes[i] != stackNodes[j]);
- invariant (forall n :: n in stackNodes ==> n in S);
- invariant (forall n :: n in stackNodes || n == t ==>
- n.marked &&
- 0 <= n.childrenVisited && n.childrenVisited <= |n.children| &&
- (forall j :: 0 <= j && j < n.childrenVisited ==>
- n.children[j] == null || n.children[j].marked));
- invariant (forall n :: n in stackNodes ==> n.childrenVisited < |n.children|);
- invariant (forall n :: n in S && n.marked && n !in stackNodes && n != t ==>
- (forall ch :: ch in n.children && ch != null ==> ch.marked));
- invariant (forall n :: n in S && n !in stackNodes && n != t ==>
- n.childrenVisited == old(n.childrenVisited));
- invariant (forall n :: n in S ==> n in stackNodes || n.children == old(n.children));
- invariant (forall n :: n in stackNodes ==>
- |n.children| == old(|n.children|) &&
- (forall j :: 0 <= j && j < |n.children| ==>
- j == n.childrenVisited || n.children[j] == old(n.children[j])));
- // every marked node is reachable:
- invariant !fresh(path); // needed to show 'path' worthy as argument to old(Reachable(...))
- invariant old(ReachableVia(root, path, t, S));
- invariant (forall n, pth :: n in S && n.marked && pth == n.pathFromRoot ==> !fresh(pth));
- invariant (forall n, pth :: n in S && n.marked && pth == n.pathFromRoot ==>
- old(ReachableVia(root, pth, n, S)));
- invariant (forall n :: n in S && n.marked ==> old(Reachable(root, n, S)));
- // the current values of m.children[m.childrenVisited] for m's on the stack:
- invariant 0 < |stackNodes| ==> stackNodes[0].children[stackNodes[0].childrenVisited] == null;
- invariant (forall k :: 0 < k && k < |stackNodes| ==>
- stackNodes[k].children[stackNodes[k].childrenVisited] == stackNodes[k-1]);
- // the original values of m.children[m.childrenVisited] for m's on the stack:
- invariant (forall k :: 0 <= k && k+1 < |stackNodes| ==>
- old(stackNodes[k].children)[stackNodes[k].childrenVisited] == stackNodes[k+1]);
- invariant 0 < |stackNodes| ==>
- old(stackNodes[|stackNodes|-1].children)[stackNodes[|stackNodes|-1].childrenVisited] == t;
- invariant (forall n :: n in S && !n.marked ==> n in unmarkedNodes);
- decreases unmarkedNodes, stackNodes, |t.children| - t.childrenVisited;
- {
- if (t.childrenVisited == |t.children|) {
- // pop
- t.childrenVisited := 0;
- if (p == null) {
- return;
- }
- var oldP := p.children[p.childrenVisited];
- // p.children[p.childrenVisited] := t;
- p.children := p.children[..p.childrenVisited] + [t] + p.children[p.childrenVisited + 1..];
- t := p;
- p := oldP;
- stackNodes := stackNodes[..|stackNodes| - 1];
- t.childrenVisited := t.childrenVisited + 1;
- path := t.pathFromRoot;
-
- } else if (t.children[t.childrenVisited] == null || t.children[t.childrenVisited].marked) {
- // just advance to next child
- t.childrenVisited := t.childrenVisited + 1;
-
- } else {
- // push
-
- var newT := t.children[t.childrenVisited];
- // t.children[t.childrenVisited] := p;
- t.children := t.children[..t.childrenVisited] + [p] + t.children[t.childrenVisited + 1..];
- p := t;
- stackNodes := stackNodes + [t];
- path := Path.Extend(path, t);
- t := newT;
- t.marked := true;
- t.pathFromRoot := path;
- unmarkedNodes := unmarkedNodes - {t};
- }
- }
- }
-}
diff --git a/Test/dafny1/SeparationLogicList.dfy b/Test/dafny1/SeparationLogicList.dfy
deleted file mode 100644
index 56a64bd6..00000000
--- a/Test/dafny1/SeparationLogicList.dfy
+++ /dev/null
@@ -1,169 +0,0 @@
-// This file contains three variations of the separation-logic lseg linked-list example.
-
-// In this first variation, the auxiliary information about the contents represented by a linked list
-// and the subpart of the heap that the list occupies is passed around as additional parameters. In
-// separation logic, the contents (here called 'q') would indeed be passed around in that way, whereas
-// separating conjunction and the abstract predicate ListSegment would take care of staking out which
-// subpart of the heap is being occupied by the linked-list representation.
-class Node<T> {
- var data: T;
- var next: Node<T>;
-
- static function ListSegment(q: seq<T>, from: Node<T>, to: Node<T>, S: set<Node<T>>): bool
- reads S;
- {
- if q == []
- then from == to
- else from != null && from in S && from.data == q[0] && ListSegment(q[1..], from.next, to, S - {from})
- }
-
- static method Create(x: T) returns (l: Node<T>, ghost S: set<Node<T>>)
- ensures ListSegment([x], l, null, S) && fresh(S);
- {
- // By using the following non-deterministic 'if' statement, the example shows that 'Create' can be
- // implemented either directly or by call 'Cons'.
- if (*) {
- l := new Node<T>;
- l.data := x;
- l.next := null;
- S := {l};
- } else {
- l, S := Cons(x, null, [], {});
- }
- }
-
- static method Cons(x: T, tail: Node<T>, ghost q: seq<T>, ghost S: set<Node<T>>) returns (l: Node<T>, ghost U: set<Node<T>>)
- requires ListSegment(q, tail, null, S);
- ensures ListSegment([x] + q, l, null, U) && fresh(U - S);
- {
- l := new Node<T>;
- l.data := x;
- l.next := tail;
- U := S + {l};
- }
-}
-
-// The following class is a variation of the one above. The difference is that, in this one, each node
-// keeps track of its own contents (called 'q' above) and representation (called 'S' and 'U' above).
-class ListNode<T> {
- ghost var Contents: seq<T>;
- ghost var Repr: set<ListNode<T>>;
-
- var data: T;
- var next: ListNode<T>;
-
- static function IsList(l: ListNode<T>): bool
- reads l, l.Repr;
- {
- if l == null then
- true
- else if l.next == null then
- l in l.Repr && l.Contents == [l.data]
- else
- {l, l.next} <= l.Repr && l.Contents == [l.data] + l.next.Contents && l.next.Repr <= l.Repr - {l} && IsList(l.next)
- }
-
- static method Create(x: T) returns (l: ListNode<T>)
- ensures IsList(l) && l != null && l.Contents == [x] && fresh({l} + l.Repr);
- {
- // By using the following non-deterministic 'if' statement, the example shows that 'Create' can be
- // implemented either directly or by call 'Cons'.
- if (*) {
- l := new ListNode<T>;
- l.data := x;
- l.next := null;
- l.Repr := {l};
- l.Contents := [x];
- } else {
- l := Cons(x, null);
- }
- }
-
- static method Cons(x: T, tail: ListNode<T>) returns (l: ListNode<T>)
- requires IsList(tail);
- ensures IsList(l) && l != null;
- ensures tail == null ==> l.Contents == [x] && fresh({l} + l.Repr);
- ensures tail != null ==> l.Contents == [x] + tail.Contents && fresh({l} + l.Repr - tail.Repr);
- {
- l := new ListNode<T>;
- l.data := x;
- l.next := tail;
- if (tail != null) {
- l.Repr := tail.Repr + {l};
- l.Contents := [x] + tail.Contents;
- } else {
- l.Repr := {l};
- l.Contents := [x];
- }
- }
-}
-
-// In this final variation, a list, empty or not, is represented by a List object. The representation
-// of a List object includes a number of linked-list nodes. To make the treatment of the empty list
-// nicer than in the class above, the List object starts its list with a sentinel object whose 'data'
-// field is not used.
-class List<T>
-{
- ghost var Contents: seq<T>;
- ghost var Repr: set<object>;
- var head: LLNode<T>;
-
- function IsList(): bool
- reads this, Repr;
- {
- this in Repr && head != null && head in Repr &&
- head.Repr <= Repr && this !in head.Repr && head.IsWellFormed() &&
- Contents == head.TailContents
- }
-
- method Init()
- modifies this;
- ensures IsList() && Contents == [] && fresh(Repr - {this});
- {
- var h := new LLNode<T>;
- h.next := null;
- h.TailContents := [];
- h.Repr := {h};
-
- head := h;
- Contents := [];
- Repr := {this} + h.Repr;
- }
-
- method Cons(x: T)
- requires IsList();
- modifies Repr;
- ensures IsList() && Contents == [x] + old(Contents) && fresh(Repr - old(Repr));
- {
- head.data := x;
- assert head.IsWellFormed(); // head remains well-formed even after assigning to an object (namely, head) in head.Repr
-
- var h := new LLNode<T>;
- h.next := head;
- h.TailContents := [x] + head.TailContents;
- h.Repr := {h} + head.Repr;
-
- head := h;
- Contents := [x] + Contents;
- Repr := Repr + {h};
- }
-}
-
-class LLNode<T>
-{
- var data: T;
- var next: LLNode<T>;
- ghost var TailContents: seq<T>;
- ghost var Repr: set<object>;
-
- function IsWellFormed(): bool
- reads this, Repr;
- {
- this in Repr &&
- (next == null ==> TailContents == []) &&
- (next != null ==>
- next in Repr &&
- next.Repr <= Repr && this !in next.Repr && next.IsWellFormed() &&
- TailContents == [next.data] + next.TailContents)
- }
-}
diff --git a/Test/dafny1/Substitution.dfy b/Test/dafny1/Substitution.dfy
deleted file mode 100644
index ad39e3f2..00000000
--- a/Test/dafny1/Substitution.dfy
+++ /dev/null
@@ -1,107 +0,0 @@
-datatype List = Nil | Cons(Expr, List);
-
-datatype Expr =
- Const(int) |
- Var(int) |
- Nary(int, List);
-
-static function Subst(e: Expr, v: int, val: int): Expr
-{
- match e
- case Const(c) => e
- case Var(x) => if x == v then Expr.Const(val) else e
- case Nary(op, args) => Expr.Nary(op, SubstList(args, v, val))
-}
-
-static function SubstList(l: List, v: int, val: int): List
-{
- match l
- case Nil => l
- case Cons(e, tail) => Cons(Subst(e, v, val), SubstList(tail, v, val))
-}
-
-static ghost method Theorem(e: Expr, v: int, val: int)
- ensures Subst(Subst(e, v, val), v, val) == Subst(e, v, val);
-{
- match e {
- case Const(c) =>
- case Var(x) =>
- case Nary(op, args) =>
- Lemma(args, v, val);
- }
-}
-
-static ghost method Lemma(l: List, v: int, val: int)
- ensures SubstList(SubstList(l, v, val), v, val) == SubstList(l, v, val);
-{
- match l {
- case Nil =>
- case Cons(e, tail) =>
- Theorem(e, v, val);
- Lemma(tail, v, val);
- }
-}
-
-// -------------------------------
-
-datatype Expression =
- Const(int) |
- Var(int) |
- Nary(int, seq<Expression>);
-
-static function Substitute(e: Expression, v: int, val: int): Expression
- decreases e;
-{
- match e
- case Const(c) => e
- case Var(x) => if x == v then Expression.Const(val) else e
- case Nary(op, args) => Expression.Nary(op, SubstSeq(e, args, v, val))
-}
-
-static function SubstSeq(/*ghost*/ parent: Expression,
- q: seq<Expression>, v: int, val: int): seq<Expression>
- requires (forall a :: a in q ==> a < parent);
- decreases parent, q;
-{
- if q == [] then [] else
- SubstSeq(parent, q[..|q|-1], v, val) + [Substitute(q[|q|-1], v, val)]
-}
-
-static ghost method TheoremSeq(e: Expression, v: int, val: int)
- ensures Substitute(Substitute(e, v, val), v, val) == Substitute(e, v, val);
-{
- match e {
- case Const(c) =>
- case Var(x) =>
- case Nary(op, args) =>
- ghost var seArgs := SubstSeq(e, args, v, val);
- LemmaSeq(e, args, v, val);
-
- ghost var se := Substitute(e, v, val);
- ghost var seArgs2 := SubstSeq(se, seArgs, v, val);
- LemmaSeq(se, seArgs, v, val);
-
- var N := |args|;
- var j := 0;
- while (j < N)
- invariant j <= N;
- invariant (forall k :: 0 <= k && k < j ==> seArgs2[k] == seArgs[k]);
- {
- TheoremSeq(args[j], v, val);
- j := j + 1;
- }
- assert seArgs == seArgs2;
- }
-}
-
-static ghost method LemmaSeq(parent: Expression, q: seq<Expression>, v: int, val: int)
- requires (forall a :: a in q ==> a < parent);
- ensures |SubstSeq(parent, q, v, val)| == |q|;
- ensures (forall k :: 0 <= k && k < |q| ==>
- SubstSeq(parent, q, v, val)[k] == Substitute(q[k], v, val));
-{
- if (q == []) {
- } else {
- LemmaSeq(parent, q[..|q|-1], v, val);
- }
-}
diff --git a/Test/dafny1/SumOfCubes.dfy b/Test/dafny1/SumOfCubes.dfy
deleted file mode 100644
index 7ed7ce9b..00000000
--- a/Test/dafny1/SumOfCubes.dfy
+++ /dev/null
@@ -1,104 +0,0 @@
-class SumOfCubes {
- static function SumEmUp(n: int, m: int): int
- requires 0 <= n && n <= m;
- decreases m - n;
- {
- if m == n then 0 else n*n*n + SumEmUp(n+1, m)
- }
-
- static method Socu(n: int, m: int) returns (r: int)
- requires 0 <= n && n <= m;
- ensures r == SumEmUp(n, m);
- {
- var a := SocuFromZero(m);
- var b := SocuFromZero(n);
- r := a - b;
- Lemma0(n, m);
- }
-
- static method SocuFromZero(k: int) returns (r: int)
- requires 0 <= k;
- ensures r == SumEmUp(0, k);
- {
- var g := Gauss(k);
- r := g * g;
- Lemma1(k);
- }
-
- ghost static method Lemma0(n: int, m: int)
- requires 0 <= n && n <= m;
- ensures SumEmUp(n, m) == SumEmUp(0, m) - SumEmUp(0, n);
- {
- var k := n;
- while (k < m)
- invariant n <= k && k <= m;
- invariant SumEmDown(0, n) + SumEmDown(n, k) == SumEmDown(0, k);
- {
- k := k + 1;
- }
- Lemma3(0, n);
- Lemma3(n, k);
- Lemma3(0, k);
- }
-
- static function GSum(k: int): int
- requires 0 <= k;
- {
- if k == 0 then 0 else GSum(k-1) + k-1
- }
-
- static method Gauss(k: int) returns (r: int)
- requires 0 <= k;
- ensures r == GSum(k);
- {
- r := k * (k - 1) / 2;
- Lemma2(k);
- }
-
- ghost static method Lemma1(k: int)
- requires 0 <= k;
- ensures SumEmUp(0, k) == GSum(k) * GSum(k);
- {
- var i := 0;
- while (i < k)
- invariant i <= k;
- invariant SumEmDown(0, i) == GSum(i) * GSum(i);
- {
- Lemma2(i);
- i := i + 1;
- }
- Lemma3(0, k);
- }
-
- ghost static method Lemma2(k: int)
- requires 0 <= k;
- ensures 2 * GSum(k) == k * (k - 1);
- {
- var i := 0;
- while (i < k)
- invariant i <= k;
- invariant 2 * GSum(i) == i * (i - 1);
- {
- i := i + 1;
- }
- }
-
- static function SumEmDown(n: int, m: int): int
- requires 0 <= n && n <= m;
- {
- if m == n then 0 else SumEmDown(n, m-1) + (m-1)*(m-1)*(m-1)
- }
-
- ghost static method Lemma3(n: int, m: int)
- requires 0 <= n && n <= m;
- ensures SumEmUp(n, m) == SumEmDown(n, m);
- {
- var k := n;
- while (k < m)
- invariant n <= k && k <= m;
- invariant SumEmUp(n, m) == SumEmDown(n, k) + SumEmUp(k, m);
- {
- k := k + 1;
- }
- }
-}
diff --git a/Test/dafny1/TerminationDemos.dfy b/Test/dafny1/TerminationDemos.dfy
deleted file mode 100644
index 0aa36a10..00000000
--- a/Test/dafny1/TerminationDemos.dfy
+++ /dev/null
@@ -1,111 +0,0 @@
-class Example {
- method M(n: int)
- {
- var i := 0;
- while (i < n)
- {
- i := i + 1;
- }
- }
-}
-
-// -----------------------------------
-
-class Fibonacci {
- function Fib(n: int): int
- {
- if n < 2 then n else Fib(n-2) + Fib(n-1)
- }
-}
-
-// -----------------------------------
-
-class Ackermann {
- function F(m: int, n: int): int
- {
- if m <= 0 then
- n + 1
- else if n <= 0 then
- F(m - 1, 1)
- else
- F(m - 1, F(m, n - 1))
- }
-
- function G(m: int, n: int): int
- requires 0 <= m && 0 <= n;
- ensures 0 <= G(m, n);
- {
- if m == 0 then
- n + 1
- else if n == 0 then
- G(m - 1, 1)
- else
- G(m - 1, G(m, n - 1))
- }
-
- function H(m: nat, n: nat): nat
- {
- if m == 0 then
- n + 1
- else if n == 0 then
- H(m - 1, 1)
- else
- H(m - 1, H(m, n - 1))
- }
-
- method ComputeAck(m: nat, n: nat) returns (r: nat)
- {
- if (m == 0) {
- r := n + 1;
- } else if (n == 0) {
- r := ComputeAck(m - 1, 1);
- } else {
- var s := ComputeAck(m, n - 1);
- r := ComputeAck(m - 1, s);
- }
- }
-}
-
-// -----------------------------------
-
-class List {
- var data: int;
- var next: List;
- ghost var ListNodes: set<List>;
- function IsAcyclic(): bool
- reads *;
- decreases ListNodes;
- {
- this in ListNodes &&
- (next != null ==>
- next.ListNodes <= ListNodes && this !in next.ListNodes &&
- next.IsAcyclic())
- }
-
- method Singleton(x: int) returns (list: List)
- ensures list != null && list.IsAcyclic();
- {
- list := new List;
- list.data := x;
- list.next := null;
- list.ListNodes := {list};
- }
-
- method Prepend(x: int, tail: List) returns (list: List)
- requires tail == null || tail.IsAcyclic();
- ensures list != null && list.IsAcyclic();
- {
- list := new List;
- list.data := x;
- list.next := tail;
- list.ListNodes := if tail == null then {list} else {list} + tail.ListNodes;
- }
-
- function Sum(): int
- requires IsAcyclic();
- reads *;
- decreases ListNodes;
- {
- if next == null then data else data + next.Sum()
- }
-}
diff --git a/Test/dafny1/TreeDatatype.dfy b/Test/dafny1/TreeDatatype.dfy
deleted file mode 100644
index a94283e6..00000000
--- a/Test/dafny1/TreeDatatype.dfy
+++ /dev/null
@@ -1,90 +0,0 @@
-// ------------------ generic list, non-generic tree
-
-datatype List<T> = Nil | Cons(T, List<T>);
-
-datatype Tree = Node(int, List<Tree>);
-
-static function Inc(t: Tree): Tree
-{
- match t
- case Node(n, children) => Tree.Node(n+1, ForestInc(children))
-}
-
-static function ForestInc(forest: List<Tree>): List<Tree>
-{
- match forest
- case Nil => forest
- case Cons(tree, tail) => List.Cons(Inc(tree), ForestInc(tail))
-}
-
-// ------------------ generic list, generic tree (but GInc defined only for GTree<int>
-
-datatype GTree<T> = Node(T, List<GTree<T>>);
-
-static function GInc(t: GTree<int>): GTree<int>
-{
- match t
- case Node(n, children) => GTree.Node(n+1, GForestInc(children))
-}
-
-static function GForestInc(forest: List<GTree<int>>): List<GTree<int>>
-{
- match forest
- case Nil => forest
- case Cons(tree, tail) => List.Cons(GInc(tree), GForestInc(tail))
-}
-
-// ------------------ non-generic structures
-
-datatype TreeList = Nil | Cons(OneTree, TreeList);
-
-datatype OneTree = Node(int, TreeList);
-
-static function XInc(t: OneTree): OneTree
-{
- match t
- case Node(n, children) => OneTree.Node(n+1, XForestInc(children))
-}
-
-static function XForestInc(forest: TreeList): TreeList
-{
- match forest
- case Nil => forest
- case Cons(tree, tail) => TreeList.Cons(XInc(tree), XForestInc(tail))
-}
-
-// ------------------ fun with recursive functions
-
-function len<T>(l: List<T>): int
-{
- match l
- case Nil => 0
- case Cons(h,t) => 1 + len(t)
-}
-
-function SingletonList<T>(h: T): List<T>
- ensures len(SingletonList(h)) == 1;
-{
- List.Cons(h, List.Nil)
-}
-
-function Append<T>(a: List<T>, b: List<T>): List<T>
- ensures len(Append(a,b)) == len(a) + len(b);
-{
- match a
- case Nil => b
- case Cons(h,t) => List.Cons(h, Append(t, b))
-}
-
-function Rotate<T>(n: int, l: List<T>): List<T>
- requires 0 <= n;
- ensures len(Rotate(n, l)) == len(l);
-{
- match l
- case Nil => l
- case Cons(h, t) =>
- if n == 0 then l else
- Rotate(n-1, Append(t, SingletonList(h)))
-}
-
-
diff --git a/Test/dafny1/UltraFilter.dfy b/Test/dafny1/UltraFilter.dfy
deleted file mode 100644
index c78d5e81..00000000
--- a/Test/dafny1/UltraFilter.dfy
+++ /dev/null
@@ -1,108 +0,0 @@
-// ultra filter
-
-class UltraFilter<G(==)> {
- static function IsFilter(f: set<set<G>>, S: set<G>): bool
- {
- (forall A, B :: A in f && A <= B ==> B in f) &&
- (forall C, D :: C in f && D in f ==> C * D in f) &&
- S in f &&
- {} !in f
- }
-
- static function IsUltraFilter(f: set<set<G>>, S: set<G>): bool
- {
- IsFilter(f, S) &&
- (forall g :: IsFilter(g, S) && f <= g ==> f == g)
- }
-
- method Theorem(f: set<set<G>>, S: set<G>, M: set<G>, N: set<G>)
- requires IsUltraFilter(f, S);
- requires M + N in f;
- ensures M in f || N in f;
- {
- if (M !in f) {
- // instantiate 'g' with the following 'h'
- var h := H(f, S, M);
- Lemma_HIsFilter(h, f, S, M);
- Lemma_FHOrdering0(h, f, S, M);
- }
- }
-
- // Dafny currently does not have a set comprehension expression, so this method stub will have to do
- method H(f: set<set<G>>, S: set<G>, M: set<G>) returns (h: set<set<G>>)
- ensures (forall X :: X in h <==> M + X in f);
-
- method Lemma_HIsFilter(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- requires M !in f;
- ensures IsFilter(h, S);
- {
- // call Lemma_H0(h, f, S, M, *, *);
- assume (forall A, B :: A in h && A <= B ==> B in h);
-
- // call Lemma_H1(h, f, S, M, *, *);
- assume (forall C, D :: C in h && D in h ==> C * D in h);
-
- Lemma_H2(h, f, S, M);
-
- Lemma_H3(h, f, S, M);
- }
-
- method Lemma_H0(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>, A: set<G>, B: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- requires A in h && A <= B;
- ensures B in h;
- {
- assert M + A <= M + B;
- }
-
- method Lemma_H1(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>, C: set<G>, D: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- requires C in h && D in h;
- ensures C * D in h;
- {
- assert (M + C) * (M + D) == M + (C * D);
- }
-
- method Lemma_H2(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- ensures S in h;
- {
- // S is intended to stand for the universal set, but this is the only place where that plays a role
- assume M <= S;
-
- assert M + S == S;
- }
-
- method Lemma_H3(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- requires M !in f;
- ensures {} !in h;
- {
- assert M + {} == M;
- }
-
- method Lemma_FHOrdering0(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- requires IsFilter(h, S);
- ensures f <= h;
- {
- // call Lemma_FHOrdering1(h, f, S, M, *);
- assume (forall Y :: Y in f ==> Y in h);
- assume f <= h; // hickup in boxing
- }
-
- method Lemma_FHOrdering1(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>, Y: set<G>)
- requires IsFilter(f, S);
- requires (forall X :: X in h <==> M + X in f);
- ensures Y in f ==> Y in h;
- {
- assert Y <= M + Y;
- }
-}
diff --git a/Test/dafny1/UnboundedStack.dfy b/Test/dafny1/UnboundedStack.dfy
deleted file mode 100644
index dfc10327..00000000
--- a/Test/dafny1/UnboundedStack.dfy
+++ /dev/null
@@ -1,96 +0,0 @@
-class UnboundedStack<T> {
- ghost var representation: set<object>;
- ghost var content: seq<T>;
- var top: Node<T>;
-
- function IsUnboundedStack(): bool
- reads this, representation;
- {
- this in representation &&
- (top == null ==>
- content == []) &&
- (top != null ==>
- top in representation && this !in top.footprint && top.footprint <= representation &&
- content == top.content &&
- top.Valid())
- }
-
- method InitUnboundedStack()
- modifies this;
- ensures IsUnboundedStack();
- ensures content == [];
- {
- this.top := null;
- this.content := [];
- this.representation := {this};
- }
-
- method Push(val: T)
- requires IsUnboundedStack();
- modifies this;
- ensures IsUnboundedStack();
- ensures content == [val] + old(content);
- {
- top := new Node<T>.InitNode(val,top);
- representation := representation + top.footprint;
- content := [val] + content;
- }
-
- method Pop() returns (result: T)
- requires IsUnboundedStack();
- requires content != [];
- modifies this;
- ensures IsUnboundedStack();
- ensures content == old(content)[1..];
- {
- result := top.val;
- top := top.next;
- content := content[1..];
- }
-
- method isEmpty() returns (result: bool)
- requires IsUnboundedStack();
- ensures result <==> content == [];
- {
- result := top == null;
- }
-}
-
-class Node<T> {
- ghost var footprint: set<object>;
- ghost var content: seq<T>;
- var val: T;
- var next: Node<T>;
-
- function Valid(): bool
- reads this, footprint;
- {
- this in footprint &&
- (next == null ==>
- content == [val]) &&
- (next != null ==>
- next in footprint && next.footprint <= footprint && this !in next.footprint &&
- content == [val] + next.content &&
- next.Valid())
- }
-
- method InitNode(val: T, next: Node<T>)
- requires next != null ==> next.Valid() && !(this in next.footprint);
- modifies this;
- ensures Valid();
- ensures next != null ==> content == [val] + next.content &&
- footprint == {this} + next.footprint;
- ensures next == null ==> content == [val] &&
- footprint == {this};
- {
- this.val := val;
- this.next := next;
- if (next == null) {
- this.footprint := {this};
- this.content := [val];
- } else {
- this.footprint := {this} + next.footprint;
- this.content := [val] + next.content;
- }
- }
-}
diff --git a/Test/dafny1/pow2.dfy b/Test/dafny1/pow2.dfy
deleted file mode 100644
index c7e4bc63..00000000
--- a/Test/dafny1/pow2.dfy
+++ /dev/null
@@ -1,54 +0,0 @@
-// This is a Dafny adaptation of a Coq program by David Pichardie.
-
-function IsEven(n: int): bool
- requires 0 <= n;
- ensures IsEven(n) ==> n == (n/2)+(n/2);
-{
- (n/2)*2 == n
-}
-
-function Square(n: int): int { n * n }
-
-function pow2(n: int): int
- requires 0 <= n;
- ensures 0 <= pow2(n);
-{
- if n == 0 then
- 1
- else if IsEven(n) then
- Square(pow2(n / 2))
- else
- 2*pow2(n-1)
-
-}
-
-function pow2_slow(n: int): int
- requires 0 <= n;
-{
- if n == 0 then
- 1
- else
- 2*pow2_slow(n-1)
-}
-
-ghost method Lemma(n: int)
- requires 0 <= n && IsEven(n);
- ensures pow2_slow(n) == Square(pow2_slow(n/2));
-{
- if (n != 0) {
- Lemma(n-2);
- }
-}
-
-ghost method Theorem(n: int)
- requires 0 <= n;
- ensures pow2(n) == pow2_slow(n);
-{
- if (n == 0) {
- } else if (IsEven(n)) {
- Lemma(n);
- Theorem(n/2);
- } else {
- Theorem(n-1);
- }
-}
diff --git a/Test/dafny1/runtest.bat b/Test/dafny1/runtest.bat
deleted file mode 100644
index a49bbf9a..00000000
--- a/Test/dafny1/runtest.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-for %%f in (Queue.dfy PriorityQueue.dfy
- ExtensibleArray.dfy ExtensibleArrayAuto.dfy
- BinaryTree.dfy
- UnboundedStack.dfy
- SeparationLogicList.dfy
- ListCopy.dfy ListReverse.dfy ListContents.dfy
- MatrixFun.dfy pow2.dfy
- SchorrWaite.dfy SchorrWaite-stages.dfy
- Cubes.dfy SumOfCubes.dfy FindZero.dfy
- TerminationDemos.dfy Substitution.dfy TreeDatatype.dfy KatzManna.dfy
- Induction.dfy Rippling.dfy MoreInduction.dfy
- Celebrity.dfy BDD.dfy
- UltraFilter.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 /vcsMaxKeepGoingSplits:2 /dprint:out.dfy.tmp %* %%f
-)
diff --git a/Test/dafny2/Answer b/Test/dafny2/Answer
deleted file mode 100644
index 2feaf6f7..00000000
--- a/Test/dafny2/Answer
+++ /dev/null
@@ -1,60 +0,0 @@
-
--------------------- Classics.dfy --------------------
-
-Dafny program verifier finished with 5 verified, 0 errors
-
--------------------- TreeBarrier.dfy --------------------
-
-Dafny program verifier finished with 8 verified, 0 errors
-
--------------------- COST-verif-comp-2011-1-MaxArray.dfy --------------------
-
-Dafny program verifier finished with 2 verified, 0 errors
-
--------------------- COST-verif-comp-2011-2-MaxTree-class.dfy --------------------
-
-Dafny program verifier finished with 8 verified, 0 errors
-
--------------------- COST-verif-comp-2011-2-MaxTree-datatype.dfy --------------------
-
-Dafny program verifier finished with 5 verified, 0 errors
-
--------------------- COST-verif-comp-2011-3-TwoDuplicates.dfy --------------------
-
-Dafny program verifier finished with 4 verified, 0 errors
-
--------------------- COST-verif-comp-2011-4-FloydCycleDetect.dfy --------------------
-
-Dafny program verifier finished with 23 verified, 0 errors
-
--------------------- StoreAndRetrieve.dfy --------------------
-
-Dafny program verifier finished with 22 verified, 0 errors
-
--------------------- Intervals.dfy --------------------
-
-Dafny program verifier finished with 5 verified, 0 errors
-
--------------------- TreeFill.dfy --------------------
-
-Dafny program verifier finished with 3 verified, 0 errors
-
--------------------- TuringFactorial.dfy --------------------
-
-Dafny program verifier finished with 3 verified, 0 errors
-
--------------------- MajorityVote.dfy --------------------
-
-Dafny program verifier finished with 11 verified, 0 errors
-
--------------------- SegmentSum.dfy --------------------
-
-Dafny program verifier finished with 3 verified, 0 errors
-
--------------------- MonotonicHeapstate.dfy --------------------
-
-Dafny program verifier finished with 36 verified, 0 errors
-
--------------------- Calculations.dfy --------------------
-
-Dafny program verifier finished with 26 verified, 0 errors
diff --git a/Test/dafny2/COST-verif-comp-2011-1-MaxArray.dfy b/Test/dafny2/COST-verif-comp-2011-1-MaxArray.dfy
deleted file mode 100644
index f67d7870..00000000
--- a/Test/dafny2/COST-verif-comp-2011-1-MaxArray.dfy
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-Rustan Leino, 5 Oct 2011
-
-COST Verification Competition, Challenge 1: Maximum in an array
-http://foveoos2011.cost-ic0701.org/verification-competition
-
-Given: A non-empty integer array a.
-
-Verify that the index returned by the method max() given below points to
-an element maximal in the array.
-
-public class Max {
- public static int max(int[] a) {
- int x = 0;
- int y = a.length-1;
-
- while (x != y) {
- if (a[x] <= a[y]) x++;
- else y--;
- }
- return x;
- }
-}
-*/
-
-// Remarks:
-
-// The verification of the loop makes use of a local ghost variable 'm'. To the
-// verifier, this variable is like any other, but the Dafny compiler ignores it.
-// In other words, ghost variables and ghost assignments (and specifications,
-// for that matter) are included in the program just for the purpose of reasoning
-// about the program, and they play no role at run time.
-
-// The only thing that needs to be human-trusted about this program is the
-// specification of 'max' (and, since verification challenge asked to prove
-// something about a particular piece of code, that the body of 'max', minus
-// the ghost constructs, is really that code).
-
-// About Dafny:
-// As always (when it is successful), Dafny verifies that the program does not
-// cause any run-time errors (like array index bounds errors), that the program
-// terminates, that expressions and functions are well defined, and that all
-// specifications are satisfied. The language prevents type errors by being type
-// safe, prevents dangling pointers by not having an "address-of" or "deallocate"
-// operation (which is accommodated at run time by a garbage collector), and
-// prevents arithmetic overflow errors by using mathematical integers (which
-// is accommodated at run time by using BigNum's). By proving that programs
-// terminate, Dafny proves that a program's time usage is finite, which implies
-// that the program's space usage is finite too. However, executing the
-// program may fall short of your hopes if you don't have enough time or
-// space; that is, the program may run out of space or may fail to terminate in
-// your lifetime, because Dafny does not prove that the time or space needed by
-// the program matches your execution environment. The only input fed to
-// the Dafny verifier/compiler is the program text below; Dafny then automatically
-// verifies and compiles the program (for this program in less than 2 seconds)
-// without further human intervention.
-
-method max(a: array<int>) returns (x: int)
- requires a != null && a.Length != 0;
- ensures 0 <= x < a.Length;
- ensures forall i :: 0 <= i < a.Length ==> a[i] <= a[x];
-{
- x := 0;
- var y := a.Length - 1;
- ghost var m := y;
- while (x != y)
- invariant 0 <= x <= y < a.Length;
- invariant m == x || m == y;
- invariant forall i :: 0 <= i < x ==> a[i] <= a[m];
- invariant forall i :: y < i < a.Length ==> a[i] <= a[m];
- {
- if (a[x] <= a[y]) {
- x := x + 1; m := y;
- } else {
- y := y - 1; m := x;
- }
- }
- return x;
-}
diff --git a/Test/dafny2/COST-verif-comp-2011-2-MaxTree-class.dfy b/Test/dafny2/COST-verif-comp-2011-2-MaxTree-class.dfy
deleted file mode 100644
index 1c01eefc..00000000
--- a/Test/dafny2/COST-verif-comp-2011-2-MaxTree-class.dfy
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Rustan Leino, 5 Oct 2011
-
-COST Verification Competition, Challenge 2: Maximum in a tree
-http://foveoos2011.cost-ic0701.org/verification-competition
-
-Given: A non-empty binary tree, where every node carries an integer.
-
-Implement and verify a program that computes the maximum of the values
-in the tree.
-
-Please base your program on the following data structure signature:
-
-public class Tree {
- int value;
- Tree left;
- Tree right;
-}
-
-You may represent empty trees as null references or as you consider
-appropriate.
-*/
-
-// Remarks:
-
-// The specification of this program uses the common dynamic-frames idiom in Dafny: the
-// ghost field 'Contents' stores the abstract value of an object, the ghost field 'Repr'
-// stores the set of (references to) objects that make up the representation of the object
-// (which in this case is the Tree itself plus the 'Repr' sets of the left and right
-// subtrees), and a function 'Valid()' that returns 'true' when an object is in a
-// consistent state (that is, when an object satisfies the "class invariant").
-
-// The design I used was to represent an empty tree as a Tree object whose left and
-// right pointers point to the object iself. This is convenient, because it lets
-// clients of Tree and the implementation of Tree always use non-null pointers to
-// Tree objects.
-
-// What needs to be human-trusted about this program is that the 'requires' and
-// 'ensures' clauses (that is, the pre- and postconditions, respectively) of
-// 'ComputeMax' are correct. And, since the specification talks about the ghost
-// variable 'Contents', one also needs to trust that the 'Valid()' function
-// constrains 'Contents' in a way that a human thinks matches the intuitive
-// definition of what the contents of a tree is.
-
-// To give a taste of that the 'Valid()' function does not over-constrain the
-// object, I have included two instance constructors, 'Empty()' and 'Node(...)'.
-// To take this a step further, one could also write a 'Main' method that
-// builds somme tree and then calls 'ComputeMax', but I didn't do that here.
-
-// About Dafny:
-// As always (when it is successful), Dafny verifies that the program does not
-// cause any run-time errors (like array index bounds errors), that the program
-// terminates, that expressions and functions are well defined, and that all
-// specifications are satisfied. The language prevents type errors by being type
-// safe, prevents dangling pointers by not having an "address-of" or "deallocate"
-// operation (which is accommodated at run time by a garbage collector), and
-// prevents arithmetic overflow errors by using mathematical integers (which
-// is accommodated at run time by using BigNum's). By proving that programs
-// terminate, Dafny proves that a program's time usage is finite, which implies
-// that the program's space usage is finite too. However, executing the
-// program may fall short of your hopes if you don't have enough time or
-// space; that is, the program may run out of space or may fail to terminate in
-// your lifetime, because Dafny does not prove that the time or space needed by
-// the program matches your execution environment. The only input fed to
-// the Dafny verifier/compiler is the program text below; Dafny then automatically
-// verifies and compiles the program (for this program in less than 2.5 seconds)
-// without further human intervention.
-
-class Tree {
- // an empty tree is represented by a Tree object with left==this==right
- var value: int;
- var left: Tree;
- var right: Tree;
-
- ghost var Contents: seq<int>;
- ghost var Repr: set<object>;
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr &&
- left != null && right != null &&
- ((left == this == right && Contents == []) ||
- (left in Repr && left.Repr <= Repr && this !in left.Repr &&
- right in Repr && right.Repr <= Repr && this !in right.Repr &&
- left.Valid() && right.Valid() &&
- Contents == left.Contents + [value] + right.Contents))
- }
-
- function method IsEmpty(): bool
- requires Valid();
- reads Repr;
- ensures IsEmpty() <==> Contents == [];
- {
- left == this
- }
-
- constructor Empty()
- modifies this;
- ensures Valid() && Contents == [];
- {
- left, right := this, this;
- Contents := [];
- Repr := {this};
- }
-
- constructor Node(lft: Tree, val: int, rgt: Tree)
- requires lft != null && rgt != null && lft.Valid() && rgt.Valid();
- requires this !in lft.Repr && this !in rgt.Repr;
- modifies this;
- ensures Valid() && Contents == lft.Contents + [val] + rgt.Contents;
- {
- left, value, right := lft, val, rgt;
- Contents := lft.Contents + [val] + rgt.Contents;
- Repr := lft.Repr + {this} + rgt.Repr;
- }
-
- method ComputeMax() returns (mx: int)
- requires Valid() && !IsEmpty();
- ensures forall x :: x in Contents ==> x <= mx;
- ensures exists x :: x in Contents && x == mx;
- decreases Repr;
- {
- mx := value;
- if (!left.IsEmpty()) {
- var m := left.ComputeMax();
- mx := if mx < m then m else mx;
- }
- if (!right.IsEmpty()) {
- var m := right.ComputeMax();
- mx := if mx < m then m else mx;
- }
- }
-}
diff --git a/Test/dafny2/COST-verif-comp-2011-2-MaxTree-datatype.dfy b/Test/dafny2/COST-verif-comp-2011-2-MaxTree-datatype.dfy
deleted file mode 100644
index 8dd7bd2d..00000000
--- a/Test/dafny2/COST-verif-comp-2011-2-MaxTree-datatype.dfy
+++ /dev/null
@@ -1,65 +0,0 @@
-// This Dafny program was inspired by Claude Marche's Why3ML program that solves
-// Challenge 2 of the COST Verification Competition. It particular, it uses an
-// inductive datatype for the Tree data structure, and it uses a Contains function
-// defined on such trees. This makes the whole program short and sweet, keeps
-// proof annotation overhead to a minimum, and--best of all--makes for a convincing
-// specification of Max.
-// Rustan Leino, 7 Oct 2011
-
-// Remarks:
-
-// A little detail about the implementation of 'Max' below is that the precondition
-// 't != Null' means that the 'match' statement does not need to include a case
-// for 'Null'. The correctness of the omission of cases is checked by the program
-// verifier.
-
-// About Dafny:
-// As always (when it is successful), Dafny verifies that the program does not
-// cause any run-time errors (like array index bounds errors), that the program
-// terminates, that expressions and functions are well defined, and that all
-// specifications are satisfied. The language prevents type errors by being type
-// safe, prevents dangling pointers by not having an "address-of" or "deallocate"
-// operation (which is accommodated at run time by a garbage collector), and
-// prevents arithmetic overflow errors by using mathematical integers (which
-// is accommodated at run time by using BigNum's). By proving that programs
-// terminate, Dafny proves that a program's time usage is finite, which implies
-// that the program's space usage is finite too. However, executing the
-// program may fall short of your hopes if you don't have enough time or
-// space; that is, the program may run out of space or may fail to terminate in
-// your lifetime, because Dafny does not prove that the time or space needed by
-// the program matches your execution environment. The only input fed to
-// the Dafny verifier/compiler is the program text below; Dafny then automatically
-// verifies and compiles the program (for this program in less than 2 seconds)
-// without further human intervention.
-
-datatype Tree = Null | Node(Tree, int, Tree);
-
-function Contains(t: Tree, v: int): bool
-{
- match t
- case Null => false
- case Node(left, x, right) => x == v || Contains(left, v) || Contains(right, v)
-}
-
-method Max(t: Tree) returns (result: int)
- requires t != Null;
- ensures Contains(t, result) && forall v :: Contains(t, v) ==> v <= result;
-{
- match (t) {
- case Node(left, x, right) =>
- result := MaxAux(right, x);
- result := MaxAux(left, result);
- }
-}
-
-method MaxAux(t: Tree, acc: int) returns (result: int)
- ensures result == acc || Contains(t, result);
- ensures acc <= result && forall v :: Contains(t, v) ==> v <= result;
-{
- match (t) {
- case Null => result := acc;
- case Node(left, x, right) =>
- result := MaxAux(right, if x < acc then acc else x);
- result := MaxAux(left, result);
- }
-}
diff --git a/Test/dafny2/COST-verif-comp-2011-3-TwoDuplicates.dfy b/Test/dafny2/COST-verif-comp-2011-3-TwoDuplicates.dfy
deleted file mode 100644
index 069baa61..00000000
--- a/Test/dafny2/COST-verif-comp-2011-3-TwoDuplicates.dfy
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Rustan Leino, 5 Oct 2011
-
-COST Verification Competition, Challenge 3: Two equal elements
-http://foveoos2011.cost-ic0701.org/verification-competition
-
-Given: An integer array a of length n+2 with n>=2. It is known that at
-least two values stored in the array appear twice (i.e., there are at
-least two duplets).
-
-Implement and verify a program finding such two values.
-
-You may assume that the array contains values between 0 and n-1.
-*/
-
-// Remarks:
-
-// The implementation of method 'Search' takes one pass through the elements of
-// the given array. To keep track of what it has seen, it allocates an array as
-// temporary storage--I imagine that this is what the competition designers
-// had in mind, since the problem description says one can assume the values
-// of the given array to lie in the range 0..n.
-
-// To keep track of whether it already has found one duplicate, the method
-// sets the output variables p and q as follows:
-// p != q - no duplicates found yet
-// p == q - one duplicate found so far, namely the value stored in p and q
-// Note, the loop invariant does not need to say anything about the state
-// of two duplicates having been found, because when the second duplicate is
-// found, the method returns.
-
-// What needs to be human-trusted about this program is the specification of
-// 'Search'. The specification straightforwardly lists the assumptions stated
-// in the problem description, including the given fact that the array contains
-// (at least) two distinct elements that each occurs (at least) twice. To
-// trust the specification of 'Search', a human also needs to trust the definition
-// of 'IsDuplicate' and its auxiliary function 'IsPrefixDuplicate'.
-
-// About Dafny:
-// As always (when it is successful), Dafny verifies that the program does not
-// cause any run-time errors (like array index bounds errors), that the program
-// terminates, that expressions and functions are well defined, and that all
-// specifications are satisfied. The language prevents type errors by being type
-// safe, prevents dangling pointers by not having an "address-of" or "deallocate"
-// operation (which is accommodated at run time by a garbage collector), and
-// prevents arithmetic overflow errors by using mathematical integers (which
-// is accommodated at run time by using BigNum's). By proving that programs
-// terminate, Dafny proves that a program's time usage is finite, which implies
-// that the program's space usage is finite too. However, executing the
-// program may fall short of your hopes if you don't have enough time or
-// space; that is, the program may run out of space or may fail to terminate in
-// your lifetime, because Dafny does not prove that the time or space needed by
-// the program matches your execution environment. The only input fed to
-// the Dafny verifier/compiler is the program text below; Dafny then automatically
-// verifies and compiles the program (for this program in less than 11 seconds)
-// without further human intervention.
-
-function IsDuplicate(a: array<int>, p: int): bool
- requires a != null;
- reads a;
-{
- IsPrefixDuplicate(a, a.Length, p)
-}
-
-function IsPrefixDuplicate(a: array<int>, k: int, p: int): bool
- requires a != null && 0 <= k <= a.Length;
- reads a;
-{
- exists i,j :: 0 <= i < j < k && a[i] == a[j] == p
-}
-
-method Search(a: array<int>) returns (p: int, q: int)
- requires a != null && 4 <= a.Length;
- requires exists p,q :: p != q && IsDuplicate(a, p) && IsDuplicate(a, q); // two distinct duplicates exist
- requires forall i :: 0 <= i < a.Length ==> 0 <= a[i] < a.Length - 2; // the elements of "a" in the range [0.. a.Length-2]
- ensures p != q && IsDuplicate(a, p) && IsDuplicate(a, q);
-{
- // allocate an array "d" and initialize its elements to -1.
- var d := new int[a.Length-2];
- var i := 0;
- while (i < d.Length)
- invariant 0 <= i <= d.Length && forall j :: 0 <= j < i ==> d[j] == -1;
- {
- d[i], i := -1, i+1;
- }
-
- i, p, q := 0, 0, 1;
- while (true)
- invariant 0 <= i < a.Length;
- invariant forall j :: 0 <= j < d.Length ==>
- (d[j] == -1 && forall k :: 0 <= k < i ==> a[k] != j) ||
- (0 <= d[j] < i && a[d[j]] == j);
- invariant p == q ==> IsDuplicate(a, p);
- invariant forall k :: 0 <= k < i && IsPrefixDuplicate(a, i, a[k]) ==> p == q == a[k];
- decreases a.Length - i;
- {
- var k := d[a[i]];
- assert k < i; // note, this assertion is really for human consumption; it is not needed by the verifier, and it does not change the performance of the verifier
- if (k == -1) {
- // a[i] does not exist in a[..i]
- d[a[i]] := i;
- } else {
- // we have encountered a duplicate
- assert a[i] == a[k] && IsDuplicate(a, a[i]); // note, this assertion is really for human consumption; it is not needed by the verifier, and it does not change the performance of the verifier
- if (p != q) {
- // this is the first duplicate encountered
- p, q := a[i], a[i];
- } else if (p == a[i]) {
- // this is another copy of the same duplicate we have seen before
- } else {
- // this is the second duplicate
- q := a[i];
- return;
- }
- }
- i := i + 1;
- }
-}
diff --git a/Test/dafny2/COST-verif-comp-2011-4-FloydCycleDetect.dfy b/Test/dafny2/COST-verif-comp-2011-4-FloydCycleDetect.dfy
deleted file mode 100644
index 774008b8..00000000
--- a/Test/dafny2/COST-verif-comp-2011-4-FloydCycleDetect.dfy
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
-Rustan Leino, 6 Oct 2011
-
-COST Verification Competition, Challenge 4: Cyclic list
-http://foveoos2011.cost-ic0701.org/verification-competition
-
-Given: A Java linked data structure with the signature:
-
-public class Node {
- Node next;
-
- public boolean cyclic() {
- //...
- }
-}
-
-Implement and verify the method cyclic() to return true when the data
-structure is cyclic (i.e., this Node can be reached by following next
-links) and false when it is not.
-*/
-
-// Remarks:
-
-// I found the problem statement slightly ambiguous. What I implemented was a
-// method 'Cyclic' that returns true when 'this' can reach a cycle. That is,
-// 'this' does not itself have to be on the cycle in order for the method to
-// return true.
-
-// I wanted to assume as little as possible about the state of the data structure
-// when 'Cyclic' is called. The proof of the algorithm (indeed, the correctness
-// of the algorithm) requires the number of nodes to be finite. To specify
-// this, I included to 'Cyclic' a parameter 'S' that contains all nodes that
-// are reachable from 'this'. The specification says that 'S' contains 'this'
-// and 'null', and that is closed under the 'next' field. This parameter and
-// its associated 'IsClosed' condition are threaded through all functions and
-// methods in the program. The set 'S' is used only for specification purposes,
-// so I declared it to be a ghost parameter of 'Cyclic'. Other than including
-// 'S' and 'IsClosed(S)' in the specification, the program does not assume anything
-// about the state of 'this' and the other objects in 'S'.
-
-// The algorithm I implement and verify is due to Bob Floyd and is sometimes
-// known as the "tortoise and hare" algorithm. The idea is simple: Use 2 pointers,
-// called 'tortoise' and 'hare', and advance 'hare' twice as quickly as 'tortoise'.
-// Eventually, 'hare' will reach 'null' (in which case 'this' does not reach a
-// cycle) or 'hare' will become equal to 'tortoise' (in which 'this' does reach a
-// cycle). Formally and mechanically proving the correctness of the algorithm
-// is much harder, I found.
-
-// Because this file is long, it is especially important to know what a human needs
-// to trust in order to believe that the program is correct. The main thing
-// is the specification of 'Cyclic', and in particular its postcondition, which
-// expresses what it means for 'this' to be able to reach a cycle. Since this
-// postcondition mentions the function 'Reaches', it is also necessary to trust
-// the definition of 'Reaches' (but it is not necessary to trust the 'ensures'
-// clause of the function). Function 'Reaches' is in turn defined in terms
-// of 'Nexxxt(k,...)' which stands for 'k' applications of the field 'next'
-// (and returns 'null' if 'null' is ever reached along the way). Other than
-// these things, the rest of the program is implementation details and proof
-// details. Well, one may want to inspect the body of 'Cyclic' to see that it
-// does indeed implement Floyd's algorithm--for this inspection, ignore all
-// ghost things, like ghost variables, updates to ghost variables, assert
-// statements, and calls to lemmas.
-
-// The proof is long. One interesting aspect of it is that it is all constructed
-// as a program fed to a program verifier. Since the additional properties
-// are specified using ghost variables, ghost methods, and other ghost constructs,
-// the run-time execution of the program is not affected by including the
-// proof as part of the program, because the Dafny compiler ignores all ghost
-// constructs.
-
-// The proof (and in particular the proof of termination), makes use of two
-// numbers, called 'A' and 'B' and computed by the call to the ghost method
-// 'AnalyzeList'. 'A' is the number of steps from 'this' before a cycle is
-// reached. If there is no cycle, 'A' is the length of the list. 'B' is the
-// length of the cycle, if any. But, you ask, how are 'A' and 'B' obtained?
-// If these are used to prove the termination of 'Cyclic', then how does one
-// prove the termination of the computation of 'A' and 'B'? The answer is
-// that 'AnalyzeList' uses a simpler algorithm, namely a depth-first traversal
-// from 'this' that uses a set to keep track of which nodes have been visited.
-// This set would not be nice to have to represent at run time, but since
-// 'AnalyzeList' is a ghost method, the variable holding the set does not survive
-// compilation. So, 'Cyclic' first calls ghost method 'Analyze' to traverse
-// the list and then, equipped with 'A' and 'B' to carry out the proof of Floyd's
-// algorithm, proceeds with Floyd's algorithm.
-
-// The ghost constructs in 'Cyclic' add some clutter to the program text. To
-// alleviate matter a little, I have include the word "Lemma" in the names of
-// all ghost methods (except ghost method 'AnalyzeList', which I guess didn't
-// feel to me like a "lemma" per se).
-
-// The Dafny verifier, which builds on verification engine Boogie, which in turn
-// builds on the SMT solver Z3, needs help throughout this proof. To give it
-// hints about which properties to prove, the program uses assert statements and
-// calls to lemmas. These do not provide the verifier with new facts or
-// assumptions--they only instruct the verifier to verify something, after which
-// the verifier can make use of what it just verified. In a number of places,
-// the assert statements mention universally quantified properties whose proof
-// require induction; Dafny heuristically detects these and applies its induction
-// tactic (in the absence of that induction tactic, more handholding would be
-// required in the program text to guide the verifier through the proof, see
-// 'Lemma_NexxxtIsTransitive', for example).
-
-// About Dafny:
-// As always (when it is successful), Dafny verifies that the program does not
-// cause any run-time errors (like array index bounds errors), that the program
-// terminates, that expressions and functions are well defined, and that all
-// specifications are satisfied. The language prevents type errors by being type
-// safe, prevents dangling pointers by not having an "address-of" or "deallocate"
-// operation (which is accommodated at run time by a garbage collector), and
-// prevents arithmetic overflow errors by using mathematical integers (which
-// is accommodated at run time by using BigNum's). By proving that programs
-// terminate, Dafny proves that a program's time usage is finite, which implies
-// that the program's space usage is finite too. However, executing the
-// program may fall short of your hopes if you don't have enough time or
-// space; that is, the program may run out of space or may fail to terminate in
-// your lifetime, because Dafny does not prove that the time or space needed by
-// the program matches your execution environment. The only input fed to
-// the Dafny verifier/compiler is the program text below; Dafny then automatically
-// verifies and compiles the program (for this program in less than 30 seconds,
-// 25 seconds of which is spent verifying the ghost method AnalyzeList)
-// without further human intervention.
-
-class Node {
- var next: Node;
-
- function IsClosed(S: set<Node>): bool
- reads S;
- {
- this in S && null in S &&
- forall n :: n in S && n != null && n.next != null ==> n.next in S
- }
-
- function Nexxxt(k: int, S: set<Node>): Node
- requires IsClosed(S) && 0 <= k;
- ensures Nexxxt(k, S) in S; // a consequence of the definition
- reads S;
- decreases k;
- {
- if k == 0 then this
- else if Nexxxt(k-1, S) == null then null
- else Nexxxt(k-1, S).next
- }
-
- function Reaches(sink: Node, S: set<Node>): bool
- requires IsClosed(S);
- ensures Reaches(sink, S) ==> sink in S; // a consequence of the definition
- reads S;
- {
- exists k :: 0 <= k && Nexxxt(k, S) == sink
- }
-
- method Cyclic(ghost S: set<Node>) returns (reachesCycle: bool)
- requires IsClosed(S);
- ensures reachesCycle <==> exists n :: n != null && Reaches(n, S) && n.next != null && n.next.Reaches(n, S);
- {
- ghost var A, B := AnalyzeList(S);
- var tortoise, hare:= this, next;
- ghost var t, h := 0, 1;
- while (hare != tortoise)
- invariant tortoise != null && tortoise in S && hare in S;
- invariant 0 <= t < h && Nexxxt(t, S) == tortoise && Nexxxt(h, S) == hare;
- // What follows of the invariant is for proving termination:
- invariant h == 1 + 2*t && t <= A + B;
- invariant forall k :: 0 <= k < t ==> Nexxxt(k, S) != Nexxxt(1+2*k, S);
- decreases A + B - t;
- {
- if (hare == null || hare.next == null) {
- ghost var distanceToNull := if hare == null then h else h+1;
- Lemma_NullImpliesNoCycles(distanceToNull, S);
- assert !exists k,l :: 0 <= k && 0 <= l && Nexxxt(k, S) != null && Nexxxt(k, S).next != null && Nexxxt(k, S).next.Nexxxt(l, S) == Nexxxt(k, S); // this is a copy of the postcondition of lemma NullImpliesNoCycles
- return false;
- }
- Lemma_NullIsTerminal(h+1, S);
- assert Nexxxt(t+1, S) != null;
- tortoise, t, hare, h := tortoise.next, t+1, hare.next.next, h+2;
- CrucialLemma(A, B, S);
- }
- Lemma_NullIsTerminal(h, S);
- Lemma_NexxxtIsTransitive(t+1, h - (t+1), S);
- assert tortoise.next.Reaches(tortoise, S);
- return true;
- }
-
- // What follows in this file are details that are relevant only to the proof. That is,
- // to trust that the algorithm is correct, it is not necessary to go through the
- // details below--the specification of 'Cyclic' above and the fact that Dafny verifies
- // the program suffice. (Of course, one also needs to trust the verifier.)
-
- ghost method AnalyzeList(S: set<Node>) returns (A: int, B: int)
- requires IsClosed(S);
- // find an A and B (0 <= A && 1 <= B) such that:
- // the first A steps are no on a cycle, and
- // either next^A == null or next^A == next^(A+B).
- ensures 0 <= A && 1 <= B;
- ensures forall k,l :: 0 <= k < l < A ==> Nexxxt(k, S) != Nexxxt(l, S);
- ensures Nexxxt(A, S) == null || Nexxxt(A, S).Nexxxt(B, S) == Nexxxt(A, S);
- {
- // since S is finite, we can just go ahead and compute the transitive closure of "next" from "this"
- var p, steps, Visited := this, 0, {null};
- while (p !in Visited)
- invariant 0 <= steps && p == Nexxxt(steps, S) && p in S && null in Visited;
- invariant Visited <= S;
- invariant forall t :: 0 <= t < steps ==> Nexxxt(t, S) in Visited;
- invariant forall q :: q in Visited ==> q == null || exists t :: 0 <= t < steps && Nexxxt(t, S) == q;
- invariant forall k,l :: 0 <= k < l < steps ==> Nexxxt(k, S) != Nexxxt(l, S);
- decreases S - Visited;
- {
- p, steps, Visited := p.next, steps + 1, Visited + {p};
- }
- if (p == null) {
- A, B := steps, 1;
- } else {
- assert exists k :: 0 <= k < steps && Nexxxt(k, S) == p;
- // find this k
- A := 0;
- while (Nexxxt(A, S) != p)
- invariant 0 <= A < steps;
- invariant forall k :: 0 <= k < A ==> Nexxxt(k, S) != p;
- decreases steps - A;
- {
- A := A + 1;
- }
- B := steps - A;
- assert Nexxxt(A, S) != null;
- Lemma_NexxxtIsTransitive(A, B, S);
- }
- }
-
- ghost method CrucialLemma(a: int, b: int, S: set<Node>)
- requires IsClosed(S);
- requires 0 <= a && 1 <= b;
- requires forall k,l :: 0 <= k < l < a ==> Nexxxt(k, S) != Nexxxt(l, S);
- requires Nexxxt(a, S) == null || Nexxxt(a, S).Nexxxt(b, S) == Nexxxt(a, S);
- ensures exists T :: 0 <= T < a+b && Nexxxt(T, S) == Nexxxt(1+2*T, S);
- {
- if (Nexxxt(a, S) == null) {
- Lemma_NullIsTerminal(1+2*a, S);
- assert Nexxxt(a, S) == null ==> Nexxxt(1+2*a, S) == null;
- } else {
- assert Nexxxt(a, S) != null && Nexxxt(a, S).Nexxxt(b, S) == Nexxxt(a, S);
- Lemma_NexxxtIsTransitive(a, b, S);
- assert Nexxxt(a + b, S) == Nexxxt(a, S);
- // When the tortoise has done "a" steps, both it and the hare have reached the cycle.
- // Since the cycle has length "b", the hare has at most "b" steps to catch up with the
- // tortoise. Well, you may think of the tortoise as being the one that has to catch up,
- // since the tortoise has not traveled as far. So, let's imagine a virtual tortoise
- // that is in the same position as the tortoise, but who got there by taking at least
- // as many steps as the hare (but fewer than "b" steps more than the hare).
- var t, h := a, 1+2*a; // steps traveled by the tortoise and the hare, respectively
- var vt := a; // steps traveled by the virtual tortoise
- while (vt < h)
- invariant t <= vt < h+b;
- invariant Nexxxt(t, S) == Nexxxt(vt, S);
- {
- Lemma_AboutCycles(a, b, vt, S);
- vt := vt + b; // let the virtual tortoise take another lap
- }
- // Good. Since the virtual tortoise has now taken at least as many steps as the hare,
- // we can compute (as a non-negative number) the steps that hare is trailing behind the
- // virtual tortoise.
- var catchup := vt - h;
- assert 0 <= catchup < b;
- // Now, let the hare catch up with the virtual tortoise by simulating "catchup" steps
- // of the algorithm.
- var i := 0;
- while (i < catchup)
- invariant 0 <= i <= catchup;
- invariant t == a + i && h == 1 + 2*t && t <= vt;
- invariant Nexxxt(t, S) == Nexxxt(vt, S) == Nexxxt(h + catchup - i, S);
- {
- i, t, vt, h := i+1, t+1, vt+1, h+2;
- }
- assert a <= t < a + b && Nexxxt(t, S) == Nexxxt(1 + 2*t, S);
- }
- }
-
- ghost method Lemma_AboutCycles(a: int, b: int, k: int, S: set<Node>)
- requires IsClosed(S);
- requires 0 <= a <= k && 1 <= b && Nexxxt(a, S) != null && Nexxxt(a, S).Nexxxt(b, S) == Nexxxt(a, S);
- ensures Nexxxt(k + b, S) == Nexxxt(k, S);
- {
- Lemma_NexxxtIsTransitive(a, b, S);
- var n := a;
- while (n < k)
- invariant a <= n <= k;
- invariant Nexxxt(n + b, S) == Nexxxt(n, S);
- {
- n := n + 1;
- }
- }
-
- ghost method Lemma_NexxxtIsTransitive(x: int, y: int, S: set<Node>)
- requires IsClosed(S) && 0 <= x && 0 <= y;
- ensures Nexxxt(x, S) != null ==> Nexxxt(x, S).Nexxxt(y, S) == Nexxxt(x + y, S);
- {
- if (Nexxxt(x, S) != null)
- {
- assert forall j :: 0 <= j ==> Nexxxt(x, S).Nexxxt(j, S) == Nexxxt(x + j, S); // Dafny's induction tactic kicks in
- /* Alternatively, here's a manual proof by induction (but only up to the needed y):
- var j := 0;
- while (j < y)
- invariant 0 <= j <= y;
- invariant Nexxxt(x, S).Nexxxt(j, S) == Nexxxt(x + j, S);
- {
- j := j + 1;
- }
- */
- }
- }
-
- ghost method Lemma_NullIsTerminal(d: int, S: set<Node>)
- requires IsClosed(S) && 0 <= d;
- ensures forall k :: 0 <= k < d && Nexxxt(d, S) != null ==> Nexxxt(k, S) != null;
- {
- var j := d;
- while (0 < j)
- invariant 0 <= j <= d;
- invariant forall k :: j <= k < d && Nexxxt(k, S) == null ==> Nexxxt(d, S) == null;
- {
- j := j - 1;
- if (Nexxxt(j, S) == null) {
- assert Nexxxt(j+1, S) == null;
- }
- }
- }
-
- ghost method Lemma_NullImpliesNoCycles(n: int, S: set<Node>)
- requires IsClosed(S) && 0 <= n && Nexxxt(n, S) == null;
- ensures !exists k,l :: 0 <= k && 0 <= l && Nexxxt(k, S) != null && Nexxxt(k, S).next != null && Nexxxt(k, S).next.Nexxxt(l, S) == Nexxxt(k, S);
- {
- // The proof of this lemma is more complicated than necessary, because Dafny does not know that
- // "if P(k,l) holds for one arbitrary (k,l), then it holds for all (k,l)".
- Lemma_NullImpliesNoCycles_part0(n, S);
- Lemma_NullImpliesNoCycles_part1(n, S);
- Lemma_NullImpliesNoCycles_part2(n, S);
- }
-
- ghost method Lemma_NullImpliesNoCycles_part0(n: int, S: set<Node>)
- requires IsClosed(S) && 0 <= n && Nexxxt(n, S) == null;
- ensures forall k,l :: n <= k && 0 <= l && Nexxxt(k, S) != null && Nexxxt(k, S).next != null ==> Nexxxt(k, S).next.Nexxxt(l, S) != Nexxxt(k, S);
- {
- assert forall k :: n <= k ==> Nexxxt(k, S) == null; // Dafny proves this thanks to its induction tactic
- }
-
- ghost method Lemma_NullImpliesNoCycles_part1(n: int, S: set<Node>)
- requires IsClosed(S) && 0 <= n && Nexxxt(n, S) == null;
- ensures forall k,l :: 0 <= k && n <= l && Nexxxt(k, S) != null && Nexxxt(k, S).next != null ==> Nexxxt(k, S).next.Nexxxt(l, S) != Nexxxt(k, S);
- {
- // Each of the following assertions makes use of Dafny's induction tactic
- assert forall k,l :: 0 <= k && 0 <= l && Nexxxt(k, S) != null && Nexxxt(k, S).next != null ==> Nexxxt(k, S).next.Nexxxt(l, S) == Nexxxt(k+1+l, S);
- assert forall kl :: n <= kl ==> Nexxxt(kl, S) == null;
- }
-
- ghost method Lemma_NullImpliesNoCycles_part2(n: int, S: set<Node>)
- requires IsClosed(S) && 0 <= n && Nexxxt(n, S) == null;
- ensures forall k,l :: 0 <= k < n && 0 <= l < n && Nexxxt(k, S) != null && Nexxxt(k, S).next != null ==> Nexxxt(k, S).next.Nexxxt(l, S) != Nexxxt(k, S);
- {
- var kn := 0;
- while (kn < n)
- invariant 0 <= kn <= n;
- invariant forall k,l :: 0 <= k < kn && 0 <= l < n && Nexxxt(k, S) != null && Nexxxt(k, S).next != null ==> Nexxxt(k, S).next.Nexxxt(l, S) != Nexxxt(k, S);
- {
- var ln := 0;
- while (ln < n)
- invariant 0 <= ln <= n;
- invariant forall k,l :: 0 <= k < kn && 0 <= l < n && Nexxxt(k, S) != null && Nexxxt(k, S).next != null ==> Nexxxt(k, S).next.Nexxxt(l, S) != Nexxxt(k, S);
- invariant forall l :: 0 <= l < ln && Nexxxt(kn, S) != null && Nexxxt(kn, S).next != null ==> Nexxxt(kn, S).next.Nexxxt(l, S) != Nexxxt(kn, S);
- {
- if (Nexxxt(kn, S) != null && Nexxxt(kn, S).next != null) {
- assert Nexxxt(kn+1, S) != null;
- Lemma_NexxxtIsTransitive(kn+1, ln, S);
- assert Nexxxt(kn, S).next.Nexxxt(ln, S) == Nexxxt(kn+1+ln, S); // follows from the transitivity lemma on the previous line
- Lemma_NexxxtIsTransitive(kn, 1+ln, S);
- assert Nexxxt(kn+1+ln, S) == Nexxxt(kn, S).Nexxxt(1+ln, S); // follows from the transitivity lemma on the previous line
- // finally, here comes the central part of the argument, namely:
- // if Nexxxt(kn, S).Nexxxt(1+ln, S) == Nexxxt(kn, S), then for any h (0 <= h), Nexxxt(kn, S).Nexxxt(h*(1+ln), S) == Nexxxt(kn, S), but
- // that can't be for n <= h*(1+ln), since Nexxxt(kn, S) != null and Nexxxt(n.., S) == null.
- if (Nexxxt(kn, S).Nexxxt(1+ln, S) == Nexxxt(kn, S)) {
- var nn := 1+ln;
- while (nn < n)
- invariant 0 <= nn;
- invariant Nexxxt(kn, S).Nexxxt(nn, S) == Nexxxt(kn, S);
- {
- assert Nexxxt(kn, S) ==
- Nexxxt(kn, S).Nexxxt(nn, S) ==
- Nexxxt(kn, S).Nexxxt(1+ln, S) ==
- Nexxxt(kn, S).Nexxxt(nn, S).Nexxxt(1+ln, S);
- Nexxxt(kn, S).Lemma_NexxxtIsTransitive(1+ln, nn, S);
- assert Nexxxt(kn, S).Nexxxt(nn+1+ln, S) == Nexxxt(kn, S);
- nn := nn + 1+ln;
- }
- Lemma_NexxxtIsTransitive(kn, nn, S);
- assert Nexxxt(kn, S).Nexxxt(nn, S) == Nexxxt(kn+nn, S);
- assert forall j :: n <= j ==> Nexxxt(j, S) == null; // this uses Dafny's induction tactic
- assert false; // we have reached a contradiction
- }
- assert Nexxxt(kn+1, S).Nexxxt(ln, S) != Nexxxt(kn, S);
- }
- ln := ln + 1;
- }
- kn := kn + 1;
- }
- }
-}
diff --git a/Test/dafny2/Calculations.dfy b/Test/dafny2/Calculations.dfy
deleted file mode 100644
index 8c13457b..00000000
--- a/Test/dafny2/Calculations.dfy
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Lists */
-// Here are some standard definitions of List and functions on Lists
-
-datatype List<T> = Nil | Cons(T, List);
-
-function length(l: List): nat
-{
- match l
- case Nil => 0
- case Cons(x, xs) => 1 + length(xs)
-}
-
-function concat(l: List, ys: List): List
-{
- match l
- case Nil => ys
- case Cons(x, xs) => Cons(x, concat(xs, ys))
-}
-
-function reverse(l: List): List
-{
- match l
- case Nil => Nil
- case Cons(x, xs) => concat(reverse(xs), Cons(x, Nil))
-}
-
-function revacc(l: List, acc: List): List
-{
- match l
- case Nil => acc
- case Cons(x, xs) => revacc(xs, Cons(x, acc))
-}
-
-function qreverse(l: List): List
-{
- revacc(l, Nil)
-}
-
-// Here are two lemmas about the List functions.
-
-ghost method Lemma_ConcatNil()
- ensures forall xs :: concat(xs, Nil) == xs;
-{
-}
-
-ghost method Lemma_RevCatCommute()
- ensures forall xs, ys, zs :: revacc(xs, concat(ys, zs)) == concat(revacc(xs, ys), zs);
-{
-}
-
-// Here is a theorem that says "qreverse" and "reverse" calculate the same result. The proof
-// is given in a calculational style. The proof is not minimal--some lines can be omitted
-// and Dafny will still fill in the details.
-
-ghost method Theorem_QReverseIsCorrect_Calc(l: List)
- ensures qreverse(l) == reverse(l);
-{
- calc {
- qreverse(l);
- // def. qreverse
- revacc(l, Nil);
- { Lemma_Revacc_calc(l, Nil); }
- concat(reverse(l), Nil);
- { Lemma_ConcatNil(); }
- reverse(l);
- }
-}
-
-ghost method Lemma_Revacc_calc(xs: List, ys: List)
- ensures revacc(xs, ys) == concat(reverse(xs), ys);
-{
- match (xs) {
- case Nil =>
- case Cons(x, xrest) =>
- calc {
- concat(reverse(xs), ys);
- // def. reverse
- concat(concat(reverse(xrest), Cons(x, Nil)), ys);
- // induction hypothesis: Lemma_Revacc_calc(xrest, Cons(x, Nil))
- concat(revacc(xrest, Cons(x, Nil)), ys);
- { Lemma_RevCatCommute(); } // forall xs,ys,zs :: revacc(xs, concat(ys, zs)) == concat(revacc(xs, ys), zs)
- revacc(xrest, concat(Cons(x, Nil), ys));
- // def. concat (x2)
- revacc(xrest, Cons(x, ys));
- // def. revacc
- revacc(xs, ys);
- }
- }
-}
-
-// Here is a version of the same proof, as it was constructed before Dafny's "calc" construct.
-
-ghost method Theorem_QReverseIsCorrect(l: List)
- ensures qreverse(l) == reverse(l);
-{
- assert qreverse(l)
- == // def. qreverse
- revacc(l, Nil);
- Lemma_Revacc(l, Nil);
- assert revacc(l, Nil)
- == concat(reverse(l), Nil);
- Lemma_ConcatNil();
-}
-
-ghost method Lemma_Revacc(xs: List, ys: List)
- ensures revacc(xs, ys) == concat(reverse(xs), ys);
-{
- match (xs) {
- case Nil =>
- case Cons(x, xrest) =>
- assert revacc(xs, ys)
- == // def. revacc
- revacc(xrest, Cons(x, ys));
-
- assert concat(reverse(xs), ys)
- == // def. reverse
- concat(concat(reverse(xrest), Cons(x, Nil)), ys)
- == // induction hypothesis: Lemma3a(xrest, Cons(x, Nil))
- concat(revacc(xrest, Cons(x, Nil)), ys);
- Lemma_RevCatCommute(); // forall xs,ys,zs :: revacc(xs, concat(ys, zs)) == concat(revacc(xs, ys), zs)
- assert concat(revacc(xrest, Cons(x, Nil)), ys)
- == revacc(xrest, concat(Cons(x, Nil), ys));
-
- assert forall g, gs :: concat(Cons(g, Nil), gs) == Cons(g, gs);
-
- assert revacc(xrest, concat(Cons(x, Nil), ys))
- == // the assert lemma just above
- revacc(xrest, Cons(x, ys));
- }
-}
-
-/* Fibonacci */
-// To further demonstrate what the "calc" construct can do, here are some proofs about the Fibonacci function.
-
-function Fib(n: nat): nat
-{
- if n < 2 then n else Fib(n - 2) + Fib(n - 1)
-}
-
-ghost method Lemma_Fib()
- ensures Fib(5) < 6;
-{
- calc {
- Fib(5);
- Fib(4) + Fib(3);
- calc {
- Fib(2);
- Fib(0) + Fib(1);
- 0 + 1;
- 1;
- }
- < 6;
- }
-}
-
-/* List length */
-// Here are some proofs that show the use of nested calculations.
-
-ghost method Lemma_Concat_Length(xs: List, ys: List)
- ensures length(concat(xs, ys)) == length(xs) + length(ys);
-{}
-
-ghost method Lemma_Reverse_Length(xs: List)
- ensures length(xs) == length(reverse(xs));
-{
- match (xs) {
- case Nil =>
- case Cons(x, xrest) =>
- calc {
- length(reverse(xs));
- // def. reverse
- length(concat(reverse(xrest), Cons(x, Nil)));
- { Lemma_Concat_Length(reverse(xrest), Cons(x, Nil)); }
- length(reverse(xrest)) + length(Cons(x, Nil));
- // induction hypothesis
- length(xrest) + length(Cons(x, Nil));
- calc {
- length(Cons(x, Nil));
- // def. length
- 1 + length(Nil);
- // def. length
- 1 + 0;
- 1;
- }
- length(xrest) + 1;
- // def. length
- length(xs);
- }
- }
-}
-
-ghost method Window(xs: List, ys: List)
- ensures length(xs) == length(ys) ==> length(reverse(xs)) == length(reverse(ys));
-{
- calc {
- length(xs) == length(ys) ==> length(reverse(xs)) == length(reverse(ys));
- { if (length(xs) == length(ys)) {
- calc {
- length(reverse(xs));
- { Lemma_Reverse_Length(xs); }
- length(xs);
- length(ys);
- { Lemma_Reverse_Length(ys); }
- length(reverse(ys));
- } } }
- length(xs) == length(ys) ==> length(reverse(xs)) == length(reverse(xs));
- true;
- }
-} \ No newline at end of file
diff --git a/Test/dafny2/Classics.dfy b/Test/dafny2/Classics.dfy
deleted file mode 100644
index 68d9bf79..00000000
--- a/Test/dafny2/Classics.dfy
+++ /dev/null
@@ -1,103 +0,0 @@
-// A version of Turing's additive factorial program [Dr. A. Turing, "Checking a large routine",
-// In "Report of a Conference of High Speed Automatic Calculating Machines", pp. 67-69, 1949].
-
-function Factorial(n: nat): nat
-{
- if n == 0 then 1 else n * Factorial(n-1)
-}
-
-method AdditiveFactorial(n: nat) returns (u: nat)
- ensures u == Factorial(n);
-{
- u := 1;
- var r := 0;
- while (r < n)
- invariant 0 <= r <= n;
- invariant u == Factorial(r);
- {
- var v := u;
- var s := 1;
- while (s <= r)
- invariant 1 <= s <= r+1;
- invariant u == s * Factorial(r);
- {
- u := u + v;
- s := s + 1;
- }
- r := r + 1;
- }
-}
-
-// Hoare's FIND program [C.A.R. Hoare, "Proof of a program: FIND", CACM 14(1): 39-45, 1971].
-// The proof annotations here are not the same as in Hoare's article.
-
-// In Hoare's words:
-// This program operates on an array A[1:N], and a value of f (1 <= f <= N).
-// Its effect is to rearrange the elements of A in such a way that:
-// forall p,q (1 <= p <= f <= q <= N ==> A[p] <= A[f] <= A[q]).
-//
-// Here, we use 0-based indices, so we would say:
-// This method operates on an array A[0..N], and a value of f (0 <= f < N).
-// Its effect is to rearrange the elements of A in such a way that:
-// forall p,q :: 0 <= p <= f <= q < N ==> A[p] <= A[f] <= A[q]).
-
-method FIND(A: array<int>, N: int, f: int)
- requires A != null && A.Length == N;
- requires 0 <= f < N;
- modifies A;
- ensures forall p,q :: 0 <= p <= f <= q < N ==> A[p] <= A[q];
-{
- var m, n := 0, N-1;
- while (m < n)
- invariant 0 <= m <= f <= n < N;
- invariant forall p,q :: 0 <= p < m <= q < N ==> A[p] <= A[q];
- invariant forall p,q :: 0 <= p <= n < q < N ==> A[p] <= A[q];
- {
- var r, i, j := A[f], m, n;
- while (i <= j)
- invariant m <= i && j <= n;
- invariant -1 <= j && i <= N;
- invariant i <= j ==> exists g :: i <= g < N && r <= A[g];
- invariant i <= j ==> exists g :: 0 <= g <= j && A[g] <= r;
- invariant forall p :: 0 <= p < i ==> A[p] <= r;
- invariant forall q :: j < q < N ==> r <= A[q];
- // the following two invariants capture (and follow from) the fact that the array is not modified outside the [m:n] range
- invariant forall p,q :: 0 <= p < m <= q < N ==> A[p] <= A[q];
- invariant forall p,q :: 0 <= p <= n < q < N ==> A[p] <= A[q];
- // the following invariant is used to prove progress of the outer loop
- invariant (i==m && j==n && r==A[f]) || (m<i && j<n);
- {
- ghost var firstIteration := i==m && j==n;
- while (A[i] < r)
- invariant m <= i <= N && (firstIteration ==> i <= f);
- invariant exists g :: i <= g < N && r <= A[g];
- invariant exists g :: 0 <= g <= j && A[g] <= r;
- invariant forall p :: 0 <= p < i ==> A[p] <= r;
- decreases j - i;
- { i := i + 1; }
-
- while (r < A[j])
- invariant 0 <= j <= n && (firstIteration ==> f <= j);
- invariant exists g :: i <= g < N && r <= A[g];
- invariant exists g :: 0 <= g <= j && A[g] <= r;
- invariant forall q :: j < q < N ==> r <= A[q];
- decreases j;
- { j := j - 1; }
-
- assert A[j] <= r <= A[i];
- if (i <= j) {
- var w := A[i]; A[i] := A[j]; A[j] := w; // swap A[i] and A[j] (which may be referring to the same location)
- assert A[i] <= r <= A[j];
- i, j := i + 1, j - 1;
- }
- }
-
- if (f <= j) {
- n := j;
- } else if (i <= f) {
- m := i;
- } else {
- break; // Hoare used a goto
- }
- }
-}
diff --git a/Test/dafny2/Intervals.dfy b/Test/dafny2/Intervals.dfy
deleted file mode 100644
index f04f6411..00000000
--- a/Test/dafny2/Intervals.dfy
+++ /dev/null
@@ -1,63 +0,0 @@
-// The RoundDown and RoundUp methods in this file are the ones in the Boogie
-// implementation Source/AbsInt/IntervalDomain.cs.
-
-var thresholds: array<int>;
-
-function Valid(): bool
- reads this, thresholds;
-{
- thresholds != null &&
- forall m,n :: 0 <= m < n < thresholds.Length ==> thresholds[m] <= thresholds[n]
-}
-
-method RoundDown(k: int) returns (r: int)
- requires Valid();
- ensures -1 <= r < thresholds.Length;
- ensures forall m :: r < m < thresholds.Length ==> k < thresholds[m];
- ensures 0 <= r ==> thresholds[r] <= k;
-{
- if (thresholds.Length == 0 || k < thresholds[0]) {
- return -1;
- }
- var i, j := 0, thresholds.Length - 1;
- while (i < j)
- invariant 0 <= i <= j < thresholds.Length;
- invariant thresholds[i] <= k;
- invariant forall m :: j < m < thresholds.Length ==> k < thresholds[m];
- {
- var mid := i + (j - i + 1) / 2;
- assert i < mid <= j;
- if (thresholds[mid] <= k) {
- i := mid;
- } else {
- j := mid - 1;
- }
- }
- return i;
-}
-
-method RoundUp(k: int) returns (r: int)
- requires Valid();
- ensures 0 <= r <= thresholds.Length;
- ensures forall m :: 0 <= m < r ==> thresholds[m] < k;
- ensures r < thresholds.Length ==> k <= thresholds[r];
-{
- if (thresholds.Length == 0 || thresholds[thresholds.Length-1] < k) {
- return thresholds.Length;
- }
- var i, j := 0, thresholds.Length - 1;
- while (i < j)
- invariant 0 <= i <= j < thresholds.Length;
- invariant k <= thresholds[j];
- invariant forall m :: 0 <= m < i ==> thresholds[m] < k;
- {
- var mid := i + (j - i) / 2;
- assert i <= mid < j;
- if (thresholds[mid] < k) {
- i := mid + 1;
- } else {
- j := mid;
- }
- }
- return i;
-}
diff --git a/Test/dafny2/MajorityVote.dfy b/Test/dafny2/MajorityVote.dfy
deleted file mode 100644
index af67ee92..00000000
--- a/Test/dafny2/MajorityVote.dfy
+++ /dev/null
@@ -1,175 +0,0 @@
-// Rustan Leino, June 2012.
-// This file verifies an algorithm, due to Boyer and Moore, that finds the majority choice
-// among a sequence of votes, see http://www.cs.utexas.edu/~moore/best-ideas/mjrty/.
-// Actually, this algorithm is a slight variation on theirs, but the general idea for why
-// it is correct is the same. In the Boyer and Moore algorithm, the loop counter is advanced
-// by exactly 1 each iteration, which means that there may or may not be a "current leader".
-// In my program below, I had instead written the loop invariant to say there is always a
-// "current leader", which requires the loop index sometimes to skip a value.
-//
-// This file has two versions of the algorithm. In the first version, the given sequence
-// of votes is assumed to have a (strict) majority choice, meaning that strictly more than
-// 50% of the votes are for one candidate. It is convenient to have a name for the majority
-// choice, in order to talk about it in specifications. The easiest way to do this in
-// Dafny is probably to introduce a ghost parameter with the given properties. That's what
-// the algorithm does, see parameter K. The postcondition is thus to output the value of
-// K, which is done in the non-ghost out-parameter k.
-// The proof of the algorithm requires two lemmas. These lemmas are proved automatically
-// by Dafny's induction tactic.
-//
-// In the second version of the program, the main method does not assume there is a majority
-// choice. Rather, it eseentially uses the first algorithm and then checks if what it
-// returns really is a majority choice. To do this, the specification of the first algorithm
-// needs to be changed slightly to accommodate the possibility that there is no majority
-// choice. That change in specification is also reflected in the loop invariant. Moreover,
-// the algorithm itself now needs to extra 'if' statements to see if the entire sequence
-// has been searched through. (This extra 'if' is essentially already handled by Boyer and
-// Moore's algorithm, because it increments the loop index by 1 each iteration and therefore
-// already has a special case for the case of running out of sequence elements without a
-// current leader.)
-// The calling harness, DetermineElection, somewhat existentially comes up with the majority
-// choice, if there is such a choice, and then passes in that choice as the ghost parameter K
-// to the main algorithm. Neat, huh?
-
-// Language comment:
-// The "(==)" that sits after some type parameters in this program says that the actual
-// type argument must support equality.
-
-// Advanced remark:
-// There is a subtle situation in the verification of DetermineElection. Suppose the type
-// parameter Candidate denotes some type whose instances depend on which object are
-// allocated. For example, if Candidate is some class type, then more candidates can come
-// into being by object allocations (using "new"). What does the quantification of
-// candidates "c" in the postcondition of DetermineElection now mean--all candidates that
-// existed in the pre-state or (the possibly larger set of) all candidates that exist in the
-// post-state? (It means the latter.) And if there does not exist a candidate in majority
-// in the pre-state, could there be a (newly created) candidate in majority in the post-state?
-// This will require some proof. The simplest argument seems to be that even if more candidates
-// are created during the course of DetermineElection, such candidates cannot possibly
-// be in majority in the sequence "a", since "a" can only contain candidates that were already
-// created in the pre-state. This property is easily specified by adding a postcondition
-// to the Count function. Alternatively, one could have added the antecedent "c in a" or
-// "old(allocated(c))" to the "forall c" quantification in the postcondition of DetermineElection.
-
-function method Count<T(==)>(a: seq<T>, s: int, t: int, x: T): int
- requires 0 <= s <= t <= |a|;
- ensures Count(a, s, t, x) == 0 || x in a;
-{
- if s == t then 0 else
- Count(a, s, t-1, x) + if a[t-1] == x then 1 else 0
-}
-
-// Here is the first version of the algorithm, the one that assumes there is a majority choice.
-
-method FindWinner<Candidate(==)>(a: seq<Candidate>, ghost K: Candidate) returns (k: Candidate)
- requires 2 * Count(a, 0, |a|, K) > |a|; // K has a (strict) majority of the votes
- ensures k == K; // find K
-{
- k := a[0];
- var n, c, s := 1, 1, 0;
- while (n < |a|)
- invariant 0 <= s <= n <= |a|;
- invariant 2 * Count(a, s, |a|, K) > |a| - s; // K has majority among a[s..]
- invariant 2 * Count(a, s, n, k) > n - s; // k has majority among a[s..n]
- invariant c == Count(a, s, n, k);
- {
- if (a[n] == k) {
- n, c := n + 1, c + 1;
- } else if (2 * c > n + 1 - s) {
- n := n + 1;
- } else {
- n := n + 1;
- // We have 2*Count(a, s, n, k) == n-s, and thus the following lemma
- // lets us conclude 2*Count(a, s, n, K) <= n-s.
- Lemma_Unique(a, s, n, K, k);
- // We also have 2*Count(a, s, |a|, K) > |a|-s, and the following lemma
- // tells us Count(a, s, |a|, K) == Count(a, s, n, K) + Count(a, n, |a|, K),
- // and thus we can conclude 2*Count(a, n, |a|, K) > |a|-n.
- Lemma_Split(a, s, n, |a|, K);
- k, n, c, s := a[n], n + 1, 1, n;
- }
- }
- Lemma_Unique(a, s, |a|, K, k); // both k and K have a majority, so K == k
-}
-
-// ------------------------------------------------------------------------------
-
-// Here is the second version of the program, the one that also computes whether or not
-// there is a majority choice.
-
-method DetermineElection<Candidate(==)>(a: seq<Candidate>) returns (hasWinner: bool, cand: Candidate)
- ensures hasWinner ==> 2 * Count(a, 0, |a|, cand) > |a|;
- ensures !hasWinner ==> forall c :: 2 * Count(a, 0, |a|, c) <= |a|;
-{
- ghost var b := exists c :: 2 * Count(a, 0, |a|, c) > |a|;
- ghost var w :| b ==> 2 * Count(a, 0, |a|, w) > |a|;
- cand := SearchForWinner(a, b, w);
- return 2 * Count(a, 0, |a|, cand) > |a|, cand;
-}
-
-// The difference between SearchForWinner for FindWinner above are the occurrences of the
-// antecedent "hasWinner ==>" and the two checks for no-more-votes that may result in a "return"
-// statement.
-
-method SearchForWinner<Candidate(==)>(a: seq<Candidate>, ghost hasWinner: bool, ghost K: Candidate) returns (k: Candidate)
- requires hasWinner ==> 2 * Count(a, 0, |a|, K) > |a|; // K has a (strict) majority of the votes
- ensures hasWinner ==> k == K; // find K
-{
- if (|a| == 0) { return; }
- k := a[0];
- var n, c, s := 1, 1, 0;
- while (n < |a|)
- invariant 0 <= s <= n <= |a|;
- invariant hasWinner ==> 2 * Count(a, s, |a|, K) > |a| - s; // K has majority among a[s..]
- invariant 2 * Count(a, s, n, k) > n - s; // k has majority among a[s..n]
- invariant c == Count(a, s, n, k);
- {
- if (a[n] == k) {
- n, c := n + 1, c + 1;
- } else if (2 * c > n + 1 - s) {
- n := n + 1;
- } else {
- n := n + 1;
- // We have 2*Count(a, s, n, k) == n-s, and thus the following lemma
- // lets us conclude 2*Count(a, s, n, K) <= n-s.
- Lemma_Unique(a, s, n, K, k);
- // We also have 2*Count(a, s, |a|, K) > |a|-s, and the following lemma
- // tells us Count(a, s, |a|, K) == Count(a, s, n, K) + Count(a, n, |a|, K),
- // and thus we can conclude 2*Count(a, n, |a|, K) > |a|-n.
- Lemma_Split(a, s, n, |a|, K);
- if (|a| == n) { return; }
- k, n, c, s := a[n], n + 1, 1, n;
- }
- }
- Lemma_Unique(a, s, |a|, K, k); // both k and K have a majority, so K == k
-}
-
-// ------------------------------------------------------------------------------
-
-// Here are two lemmas about Count that are used in the methods above.
-
-ghost method Lemma_Split<T>(a: seq<T>, s: int, t: int, u: int, x: T)
- requires 0 <= s <= t <= u <= |a|;
- ensures Count(a, s, t, x) + Count(a, t, u, x) == Count(a, s, u, x);
-{
- /* The postcondition of this method is proved automatically via Dafny's
- induction tactic. But if a manual proof had to be provided, it would
- look like this:
- if (s != t) {
- Lemma_Split(a, s, t-1, u, x);
- }
- */
-}
-
-ghost method Lemma_Unique<T>(a: seq<T>, s: int, t: int, x: T, y: T)
- requires 0 <= s <= t <= |a|;
- ensures x != y ==> Count(a, s, t, x) + Count(a, s, t, y) <= t - s;
-{
- /* The postcondition of this method is proved automatically via Dafny's
- induction tactic. But if a manual proof had to be provided, it would
- look like this:
- if (s != t) {
- Lemma_Unique(a, s, t-1, x, y);
- }
- */
-}
diff --git a/Test/dafny2/MonotonicHeapstate.dfy b/Test/dafny2/MonotonicHeapstate.dfy
deleted file mode 100644
index 4844086e..00000000
--- a/Test/dafny2/MonotonicHeapstate.dfy
+++ /dev/null
@@ -1,143 +0,0 @@
-module M0 {
- datatype Kind = Constant | Ident | Binary;
-
- class Expr {
- var kind: Kind;
- var value: int; // value if kind==Constant; id if kind==VarDecl; operator if kind==Binary
- var left: Expr; // if kind==Binary
- var right: Expr; // if kind==Binary
-
- ghost var Repr: set<object>;
-
- predicate Valid()
- reads this, Repr;
- {
- this in Repr && null !in Repr &&
- (left != null ==> left in Repr && this !in left.Repr && right !in left.Repr && left.Repr <= Repr && left.Valid()) &&
- (right != null ==> right in Repr && this !in right.Repr && left !in right.Repr && right.Repr <= Repr && right.Valid()) &&
- (kind == Binary ==> left != null && right != null && left.Repr !! right.Repr)
- }
-
- constructor CreateConstant(x: int)
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- {
- kind, value := Constant, x;
- left, right := null, null;
- Repr := {this};
- }
-
- constructor CreateIdent(name: int)
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- {
- kind, value := Ident, name;
- left, right := null, null;
- Repr := {this};
- }
-
- constructor CreateBinary(op: int, left: Expr, right: Expr)
- requires left != null && left.Valid() && this !in left.Repr;
- requires right != null && right.Valid() && this !in right.Repr;
- requires left.Repr !! right.Repr;
- modifies this;
- ensures Valid() && fresh(Repr - {this} - left.Repr - right.Repr);
- {
- kind, value := Binary, op;
- this.left, this.right := left, right;
- Repr := {this} + left.Repr + right.Repr;
- }
- }
-}
-
-// Introduce the idea of resolved
-module M1 refines M0 {
- class Expr {
- ghost var resolved: bool;
-
- predicate Valid()
- {
- resolved ==>
- (kind == Binary ==> left.resolved && right.resolved)
- }
-
- constructor CreateConstant...
- {
- resolved := false;
- }
-
- constructor CreateIdent...
- {
- resolved := false;
- }
-
- constructor CreateBinary...
- {
- resolved := false;
- }
-
- method Resolve()
- requires Valid(); // it's okay if it's already resolved
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures resolved;
- decreases Repr;
- {
- if (kind == Binary) {
- left.Resolve();
- right.Resolve();
- }
- Repr := Repr + (if left != null then left.Repr else {}) + (if right != null then right.Repr else {});
- resolved := true;
- }
- }
-}
-
-// Give "resolved" some meaning
-module M2 refines M1 {
- class VarDecl {
- }
-
- class Expr {
- var decl: VarDecl; // if kind==Ident, filled in during resolution
-
- predicate Valid()
- {
- resolved ==>
- (kind == Ident ==> decl != null)
- }
-
- method Resolve...
- {
- if (kind == Ident) {
- decl := new VarDecl;
- }
- }
- }
-}
-
-// Finally, supposing each VarDecl has a value, evaluate a resolved expression
-module M3 refines M2 {
- class VarDecl {
- var val: int;
- }
-
- class Expr {
- method Eval() returns (r: int)
- requires Valid();
- requires resolved;
- decreases Repr;
- {
- match (kind) {
- case Constant =>
- r := value;
- case Ident =>
- r := decl.val; // note how this statement relies on "decl" being non-null, which follows from the expression being resolved
- case Binary =>
- var x := left.Eval();
- var y := right.Eval();
- r := x + y;
- }
- }
- }
-}
diff --git a/Test/dafny2/SegmentSum.dfy b/Test/dafny2/SegmentSum.dfy
deleted file mode 100644
index dc67162b..00000000
--- a/Test/dafny2/SegmentSum.dfy
+++ /dev/null
@@ -1,29 +0,0 @@
-function Sum(a: seq<int>, s: int, t: int): int
- requires 0 <= s <= t <= |a|;
-{
- if s == t then 0 else Sum(a, s, t-1) + a[t-1]
-}
-
-method MaxSegSum(a: seq<int>) returns (k: int, m: int)
- ensures 0 <= k <= m <= |a|;
- ensures forall p,q :: 0 <= p <= q <= |a| ==> Sum(a, p, q) <= Sum(a, k, m);
-{
- k, m := 0, 0;
- var s := 0; // invariant s == Sum(a, k, m)
- var n := 0;
- var c, t := 0, 0; // invariant t == Sum(a, c, n)
- while (n < |a|)
- invariant n <= |a|;
- invariant 0 <= c <= n && t == Sum(a, c, n);
- invariant forall b :: 0 <= b <= n ==> Sum(a, b, n) <= Sum(a, c, n);
- invariant 0 <= k <= m <= n && s == Sum(a, k, m);
- invariant forall p,q :: 0 <= p <= q <= n ==> Sum(a, p, q) <= Sum(a, k, m);
- {
- t, n := t + a[n], n + 1;
- if (t < 0) {
- c, t := n, 0;
- } else if (s < t) {
- k, m, s := c, n, t;
- }
- }
-}
diff --git a/Test/dafny2/SnapshotableTrees.dfy b/Test/dafny2/SnapshotableTrees.dfy
deleted file mode 100644
index 2c7a91df..00000000
--- a/Test/dafny2/SnapshotableTrees.dfy
+++ /dev/null
@@ -1,480 +0,0 @@
-// Rustan Leino, September 2011.
-// This file contains a version of the C5 library's snapshotable trees. A different verification
-// of a version like this has been done by Hannes Mehnert, Filip Sieczkowski, Lars Birkedal, and
-// Peter Sestoft in separation logic using Coq.
-
-method Main()
-{
- var t := new Tree.Empty();
- ghost var pos := t.Insert(2);
- pos := t.Insert(1);
- pos := t.Insert(3);
- pos := t.Insert(-15);
- pos := t.Insert(0);
-
- var s := t.CreateSnapshot();
- ghost var sc := s.Contents;
- var it := s.CreateIterator();
- var more := it.MoveNext();
- while (more)
- invariant t.Valid() && !t.IsReadonly && it.Valid();
- invariant more ==> 0 <= it.N < |it.Contents|;
- invariant fresh(t.Repr) && fresh(it.IterRepr) && t.MutableRepr !! it.T.Repr && t.Repr !! it.IterRepr;
- invariant it.T == s && s.Valid() && s.Contents == sc; // this is not needed in the loop, but serves as an extra test case of the specifications
- decreases |it.Contents| - it.N;
- {
- var x := it.Current();
- print "Main iterates on ", x, "\n";
- pos := t.Insert(x*3);
- more := it.MoveNext();
- }
- assert s.Contents == sc; // this is not needed in the loop, but serves as an extra test case of the specifications
- t.Print();
-}
-
-method TestContents() // this method tests Tree.Insert's specifications of Contents
-{
- var t := new Tree.Empty(); assert t.Contents == [];
- ghost var pos := t.Insert(2); assert pos == 0 && t.Contents == [2];
-
- pos := t.Insert(1);
- // Convince the verifier of the absurdity of pos==1
- assert pos == 1 ==> t.Contents == [2,1];
- ghost var hc := [2,1];
- assert hc[0] == 2 && hc[1] == 1 && !Tree.IsSorted(hc);
- // So:
- assert pos == 0 && t.Contents == [1, 2];
-}
-
-class Tree
-{
- // public
- ghost var Contents: seq<int>;
- var IsReadonly: bool;
- ghost var Repr: set<object>;
- ghost var MutableRepr: set<object>;
- // private
- var root: Node;
- var reprIsShared: bool;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in MutableRepr && MutableRepr <= Repr && null !in Repr &&
- (root == null ==> Contents == []) &&
- (root != null ==>
- root in Repr && root.Repr <= Repr && this !in root.Repr &&
- root.Valid() && Contents == root.Contents) &&
- IsSorted(Contents) &&
- (IsReadonly ==> reprIsShared) &&
- (!reprIsShared && root != null ==> root.Repr <= MutableRepr) &&
- (reprIsShared ==> MutableRepr == {this})
- }
-
- static function IsSorted(c: seq<int>): bool // checks if "c" is sorted and has no duplicates
- {
- forall i, j :: 0 <= i < j < |c| ==> c[i] < c[j]
- }
-
- constructor Empty()
- modifies this;
- ensures Valid() && Contents == [] && !IsReadonly;
- ensures fresh(Repr - {this});
- {
- Contents := [];
- IsReadonly := false;
- MutableRepr := {this};
- Repr := MutableRepr;
- root := null;
- reprIsShared := false;
- }
-
- method CreateSnapshot() returns (snapshot: Tree)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents) && IsReadonly == old(IsReadonly);
- ensures snapshot != null && snapshot.Valid();
- ensures snapshot.Contents == Contents && snapshot.IsReadonly;
- // the mutable part of the original tree is disjoint from the representation of the snapshot
- ensures snapshot.Repr !! MutableRepr;
- // representation of the snapshot consists of new things of things from the previous tree (that are now immutable)
- ensures fresh(snapshot.Repr - old(Repr));
- {
- // from now on, only "this" is mutable; the rest of the representation is immutable
- Repr := Repr + MutableRepr;
- MutableRepr := {this};
- reprIsShared := true;
- snapshot := new Tree.Private();
- snapshot.Contents := Contents;
- snapshot.IsReadonly := true;
- snapshot.MutableRepr := {snapshot};
- snapshot.Repr := Repr - {this} + {snapshot};
- snapshot.root := root;
- snapshot.reprIsShared := true;
- }
-
- // private
- constructor Private() { }
-
- method Insert(x: int) returns (ghost pos: int)
- requires Valid() && !IsReadonly;
- modifies MutableRepr;
- ensures Valid() && fresh(Repr - old(Repr)) && fresh(MutableRepr - old(MutableRepr));
- ensures IsReadonly == old(IsReadonly);
- ensures x in old(Contents) ==> pos < 0 && Contents == old(Contents);
- ensures x !in old(Contents) ==>
- 0 <= pos < |Contents| == |old(Contents)| + 1 &&
- Contents == old(Contents[..pos] + [x] + Contents[pos..]);
- {
- if (reprIsShared) {
- root, pos := Node.FunctionalInsert(root, x);
- Contents := root.Contents;
- Repr := root.Repr + {this};
- MutableRepr := {this};
- } else if (root == null) {
- root := new Node.Init(x);
- Contents := root.Contents;
- pos := 0;
- MutableRepr := root.Repr + {this};
- Repr := MutableRepr;
- } else {
- pos := root.MutatingInsert(x);
- Contents := root.Contents;
- MutableRepr := MutableRepr + root.Repr;
- Repr := MutableRepr;
- }
- }
-
- method CreateIterator() returns (iter: Iterator)
- requires Valid(); // && IsReadonly;
- ensures iter != null && iter.Valid() && fresh(iter.IterRepr);
- ensures iter.T == this && iter.Contents == Contents && iter.N == -1;
- {
- iter := new Iterator.Init(this);
- }
-
- method Print()
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents) && IsReadonly == old(IsReadonly);
- {
- print "Tree:";
- var s := CreateSnapshot();
- var it := s.CreateIterator();
- var more := it.MoveNext();
- while (more)
- invariant Valid() && fresh(Repr - old(Repr)) && Contents == old(Contents) && IsReadonly == old(IsReadonly);
- invariant it.Valid();
- invariant more ==> 0 <= it.N < |it.Contents|;
- invariant fresh(it.IterRepr) && MutableRepr !! it.T.Repr && Repr !! it.IterRepr;
- decreases |it.Contents| - it.N;
- {
- var x := it.Current();
- print " ", x;
- more := it.MoveNext();
- }
- print "\n";
- }
-}
-
-class Node
-{
- ghost var Contents: seq<int>;
- ghost var Repr: set<object>;
- var data: int;
- var left: Node;
- var right: Node;
-
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr && null !in Repr &&
- (left != null ==>
- left in Repr && left.Repr <= Repr && this !in left.Repr && left.Valid()) &&
- (right != null ==>
- right in Repr && right.Repr <= Repr && this !in right.Repr && right.Valid()) &&
- (left == null && right == null ==> Contents == [data]) &&
- (left != null && right == null ==> Contents == left.Contents + [data]) &&
- (left == null && right != null ==> Contents == [data] + right.Contents) &&
- (left != null && right != null ==> Contents == left.Contents + [data] + right.Contents && left.Repr !! right.Repr) &&
- Tree.IsSorted(Contents)
- }
-
- constructor Init(x: int)
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- ensures Contents == [x];
- {
- Contents := [x];
- Repr := {this};
- left, data, right := null, x, null;
- }
-
- constructor Build(left: Node, x: int, right: Node)
- requires this != left && this != right;
- requires left != null ==> left.Valid() && this !in left.Repr &&
- forall i :: 0 <= i < |left.Contents| ==> left.Contents[i] < x;
- requires right != null ==> right.Valid() && this !in right.Repr &&
- forall i :: 0 <= i < |right.Contents| ==> x < right.Contents[i];
- requires left != null && right != null ==> left.Repr !! right.Repr;
- modifies this;
- ensures Valid();
- ensures left == null && right == null ==> Contents == [x] && fresh(Repr - {this});
- ensures left != null && right == null ==> Contents == left.Contents + [x] && fresh(Repr - {this} - left.Repr);
- ensures left == null && right != null ==> Contents == [x] + right.Contents && fresh(Repr - {this} - right.Repr);
- ensures left != null && right != null ==> Contents == left.Contents + [x] + right.Contents && fresh(Repr - {this} - left.Repr - right.Repr);
- {
- Contents := [x];
- Repr := {this};
- this.left, data, this.right := left, x, right;
- if (left != null) {
- Contents := left.Contents + Contents;
- Repr := Repr + left.Repr;
- }
- if (right != null) {
- Contents := Contents + right.Contents;
- Repr := Repr + right.Repr;
- }
- }
-
- static method FunctionalInsert(n: Node, x: int) returns (r: Node, ghost pos: int)
- requires n != null ==> n.Valid();
- ensures r != null && r.Valid();
- ensures n == null ==> fresh(r.Repr);
- ensures n != null ==> fresh(r.Repr - n.Repr);
- ensures n == null ==> r.Contents == [x] && pos == 0;
- ensures n != null && x in n.Contents ==> r == n && pos < 0;
- ensures n != null && x !in n.Contents ==>
- 0 <= pos < |r.Contents| == |n.Contents| + 1 &&
- r.Contents == n.Contents[..pos] + [x] + n.Contents[pos..];
- decreases if n == null then {} else n.Repr;
- {
- if (n == null) {
- r := new Node.Init(x);
- pos := 0;
- } else if (x < n.data) {
- var left;
- assert n.left != null ==> n.data == n.Contents[|n.left.Contents|];
- assert n.left == null ==> n.data == n.Contents[0];
- left, pos := FunctionalInsert(n.left, x);
- assert n.left == old(n.left);
- if (left == n.left) {
- r, pos := n, -1;
- } else {
- assert n.left != null ==> forall i :: 0 <= i < |n.left.Contents| ==> n.Contents[i] < n.data;
- assert forall i :: 0 <= i < |left.Contents| ==> left.Contents[i] < n.data;
- r := new Node.Build(left, n.data, n.right);
- }
- } else if (n.data < x) {
- var right;
- assert n.left != null ==> n.data == n.Contents[|n.left.Contents|];
- assert n.left == null ==> n.data == n.Contents[0];
- right, pos := FunctionalInsert(n.right, x);
- if (right == n.right) {
- assert n != null && x in n.Contents;
- r, pos := n, -1;
- } else {
- assert n.left != null ==> forall i :: 0 <= i < |n.left.Contents| ==> n.left.Contents[i] < n.data;
- assert forall i :: 0 <= i < |right.Contents| ==> n.data < right.Contents[i];
- r := new Node.Build(n.left, n.data, right);
- pos := pos + 1 + if n.left == null then 0 else |n.left.Contents|;
- assert n != null && x !in n.Contents ==> r.Contents == n.Contents[..pos] + [x] + n.Contents[pos..];
- }
- } else {
- r, pos := n, -1;
- }
- }
-
- method MutatingInsert(x: int) returns (ghost pos: int)
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures x in old(Contents) ==> pos < 0 && Contents == old(Contents);
- ensures x !in old(Contents) ==>
- 0 <= pos < |Contents| == |old(Contents)| + 1 &&
- Contents == old(Contents[..pos] + [x] + Contents[pos..]);
- decreases Repr;
- {
- assert data == Contents[if left==null then 0 else |left.Contents|];
- if (x < data) {
- assert right == null || x !in right.Contents;
- assert right != null ==> forall i :: 0 <= i < |right.Contents| ==> x < right.Contents[i];
- if (left == null) {
- left := new Node.Init(x);
- pos := 0;
- } else {
- assert forall i :: 0 <= i < |left.Contents| ==> left.Contents[i] < data;
- pos := left.MutatingInsert(x);
- assert Tree.IsSorted(left.Contents);
- assert right != null ==> Tree.IsSorted(right.Contents);
- assert forall i :: 0 <= i < |left.Contents| ==> left.Contents[i] < data;
- }
- Repr := Repr + left.Repr;
- Contents := left.Contents + [data] + if right == null then [] else right.Contents;
- assert Tree.IsSorted(Contents);
- } else if (data < x) {
- assert left == null || x !in left.Contents;
- assert left != null ==> forall i :: 0 <= i < |left.Contents| ==> left.Contents[i] < x;
- if (right == null) {
- right := new Node.Init(x);
- pos := 1 + if left == null then 0 else |left.Contents|;
- } else {
- assert forall i :: 0 <= i < |right.Contents| ==> data < right.Contents[i];
- pos := right.MutatingInsert(x);
- assert Tree.IsSorted(right.Contents);
- assert left != null ==> Tree.IsSorted(left.Contents);
- assert forall i :: 0 <= i < |right.Contents| ==> data < right.Contents[i];
- if (0 <= pos) {
- pos := pos + 1 + if left == null then 0 else |left.Contents|;
- assert (if left == null then [] else left.Contents) + [data] + right.Contents == old(Contents[..pos] + [x] + Contents[pos..]);
- }
- }
- Repr := Repr + right.Repr;
- Contents := (if left == null then [] else left.Contents) + [data] + right.Contents;
- assert Tree.IsSorted(Contents);
- } else {
- pos := -1;
- }
- }
-}
-
-class Iterator
-{
- // public
- ghost var IterRepr: set<object>; // note, IterRepr does not include T.Repr
- ghost var Contents: seq<int>;
- ghost var N: int;
- var T: Tree;
- // private
- var initialized: bool;
- var stack: List;
-
- function Valid(): bool
- reads this, IterRepr, T, T.Repr;
- {
- this in IterRepr && null !in IterRepr &&
- T != null && T.Valid() && IterRepr !! T.Repr &&
- Contents == T.Contents && -1 <= N <= |Contents| &&
- (initialized <==> 0 <= N) &&
- (N < 0 ==> R(stack, 0, Contents, T.Repr)) &&
- (0 <= N ==> R(stack, N, Contents, T.Repr))
- }
-
- // R(wlist, n, C, Nodes) says that C[n..] are data items yet to be processed.
- // In more detail, wlist is a stack of tree fragments, where the concatenation of the
- // "load" of each tree fragment (from the top of the stack downwards) equals
- // C[n..]. A tree fragment is either
- // * for Nil, the empty fragment
- // * for Cons(p, rest), fragment [p.data]+p.right.Contents
- // In each case, R(wlist,n,C,Nodes) implies that the fragment wlist proper is a prefix of C[n..].
- // Nodes is (an overapproximation of) the set of nodes read by R.
- static function R(wlist: List, n: int, C: seq<int>, Nodes: set<object>): bool
- reads Nodes;
- decreases wlist;
- {
- match wlist
- case Nil => n == |C|
- case Cons(p, rest) =>
- p != null && p in Nodes && p.Repr <= Nodes && p.Valid() &&
- 0 <= n < |C| && p.data == C[n] &&
- R(rest, n + 1 + if p.right==null then 0 else |p.right.Contents|, C, Nodes) &&
- p.Contents[if p.left==null then 0 else |p.left.Contents| ..] <= C[n..]
- }
-
- constructor Init(t: Tree)
- requires t != null && t.Valid() && this !in t.Repr;
- modifies this;
- ensures Valid() && fresh(IterRepr - {this});
- ensures T == t && Contents == t.Contents && N == -1;
- {
- T := t;
- IterRepr := {this};
- Contents := T.Contents;
- initialized, stack, N := false, Nil, -1;
- if (t.root != null) {
- stack := Push(stack, 0, t.root, Contents, T.Repr);
- }
- }
-
- // private
- static method Push(stIn: List, ghost n: int, p: Node, ghost C: seq<int>, ghost Nodes: set<object>) returns (st: List)
- requires p != null && p in Nodes && p.Repr <= Nodes && p.Valid();
- requires 0 <= n <= |C|;
- requires p.Contents <= C[n..];
- requires R(stIn, n + |p.Contents|, C, Nodes);
- ensures R(st, n, C, Nodes);
- decreases p.Contents;
- {
- st := Cons(p, stIn);
-
- assert p.data == p.Contents[if p.left == null then 0 else |p.left.Contents|]; // lemma
- if (p.left != null) {
- st := Push(st, n, p.left, C, Nodes);
- }
- }
-
- method Current() returns (x: int)
- requires Valid() && 0 <= N < |Contents|;
- ensures x == Contents[N];
- {
- match (stack) {
- case Cons(y, rest) => x := y.data;
- }
- }
-
- method MoveNext() returns (hasCurrent: bool)
- requires Valid() && N <= |Contents|;
- modifies IterRepr;
- ensures Valid() && fresh(IterRepr - old(IterRepr)) && T.Repr == old(T.Repr);
- ensures Contents == old(Contents) && T == old(T);
- ensures old(N) < |Contents| ==> N == old(N) + 1;
- ensures old(N) == |Contents| ==> N == old(N);
- ensures hasCurrent <==> 0 <= N < |Contents|;
- {
- if (!initialized) {
- initialized, N := true, 0;
- hasCurrent := stack != Nil;
- } else {
- match (stack) {
- case Nil =>
- hasCurrent := false;
- case Cons(p, rest) =>
- // lemmas:
- assert R(rest, N + 1 + if p.right==null then 0 else |p.right.Contents|, Contents, T.Repr);
- ghost var k := if p.left==null then 0 else |p.left.Contents|;
- assert p.Contents[k..] == [p.data] + p.Contents[k+1..];
- assert p.Contents[k+1..] <= Contents[N+1..];
-
- stack, N := rest, N+1;
-
- if (p.right != null) {
- stack := Push(stack, N, p.right, Contents, T.Repr);
- }
- hasCurrent := stack != Nil;
- }
- }
- match (stack) { case Nil => assert N == |Contents|; case Cons(p, rest) => assert N < |Contents|; } // lemma
- }
-}
-
-datatype List = Nil | Cons(Node, List);
-
-/* The following method shows the problem of concurrent modifications and shows that the
- * design of the snapshotable trees herein handle this correctly. That is, after inserting
- * into a tree that is being iterated, use of the associated iterator can no longer be
- * proved to be correct.
- *
-method TestConcurrentModification(t: Tree)
- requires t != null && t.Valid() && !t.IsReadonly;
- modifies t.MutableRepr;
-{
- var it := t.CreateIterator();
- var more := it.MoveNext();
- if (more) {
- var pos := t.Insert(52); // this modification of the collection renders all associated iterators invalid
- more := it.MoveNext(); // error: operation t.Insert may have made this iterator invalid
- }
-}
-*/
diff --git a/Test/dafny2/StoreAndRetrieve.dfy b/Test/dafny2/StoreAndRetrieve.dfy
deleted file mode 100644
index da62f91c..00000000
--- a/Test/dafny2/StoreAndRetrieve.dfy
+++ /dev/null
@@ -1,76 +0,0 @@
-ghost module A {
- import L = Library;
- class {:autocontracts} StoreAndRetrieve<Thing> {
- ghost var Contents: set<Thing>;
- predicate Valid
- {
- true
- }
- constructor Init()
- {
- Contents := {};
- }
- method Store(t: Thing)
- {
- Contents := Contents + {t};
- }
- method Retrieve(matchCriterion: L.Function) returns (thing: Thing)
- requires exists t :: t in Contents && L.Function.Apply(matchCriterion, t);
- ensures Contents == old(Contents);
- ensures thing in Contents && L.Function.Apply(matchCriterion, thing);
- {
- var k :| k in Contents && L.Function.Apply(matchCriterion, k);
- thing := k;
- }
- }
-}
-
-module B refines A {
- class StoreAndRetrieve<Thing> {
- var arr: seq<Thing>;
- predicate Valid
- {
- Contents == set x | x in arr
- }
- constructor Init()
- {
- arr := [];
- }
- method Store...
- {
- arr := arr + [t];
- }
- method Retrieve...
- {
- var i := 0;
- while (i < |arr|)
- invariant i < |arr|;
- invariant forall j :: 0 <= j < i ==> !L.Function.Apply(matchCriterion, arr[j]);
- {
- if (L.Function.Apply(matchCriterion, arr[i])) { break; }
- i := i + 1;
- }
- var k := arr[i];
- ...;
- var a :| Contents == set x | x in a;
- arr := a;
- }
- }
-}
-
-module C refines B {
- class StoreAndRetrieve<Thing> {
- method Retrieve...
- {
- ...;
- var a := [thing] + arr[..i] + arr[i+1..]; // LRU behavior
- }
- }
-}
-
-module Library {
- // This class simulates function parameters
- class Function {
- static function method Apply<T>(f: Function, t: T): bool
- }
-}
diff --git a/Test/dafny2/TreeBarrier.dfy b/Test/dafny2/TreeBarrier.dfy
deleted file mode 100644
index f4cc25d2..00000000
--- a/Test/dafny2/TreeBarrier.dfy
+++ /dev/null
@@ -1,143 +0,0 @@
-class Node {
- var left: Node;
- var right: Node;
- var parent: Node;
- var anc: set<Node>;
- var desc: set<Node>;
- var sense: bool;
- var pc: int;
-
-
- function validDown(): bool
- reads this, desc;
- {
- this !in desc &&
- null !in desc &&
- left != right && // not needed, but speeds up verification
-
- (right != null ==> right in desc && left !in right.desc) &&
-
- (left != null ==>
- left in desc &&
- (right != null ==> desc == {left,right} + left.desc + right.desc) &&
- (right == null ==> desc == {left} + left.desc) &&
- left.validDown()) &&
- (left == null ==>
- (right != null ==> desc == {right} + right.desc) &&
- (right == null ==> desc == {})) &&
-
- (right != null ==> right.validDown()) &&
-
- (blocked() ==> forall m :: m in desc ==> m.blocked()) &&
- (after() ==> forall m :: m in desc ==> m.blocked() || m.after())
-// (left != null && right != null ==> left.desc !! right.desc) // not needed
- }
-
-
-
-
- function validUp(): bool
- reads this, anc;
- {
- this !in anc &&
- null !in anc &&
- (parent != null ==> parent in anc && anc == { parent } + parent.anc && parent.validUp()) &&
- (parent == null ==> anc == {}) &&
- (after() ==> forall m :: m in anc ==> m.after())
- }
-
- function valid(): bool
- reads this, desc, anc;
- { validUp() && validDown() && desc !! anc }
-
- function before(): bool
- reads this;
- { !sense && pc <= 2 }
-
- function blocked(): bool
- reads this;
- { sense }
-
- function after(): bool
- reads this;
- { !sense && 3 <= pc }
-
-
- method barrier()
- requires valid();
- requires before();
- modifies this, left, right;
- {
-
-//A
- pc := 1;
- if(left != null) {
- while(!left.sense)
- modifies left;
- invariant validDown(); // this seems necessary to get the necessary unfolding of functions
- invariant valid();
- decreases *; // to by-pass termination checking for this loop
- {
- // this loop body is supposed to model what the "left" thread
- // might do to its node. This body models a transition from
- // "before" to "blocked" by setting sense to true. A transition
- // all the way to "after" is not permitted; this would require
- // a change of pc.
- // We assume that "left" preserves the validity of its subtree,
- // which means in particular that it goes to "blocked" only if
- // all its descendants are already blocked.
- left.sense := *;
- assume left.blocked() ==> forall m :: m in left.desc ==> m.blocked();
- }
- }
- if(right != null) {
- while(!right.sense)
- modifies right;
- invariant validDown(); // this seems necessary to get the necessary unfolding of functions
- invariant valid();
- decreases *; // to by-pass termination checking for this loop
- {
- // analogous to the previous loop
- right.sense := *;
- assume right.blocked() ==> forall m :: m in right.desc ==> m.blocked();
- }
- }
-
-//B
- pc := 2;
- if(parent != null) {
- sense := true;
- }
-//C
- pc := 3;
- while(sense)
- modifies this;
- invariant validUp(); // this seems necessary to get the necessary unfolding of functions
- invariant valid();
- invariant left == old(left);
- invariant right == old(right);
- invariant sense ==> parent != null;
- decreases *; // to by-pass termination checking for this loop
- {
- // this loop body is supposed to model what the "parent" thread
- // might do to its node. The body models a transition from
- // "blocked" to "after" by setting sense to false.
- // We assume that "parent" initiates this transition only
- // after it went to state "after" itself.
- sense := *;
- assume !sense ==> parent.after();
- }
-//D
- pc := 4;
- if(left != null) {
- left.sense := false;
- }
-//E
- pc := 5;
- if(right != null) {
- right.sense := false;
- }
-//F
- pc := 6;
- }
-}
diff --git a/Test/dafny2/TreeFill.dfy b/Test/dafny2/TreeFill.dfy
deleted file mode 100644
index f7e2cc89..00000000
--- a/Test/dafny2/TreeFill.dfy
+++ /dev/null
@@ -1,27 +0,0 @@
-datatype Tree<T> = Null | Node(Tree, T, Tree);
-
-function Contains<T>(t: Tree, v: T): bool
-{
- match t
- case Null => false
- case Node(left, x, right) => x == v || Contains(left, v) || Contains(right, v)
-}
-
-method Fill<T>(t: Tree, a: array<T>, start: int) returns (end: int)
- requires a != null && 0 <= start <= a.Length;
- modifies a;
- ensures start <= end <= a.Length;
- ensures forall i :: 0 <= i < start ==> a[i] == old(a[i]);
- ensures forall i :: start <= i < end ==> Contains(t, a[i]);
-{
- match (t) {
- case Null =>
- end := start;
- case Node(left, x, right) =>
- end := Fill(left, a, start);
- if (end < a.Length) {
- a[end] := x;
- end := Fill(right, a, end + 1);
- }
- }
-}
diff --git a/Test/dafny2/TuringFactorial.dfy b/Test/dafny2/TuringFactorial.dfy
deleted file mode 100644
index 585c998e..00000000
--- a/Test/dafny2/TuringFactorial.dfy
+++ /dev/null
@@ -1,26 +0,0 @@
-function Factorial(n: nat): nat
-{
- if n == 0 then 1 else n * Factorial(n-1)
-}
-
-method ComputeFactorial(n: int) returns (u: int)
- requires 1 <= n;
- ensures u == Factorial(n);
-{
- var r := 1;
- u := 1;
- while (r < n)
- invariant r <= n;
- invariant u == Factorial(r);
- {
- var v, s := u, 1;
- while (s < r + 1)
- invariant s <= r + 1;
- invariant v == Factorial(r) && u == s * Factorial(r);
- {
- u := u + v;
- s := s + 1;
- }
- r := r + 1;
- }
-}
diff --git a/Test/dafny2/runtest.bat b/Test/dafny2/runtest.bat
deleted file mode 100644
index 72959830..00000000
--- a/Test/dafny2/runtest.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-REM soon again: SnapshotableTrees.dfy
-for %%f in (
- Classics.dfy
- TreeBarrier.dfy
- COST-verif-comp-2011-1-MaxArray.dfy
- COST-verif-comp-2011-2-MaxTree-class.dfy
- COST-verif-comp-2011-2-MaxTree-datatype.dfy
- COST-verif-comp-2011-3-TwoDuplicates.dfy
- COST-verif-comp-2011-4-FloydCycleDetect.dfy
- StoreAndRetrieve.dfy
- Intervals.dfy TreeFill.dfy TuringFactorial.dfy
- MajorityVote.dfy SegmentSum.dfy
- MonotonicHeapstate.dfy Calculations.dfy
- ) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 /dprint:out.dfy.tmp %* %%f
-)
diff --git a/Test/dafnytests.txt b/Test/dafnytests.txt
deleted file mode 100644
index 2b457c91..00000000
--- a/Test/dafnytests.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-dafny0 Use Dafny functionality tests
-dafny1 Use Various Dafny examples
-dafny2 Use More Dafny examples
-VSI-Benchmarks Use Solutions to Verified Software Initiative verification challenges
-vacid0 Use Dafny attempts to VACID Edition 0 benchmarks
-vstte2012 Use Dafny solutions for the VSTTE 2012 program verification competition
-VSComp2010 Use Dafny solutions to VSComp (verified software competition) problems
diff --git a/Test/jennisys0/Answer b/Test/jennisys0/Answer
deleted file mode 100644
index 5a3f9e82..00000000
--- a/Test/jennisys0/Answer
+++ /dev/null
@@ -1,90 +0,0 @@
-
--------------------- Prog0.jen --------------------
-// Jennisys, Copyright (c) 2011, Microsoft.
----------- Given Jennisys program ----------
-class C {
- var a: seq[int]
- var x: int
- constructor Init()
- method Update(d)
- x := x + 1
- {
- nested := statement
- yes := sirrie
- }
- x.f := (12 + true)[8000 := 0 <= n]
- method Query() returns (r)
- requires r
- requires a[*]
- requires r.r.s
- requires a[i]
- requires a[i := 58]
- requires hello
- requires (hello + goodbye) - soonyousoon
- requires 0 <= r
- {
- }
- method ManyParams(x: bool, y) returns (r, s: set[MyClass], t)
-}
-model C {
- var x: int
- var q: bool
- frame
- xyz
- abc
- klm
- mno
- pqr
- a
- b
- c
- invariant
- x <= x
- x < 100
- y < 1000
-}
-code C {
-}
-----------
-
--------------------- ExtensibleArray.jen --------------------
-// Jennisys, Copyright (c) 2011, Microsoft.
----------- Given Jennisys program ----------
-class ExtensibleArray[T] {
- var Contents: seq[T]
- constructor Init()
- Contents := []
- method Get(i) returns (t)
- requires 0 <= i
- requires i < |Contents|
- t := Contents[i]
- method Set(i, t)
- requires 0 <= i
- requires i < |Contents|
- Contents := Contents[i := t]
- method Append(t)
- Contents := Contents + [t]
-}
-model ExtensibleArray[T] {
- var elements: array[T]
- var more: ExtensibleArray[array[T]]
- var length: int
- var M: int
- frame
- elements
- more
- more.Contents[*]
- invariant
- elements != null
- elements.Length = 256
- more = null ==> M = 0
- more != null ==> |more.Contents| != 0 && M = 256 * |more.Contents|
- 0 <= length
- length <= M + 256
- more != null ==> M < length
- length = |Contents|
- more != null ==> (forall i :: 0 <= i && i < |more.Contents| ==> more.Contents[i] != null && more.Contents[i].Length = 256)
- more != null ==> (forall i :: 0 <= i && i < M ==> Contents[i] = more.Contents[i div 256][i mod 256])
- forall i :: M <= i && i < length ==> Contents[i] = elements[i - M]
-}
-----------
diff --git a/Test/jennisys0/ExtensibleArray.jen b/Test/jennisys0/ExtensibleArray.jen
deleted file mode 100644
index 7ef36ce2..00000000
--- a/Test/jennisys0/ExtensibleArray.jen
+++ /dev/null
@@ -1,40 +0,0 @@
-class ExtensibleArray[T] {
- var Contents: seq[T]
-
- constructor Init()
- Contents := []
-
- method Get(i) returns (t)
- requires 0 <= i && i < |Contents|
- t := Contents[i]
-
- method Set(i, t)
- requires 0 <= i && i < |Contents|
- Contents := Contents[i := t]
-
- method Append(t)
- Contents := Contents + [t]
-}
-
-model ExtensibleArray[T] {
- var elements: array[T]
- var more: ExtensibleArray[array[T]]
- var length: int
- var M: int
-
- frame
- elements * more * more.Contents[*]
-
- invariant
- elements != null
- elements.Length = 256
- more = null ==> M = 0
- more != null ==> |more.Contents| != 0 && M = 256 * |more.Contents|
- 0 <= length && length <= M + 256
- more != null ==> M < length
-
- length = |Contents|
- more != null ==> forall i :: 0 <= i && i < |more.Contents| ==> more.Contents[i] != null && more.Contents[i].Length = 256
- more != null ==> forall i :: 0 <= i && i < M ==> Contents[i] = more.Contents[i div 256][i mod 256]
- forall i :: M <= i && i < length ==> Contents[i] = elements[i - M]
-}
diff --git a/Test/jennisys0/Prog0.jen b/Test/jennisys0/Prog0.jen
deleted file mode 100644
index 7ce79cac..00000000
--- a/Test/jennisys0/Prog0.jen
+++ /dev/null
@@ -1,35 +0,0 @@
-class C {
- var a: seq[int]
- var x: int
- constructor Init()
- method Update(d)
- x := x + 1
- { nested := statement yes := sirrie }
- x.f := (12 + true)[8000 := 0 <= n]
- method Query() returns (r)
- requires r
- requires true
- requires a[*]
- requires r.r.s
- requires a[i]
- requires a[i := 58]
- requires (((hello)))
- requires (((hello) + (goodbye)) - soonyousoon)
- requires 0 <= r
- { }
- method ManyParams(x:bool,y) returns (r,s:set[MyClass],t)
-}
-
-model C {
- var x: int
- frame xyz * abc * klm
- mno pqr
- invariant x <= x
- var q: bool
- invariant frame frame
- invariant x < 100 y < 1000
- frame a * b c
-}
-
-code C {
-}
diff --git a/Test/jennisys0/runtest.bat b/Test/jennisys0/runtest.bat
deleted file mode 100644
index 6bae956e..00000000
--- a/Test/jennisys0/runtest.bat
+++ /dev/null
@@ -1,10 +0,0 @@
-@echo off
-setlocal
-
-set JENNISYS_EXE=..\..\Jennisys\Jennisys\bin\Debug\Jennisys.exe
-
-for %%f in (Prog0.jen ExtensibleArray.jen) do (
- echo.
- echo -------------------- %%f --------------------
- %JENNISYS_EXE% %* /trace /noAnalysis %%f
-)
diff --git a/Test/runtestdafny.bat b/Test/runtestdafny.bat
deleted file mode 100644
index df633681..00000000
--- a/Test/runtestdafny.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-@echo off
-setlocal
-
-set errors=0
-
-for /F "eol=; tokens=1,2,3*" %%i in (dafnytests.txt) do if %%j==Use call runtest.bat %%i %1 %2 %3 %4 %5 %6 %7 %8 %9 || set errors=1
-
-exit /b %errors%
diff --git a/Test/vacid0/Answer b/Test/vacid0/Answer
deleted file mode 100644
index 90bbcc78..00000000
--- a/Test/vacid0/Answer
+++ /dev/null
@@ -1,12 +0,0 @@
-
--------------------- LazyInitArray.dfy --------------------
-
-Dafny program verifier finished with 7 verified, 0 errors
-
--------------------- SparseArray.dfy --------------------
-
-Dafny program verifier finished with 9 verified, 0 errors
-
--------------------- Composite.dfy --------------------
-
-Dafny program verifier finished with 16 verified, 0 errors
diff --git a/Test/vacid0/AnswerRuntimeChecking b/Test/vacid0/AnswerRuntimeChecking
deleted file mode 100644
index e69de29b..00000000
--- a/Test/vacid0/AnswerRuntimeChecking
+++ /dev/null
diff --git a/Test/vacid0/Composite.dfy b/Test/vacid0/Composite.dfy
deleted file mode 100644
index ed376931..00000000
--- a/Test/vacid0/Composite.dfy
+++ /dev/null
@@ -1,172 +0,0 @@
-class Composite {
- var left: Composite;
- var right: Composite;
- var parent: Composite;
- var val: int;
- var sum: int;
-
- function Valid(S: set<Composite>): bool
- reads this, parent, left, right;
- {
- this in S &&
- (parent != null ==> parent in S && (parent.left == this || parent.right == this)) &&
- (left != null ==> left in S && left.parent == this && left != right) &&
- (right != null ==> right in S && right.parent == this && left != right) &&
- sum == val + (if left == null then 0 else left.sum) + (if right == null then 0 else right.sum)
- }
-
- function Acyclic(S: set<Composite>): bool
- reads S;
- {
- this in S &&
- (parent != null ==> parent.Acyclic(S - {this}))
- }
-
- method Init(x: int)
- modifies this;
- ensures Valid({this}) && Acyclic({this}) && val == x && parent == null;
- {
- parent := null;
- left := null;
- right := null;
- val := x;
- sum := val;
- }
-
- method Update(x: int, ghost S: set<Composite>)
- requires this in S && Acyclic(S);
- requires (forall c :: c in S ==> c != null && c.Valid(S));
- modifies S;
- ensures (forall c :: c in S ==> c.Valid(S));
- ensures (forall c :: c in S ==> c.left == old(c.left) && c.right == old(c.right) && c.parent == old(c.parent));
- ensures (forall c :: c in S && c != this ==> c.val == old(c.val));
- ensures val == x;
- {
- var delta := x - val;
- val := x;
- Adjust(delta, S, S);
- }
-
- method Add(ghost S: set<Composite>, child: Composite, ghost U: set<Composite>)
- requires this in S && Acyclic(S);
- requires (forall c :: c in S ==> c != null && c.Valid(S));
- requires child != null && child in U;
- requires (forall c :: c in U ==> c != null && c.Valid(U));
- requires S !! U;
- requires left == null || right == null;
- requires child.parent == null;
- // modifies only one of this.left and this.right, and child.parent, and various sum fields:
- modifies S, child;
- ensures child.left == old(child.left) && child.right == old(child.right) && child.val == old(child.val);
- ensures (forall c :: c in S && c != this ==> c.left == old(c.left) && c.right == old(c.right));
- ensures old(left) != null ==> left == old(left);
- ensures old(right) != null ==> right == old(right);
- ensures (forall c :: c in S ==> c.parent == old(c.parent) && c.val == old(c.val));
- // sets child.parent to this:
- ensures child.parent == this;
- // leaves everything in S+U valid:
- ensures (forall c :: c in S+U ==> c.Valid(S+U));
- {
- if (left == null) {
- left := child;
- } else {
- right := child;
- }
- child.parent := this;
- Adjust(child.sum, S, S+U);
- }
-
- method Dislodge(ghost S: set<Composite>)
- requires this in S && Acyclic(S);
- requires (forall c :: c in S ==> c != null && c.Valid(S));
- modifies S;
- 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});
- {
- var p := parent;
- parent := null;
- if (p != null) {
- if (p.left == this) {
- p.left := null;
- } else {
- p.right := null;
- }
- var delta := -sum;
- p.Adjust(delta, S - {this}, S);
- }
- }
-
- /*private*/ method Adjust(delta: int, ghost U: set<Composite>, ghost S: set<Composite>)
- requires U <= S && Acyclic(U);
- // everything else is valid:
- requires (forall c :: c in S && c != this ==> c != null && c.Valid(S));
- // this is almost valid:
- requires parent != null ==> parent in S && (parent.left == this || parent.right == this);
- requires left != null ==> left in S && left.parent == this && left != right;
- requires right != null ==> right in S && right.parent == this && left != right;
- // ... except that sum needs to be adjusted by delta:
- requires sum + delta == val + (if left == null then 0 else left.sum) + (if right == null then 0 else right.sum);
- // modifies sum fields in U:
- modifies U`sum;
- // everything is valid, including this:
- ensures (forall c :: c in S ==> c.Valid(S));
- {
- var p := this;
- ghost var T := U;
- while (p != null)
- invariant T <= U;
- invariant p == null || p.Acyclic(T);
- invariant (forall c :: c in S && c != p ==> c.Valid(S));
- invariant p != null ==> p.sum + delta == p.val + (if p.left == null then 0 else p.left.sum) + (if p.right == null then 0 else p.right.sum);
- invariant (forall c :: c in S ==> c.left == old(c.left) && c.right == old(c.right) && c.parent == old(c.parent) && c.val == old(c.val));
- decreases T;
- {
- p.sum := p.sum + delta;
- T := T - {p};
- p := p.parent;
- }
- }
-}
-
-method Main()
-{
- var c0 := new Composite.Init(57);
-
- var c1 := new Composite.Init(12);
- c0.Add({c0}, c1, {c1});
-
- var c2 := new Composite.Init(48);
-
- var c3 := new Composite.Init(48);
- c2.Add({c2}, c3, {c3});
- c0.Add({c0,c1}, c2, {c2,c3});
-
- ghost var S := {c0, c1, c2, c3};
- c1.Update(100, S);
- c2.Update(102, S);
-
- c2.Dislodge(S);
- c2.Update(496, S);
- c0.Update(0, S);
-}
-
-method Harness() {
- var a := new Composite.Init(5);
- var b := new Composite.Init(7);
- a.Add({a}, b, {b});
- assert a.sum == 12;
-
- b.Update(17, {a,b});
- assert a.sum == 22;
-
- var c := new Composite.Init(10);
- b.Add({a,b}, c, {c});
- b.Dislodge({a,b,c});
- assert b.sum == 27;
-}
-
diff --git a/Test/vacid0/LazyInitArray.dfy b/Test/vacid0/LazyInitArray.dfy
deleted file mode 100644
index 3e5a95ef..00000000
--- a/Test/vacid0/LazyInitArray.dfy
+++ /dev/null
@@ -1,105 +0,0 @@
-class LazyInitArray<T> {
- ghost var Contents: seq<T>;
- var Zero: T;
- /*private*/ var a: array<T>;
- /*private*/ var b: array<int>;
- /*private*/ var c: array<int>;
- /*private*/ var n: int;
- /*private*/ ghost var d: seq<int>;
- /*private*/ ghost var e: seq<int>;
- function Valid(): bool
- reads this, a, b, c;
- {
- a != null && b != null && c != null &&
- a.Length == |Contents| &&
- b.Length == |Contents| &&
- c.Length == |Contents| &&
- b != c && a != b && a != c &&
- 0 <= n && n <= c.Length &&
- (forall i :: 0 <= i && i < |Contents| ==>
- Contents[i] == (if 0 <= b[i] && b[i] < n && c[b[i]] == i then a[i] else Zero)) &&
- (forall i :: 0 <= i && i < |Contents| ==>
- ((exists j :: 0 <= j && j < n && c[j] == i)
- <==>
- 0 <= b[i] && b[i] < n && c[b[i]] == i)) &&
- // The idea behind d and e is the following:
- // * d is a permutation of the first |Contents| natural numbers
- // * e describes which permutation d is
- // * c[..n] == d[..n]
- |d| == |Contents| &&
- |e| == |Contents| &&
- (forall i :: 0 <= i && i < n ==> c[i] == d[i]) &&
- (forall i :: 0 <= i && i < |d| ==> 0 <= d[i] && d[i] < |d|) &&
- (forall i :: 0 <= i && i < |e| ==> 0 <= e[i] && e[i] < |e|) &&
- (forall i :: 0 <= i && i < |e| ==> d[e[i]] == i)
- }
-
- method Init(N: int, zero: T)
- requires 0 <= N;
- modifies this, a, b, c;
- ensures Valid();
- ensures |Contents| == N && Zero == zero;
- ensures (forall x :: x in Contents ==> x == zero);
- {
- a := new T[N];
- b := new int[N];
- c := new int[N];
- n := 0;
-
- // initialize ghost variable Contents to a sequence of length N containing only zero's,
- // and ghost variables d and e to be the identity sequences of length N
- ghost var s := [];
- ghost var id := [];
- ghost var k := 0;
- while (k < N)
- invariant k <= N;
- invariant |s| == k && (forall i :: 0 <= i && i < |s| ==> s[i] == zero);
- invariant |id| == k && (forall i :: 0 <= i && i < k ==> id[i] == i);
- {
- s := s + [zero];
- id := id + [k];
- k := k + 1;
- }
-
- d := id;
- e := id;
- Zero := zero;
- Contents := s;
- }
-
- method Get(i: int) returns (x: T)
- requires Valid();
- requires 0 <= i && i < |Contents|;
- ensures x == Contents[i];
- {
- if (0 <= b[i] && b[i] < n && c[b[i]] == i) {
- x := a[i];
- } else {
- x := Zero;
- }
- }
-
- method Set(i: int, x: T)
- requires Valid();
- requires 0 <= i && i < |Contents|;
- modifies this, a, b, c;
- ensures Valid();
- ensures |Contents| == |old(Contents)| && Contents == Contents[i := x];
- ensures Zero == old(Zero);
- {
- if (0 <= b[i] && b[i] < n && c[b[i]] == i) {
- } else {
- assert n <= e[i]; // lemma
- b[i] := n;
- c[n] := i;
- ghost var t := d[n];
- ghost var k := e[i];
- d := d[n := i][k := t];
- e := e[i := n][t := k];
- n := n + 1;
- }
-
- a[i] := x;
- Contents := Contents[i := x];
- }
-}
diff --git a/Test/vacid0/SparseArray.dfy b/Test/vacid0/SparseArray.dfy
deleted file mode 100644
index 989ddfc6..00000000
--- a/Test/vacid0/SparseArray.dfy
+++ /dev/null
@@ -1,116 +0,0 @@
-class SparseArray<T> {
- ghost var Contents: seq<T>;
- var zero: T;
- /*private*/ var a: seq<T>; // should really be an array
- /*private*/ var b: seq<int>; // should really be an array
- /*private*/ var c: seq<int>; // should really be an array
- /*private*/ var n: int;
- /*private*/ ghost var d: seq<int>; // would be better as an array
- /*private*/ ghost var e: seq<int>; // would be better as an array
- function Valid(): bool
- reads this;
- {
- |a| == |Contents| &&
- |b| == |Contents| &&
- |c| == |Contents| &&
- 0 <= n && n <= |c| &&
- (forall i :: 0 <= i && i < |Contents| ==>
- Contents[i] == (if 0 <= b[i] && b[i] < n && c[b[i]] == i then a[i] else zero)) &&
- (forall i :: 0 <= i && i < |Contents| ==>
- (i in c[..n] <==> 0 <= b[i] && b[i] < n && c[b[i]] == i)) &&
- // The idea behind d and e is the following:
- // * d is a permutation of the first |Contents| natural numbers
- // * e describes which permutation d is
- // * c[..n] == d[..n]
- |d| == |Contents| &&
- |e| == |Contents| &&
- (forall i :: 0 <= i && i < n ==> c[i] == d[i]) &&
- (forall i :: 0 <= i && i < |d| ==> 0 <= d[i] && d[i] < |d|) &&
- (forall i :: 0 <= i && i < |e| ==> 0 <= e[i] && e[i] < |e|) &&
- (forall i :: 0 <= i && i < |e| ==> d[e[i]] == i)
- }
-
- method Init(N: int, zero: T)
- requires 0 <= N;
- modifies this;
- ensures Valid();
- ensures |Contents| == N && this.zero == zero;
- ensures (forall x :: x in Contents ==> x == zero);
- {
- var aa := AllocateArray(N); this.a := aa;
- var bb := AllocateArray(N); this.b := bb;
- bb := AllocateArray(N); this.c := bb;
- this.n := 0;
-
- // initialize ghost variable Contents to a sequence of length N containing only zero's,
- // and ghost variables d and e to be the identity sequences of length N
- ghost var s := [];
- ghost var id := [];
- ghost var k := 0;
- while (k < N)
- invariant k <= N;
- invariant |s| == k;
- // TODO: why doesn't this work instead of the next line? invariant (forall x :: x in s ==> x == zero);
- invariant (forall i :: 0 <= i && i < |s| ==> s[i] == zero);
- invariant |id| == k && (forall i :: 0 <= i && i < k ==> id[i] == i);
- {
- s := s + [zero];
- id := id + [k];
- k := k + 1;
- }
-
- this.zero := zero;
- this.Contents := s;
- this.d := id;
- this.e := id;
- }
- method Get(i: int) returns (x: T)
- requires Valid();
- requires 0 <= i && i < |Contents|;
- ensures x == Contents[i];
- {
- if (0 <= b[i] && b[i] < n && c[b[i]] == i) {
- x := a[i];
- } else {
- x := zero;
- }
- }
- method Set(i: int, x: T)
- requires Valid();
- requires 0 <= i && i < |Contents|;
- modifies this;
- ensures Valid();
- ensures |Contents| == |old(Contents)| && Contents == Contents[i := x];
- ensures zero == old(zero);
- {
- if (0 <= b[i] && b[i] < n && c[b[i]] == i) {
- } else {
- assert n <= e[i]; // lemma
- b := b[i := n];
- c := c[n := i];
- ghost var t := d[n];
- ghost var k := e[i];
- d := d[n := i][k := t];
- e := e[i := n][t := k];
- n := n + 1;
- }
- a := a[i := x];
- Contents := Contents[i := x];
- }
-
- /* The following method is here only to simulate support of arrays in Dafny */
- /*private*/ static method AllocateArray<G>(n: int) returns (arr: seq<G>)
- requires 0 <= n;
- ensures |arr| == n;
- {
- arr := [];
- var i := 0;
- while (i < n)
- invariant i <= n && |arr| == i;
- {
- var g: G;
- arr := arr + [g];
- i := i + 1;
- }
- }
-}
diff --git a/Test/vacid0/runtest.bat b/Test/vacid0/runtest.bat
deleted file mode 100644
index cd047d39..00000000
--- a/Test/vacid0/runtest.bat
+++ /dev/null
@@ -1,11 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-for %%f in (LazyInitArray.dfy SparseArray.dfy Composite.dfy) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 %* %%f
-)
diff --git a/Test/vstte2012/Answer b/Test/vstte2012/Answer
deleted file mode 100644
index bca270c3..00000000
--- a/Test/vstte2012/Answer
+++ /dev/null
@@ -1,24 +0,0 @@
-
--------------------- Two-Way-Sort.dfy --------------------
-
-Dafny program verifier finished with 4 verified, 0 errors
-
--------------------- Combinators.dfy --------------------
-
-Dafny program verifier finished with 25 verified, 0 errors
-
--------------------- RingBuffer.dfy --------------------
-
-Dafny program verifier finished with 13 verified, 0 errors
-
--------------------- RingBufferAuto.dfy --------------------
-
-Dafny program verifier finished with 13 verified, 0 errors
-
--------------------- Tree.dfy --------------------
-
-Dafny program verifier finished with 15 verified, 0 errors
-
--------------------- BreadthFirstSearch.dfy --------------------
-
-Dafny program verifier finished with 24 verified, 0 errors
diff --git a/Test/vstte2012/BreadthFirstSearch.dfy b/Test/vstte2012/BreadthFirstSearch.dfy
deleted file mode 100644
index 4373136b..00000000
--- a/Test/vstte2012/BreadthFirstSearch.dfy
+++ /dev/null
@@ -1,276 +0,0 @@
-class BreadthFirstSearch<Vertex(==)>
-{
- // The following function is left uninterpreted (for the purpose of the
- // verification problem, it can be thought of as a parameter to the class)
- function method Succ(x: Vertex): set<Vertex>
-
- // This is the definition of what it means to be a path "p" from vertex
- // "source" to vertex "dest"
- function IsPath(source: Vertex, dest: Vertex, p: seq<Vertex>): bool
- {
- if source == dest then
- p == []
- else
- p != [] && dest in Succ(p[|p|-1]) && IsPath(source, p[|p|-1], p[..|p|-1])
- }
-
- function IsClosed(S: set<Vertex>): bool // says that S is closed under Succ
- {
- forall v :: v in S ==> Succ(v) <= S
- }
-
- // This is the main method to be verified. Note, instead of using a
- // postcondition that talks about that there exists a path (such that ...),
- // this method returns, as a ghost out-parameter, that existential
- // witness. The method could equally well have been written using an
- // existential quantifier and no ghost out-parameter.
- method BFS(source: Vertex, dest: Vertex, ghost AllVertices: set<Vertex>)
- returns (d: int, ghost path: seq<Vertex>)
- // source and dest are among AllVertices
- requires source in AllVertices && dest in AllVertices;
- // AllVertices is closed under Succ
- requires IsClosed(AllVertices);
- // This method has two basic outcomes, as indicated by the sign of "d".
- // More precisely, "d" is non-negative iff "source" can reach "dest".
- // The following postcondition says that under the "0 <= d" outcome,
- // "path" denotes a path of length "d" from "source" to "dest":
- ensures 0 <= d ==> IsPath(source, dest, path) && |path| == d;
- // Moreover, that path is as short as any path from "source" to "dest":
- ensures 0 <= d ==> forall p :: IsPath(source, dest, p) ==> |path| <= |p|;
- // Finally, under the outcome "d < 0", there is no path from "source" to "dest":
- ensures d < 0 ==> !exists p :: IsPath(source, dest, p);
- {
- var V, C, N := {source}, {source}, {};
- ghost var Processed, paths := {}, Maplet({source}, source, [], Empty);
- // V - all encountered vertices
- // Processed - vertices reachable from "source" is at most "d" steps
- // C - unprocessed vertices reachable from "source" in "d" steps
- // (but no less)
- // N - vertices encountered and reachable from "source" in "d+1" steps
- // (but no less)
- d := 0;
- var dd := Zero;
- while (C != {})
- // V, Processed, C, N are all subsets of AllVertices:
- invariant V <= AllVertices && Processed <= AllVertices && C <= AllVertices && N <= AllVertices;
- // source is encountered:
- invariant source in V;
- // V is the disjoint union of Processed, C, and N:
- invariant V == Processed + C + N;
- invariant Processed !! C !! N; // Processed, C, and N are mutually disjoint
- // "paths" records a path for every encountered vertex
- invariant ValidMap(source, paths);
- invariant V == Domain(paths);
- // shortest paths for vertices in C have length d, and for vertices in N
- // have length d+1
- invariant forall x :: x in C ==> |Find(source, x, paths)| == d;
- invariant forall x :: x in N ==> |Find(source, x, paths)| == d + 1;
- // "dd" is just an inductive-looking way of writing "d":
- invariant Value(dd) == d;
- // "dest" is not reachable for any smaller value of "d":
- invariant dest in R(source, dd, AllVertices) ==> dest in C;
- invariant d != 0 ==> dest !in R(source, dd.predecessor, AllVertices);
- // together, Processed and C are all the vertices reachable in at most d steps:
- invariant Processed + C == R(source, dd, AllVertices);
- // N are the successors of Processed that are not reachable within d steps:
- invariant N == Successors(Processed, AllVertices) - R(source, dd, AllVertices);
- // if we have exhausted C, then we have also exhausted N:
- invariant C == {} ==> N == {};
- // variant:
- decreases AllVertices - Processed;
- {
- // remove a vertex "v" from "C"
- var v := choose C;
- C, Processed := C - {v}, Processed + {v};
- ghost var pathToV := Find(source, v, paths);
-
- if (v == dest) {
- parallel (p | IsPath(source, dest, p))
- ensures |pathToV| <= |p|;
- {
- Lemma_IsPath_R(source, dest, p, AllVertices);
- if (|p| < |pathToV|) {
- // show that this branch is impossible
- ToNat_Value_Bijection(|p|);
- RMonotonicity(source, ToNat(|p|), dd.predecessor, AllVertices);
- }
- }
- return d, pathToV;
- }
-
- // process newly encountered successors
- var newlyEncountered := set w | w in Succ(v) && w !in V;
- V, N := V + newlyEncountered, N + newlyEncountered;
- paths := UpdatePaths(newlyEncountered, source, paths, v, pathToV);
-
- if (C == {}) {
- C, N, d, dd := N, {}, d+1, Suc(dd);
- }
- }
-
- // show that "dest" in not in any reachability set, no matter
- // how many successors one follows
- parallel (nn)
- ensures dest !in R(source, nn, AllVertices);
- {
- if (Value(nn) < Value(dd)) {
- RMonotonicity(source, nn, dd, AllVertices);
- } else {
- IsReachFixpoint(source, dd, nn, AllVertices);
- }
- }
-
- // Now, show what what the above means in terms of IsPath. More
- // precisely, show that there is no path "p" from "source" to "dest".
- parallel (p | IsPath(source, dest, p))
- // this and the previous two lines will establish the
- // absurdity of a "p" satisfying IsPath(source, dest, p)
- ensures false;
- {
- Lemma_IsPath_R(source, dest, p, AllVertices);
- // a consequence of Lemma_IsPath_R is:
- // dest in R(source, ToNat(|p|), AllVertices)
- // but that contradicts the conclusion of the preceding parallel statement
- }
-
- d := -1; // indicate "no path"
- }
-
- // property of IsPath
-
- ghost method Lemma_IsPath_Closure(source: Vertex, dest: Vertex,
- p: seq<Vertex>, AllVertices: set<Vertex>)
- requires IsPath(source, dest, p) && source in AllVertices && IsClosed(AllVertices);
- ensures dest in AllVertices && forall v :: v in p ==> v in AllVertices;
- {
- if (p != []) {
- var last := |p| - 1;
- Lemma_IsPath_Closure(source, p[last], p[..last], AllVertices);
- }
- }
-
- // operations on Nat
-
- function Value(nn: Nat): nat
- ensures ToNat(Value(nn)) == nn;
- {
- match nn
- case Zero => 0
- case Suc(mm) => Value(mm) + 1
- }
-
- function ToNat(n: nat): Nat
- {
- if n == 0 then Zero else Suc(ToNat(n - 1))
- }
-
- ghost method ToNat_Value_Bijection(n: nat)
- ensures Value(ToNat(n)) == n;
- {
- // Dafny automatically figures out the inductive proof of the postcondition
- }
-
- // Reachability
-
- function R(source: Vertex, nn: Nat, AllVertices: set<Vertex>): set<Vertex>
- {
- match nn
- case Zero => {source}
- case Suc(mm) => R(source, mm, AllVertices) +
- Successors(R(source, mm, AllVertices), AllVertices)
- }
-
- function Successors(S: set<Vertex>, AllVertices: set<Vertex>): set<Vertex>
- {
- set w | w in AllVertices && exists x :: x in S && w in Succ(x)
- }
-
- ghost method RMonotonicity(source: Vertex, mm: Nat, nn: Nat, AllVertices: set<Vertex>)
- requires Value(mm) <= Value(nn);
- ensures R(source, mm, AllVertices) <= R(source, nn, AllVertices);
- decreases Value(nn) - Value(mm);
- {
- if (Value(mm) < Value(nn)) {
- RMonotonicity(source, Suc(mm), nn, AllVertices);
- }
- }
-
- ghost method IsReachFixpoint(source: Vertex, mm: Nat, nn: Nat, AllVertices: set<Vertex>)
- requires R(source, mm, AllVertices) == R(source, Suc(mm), AllVertices);
- requires Value(mm) <= Value(nn);
- ensures R(source, mm, AllVertices) == R(source, nn, AllVertices);
- decreases Value(nn) - Value(mm);
- {
- if (Value(mm) < Value(nn)) {
- IsReachFixpoint(source, Suc(mm), nn, AllVertices);
- }
- }
-
- ghost method Lemma_IsPath_R(source: Vertex, x: Vertex,
- p: seq<Vertex>, AllVertices: set<Vertex>)
- requires IsPath(source, x, p) && source in AllVertices && IsClosed(AllVertices);
- ensures x in R(source, ToNat(|p|), AllVertices);
- {
- if (p != []) {
- Lemma_IsPath_Closure(source, x, p, AllVertices);
- var last := |p| - 1;
- Lemma_IsPath_R(source, p[last], p[..last], AllVertices);
- }
- }
-
- // operations on Map's
-
- function Domain(m: Map<Vertex>): set<Vertex>
- {
-// if m.Maplet? then m.dom else {}
-// if m == Empty then {} else assert m.Maplet?; m.dom
- match m
- case Empty => {}
- case Maplet(dom, t, s, nxt) => dom
- }
-
- // ValidMap encodes the consistency of maps (think, invariant).
- // An explanation of this idiom is explained in the README file.
- function ValidMap(source: Vertex, m: Map<Vertex>): bool
- {
- match m
- case Empty => true
- case Maplet(dom, v, path, next) =>
- v in dom && dom == Domain(next) + {v} &&
- IsPath(source, v, path) &&
- ValidMap(source, next)
- }
-
- function Find(source: Vertex, x: Vertex, m: Map<Vertex>): seq<Vertex>
- requires ValidMap(source, m) && x in Domain(m);
- ensures IsPath(source, x, Find(source, x, m));
- {
- match m
- case Maplet(dom, v, path, next) =>
- if x == v then path else Find(source, x, next)
- }
-
- ghost method UpdatePaths(vSuccs: set<Vertex>, source: Vertex,
- paths: Map<Vertex>, v: Vertex, pathToV: seq<Vertex>)
- returns (newPaths: Map<Vertex>)
- requires ValidMap(source, paths);
- requires vSuccs !! Domain(paths);
- requires forall succ :: succ in vSuccs ==> IsPath(source, succ, pathToV + [v]);
- ensures ValidMap(source, newPaths) && Domain(newPaths) == Domain(paths) + vSuccs;
- ensures forall x :: x in Domain(paths) ==>
- Find(source, x, paths) == Find(source, x, newPaths);
- ensures forall x :: x in vSuccs ==> Find(source, x, newPaths) == pathToV + [v];
- {
- if (vSuccs == {}) {
- newPaths := paths;
- } else {
- var succ := choose vSuccs;
- newPaths := Maplet(Domain(paths) + {succ}, succ, pathToV + [v], paths);
- newPaths := UpdatePaths(vSuccs - {succ}, source, newPaths, v, pathToV);
- }
- }
-}
-
-datatype Map<T> = Empty | Maplet(dom: set<T>, T, seq<T>, next: Map<T>);
-
-datatype Nat = Zero | Suc(predecessor: Nat);
diff --git a/Test/vstte2012/Combinators.dfy b/Test/vstte2012/Combinators.dfy
deleted file mode 100644
index 46daf48d..00000000
--- a/Test/vstte2012/Combinators.dfy
+++ /dev/null
@@ -1,459 +0,0 @@
-// Problem 2 concerns an interpreter for the language of S and K combinators.
-
-// -----------------------------------------------------------------------------
-// Definitions
-
-// First, we define the language of combinator terms. "Apply(x, y)" is what
-// the problem description writes as "(x y)". In the following Dafny
-// definition, "car" and "cdr" are declared to be destructors for terms
-// constructed by Apply.
-
-datatype Term = S | K | Apply(car: Term, cdr: Term);
-
-// The problem defines values to be a subset of the terms. More precisely,
-// a Value is a Term that fits the following grammar:
-// Value = K | S | (K Value) | (S Value) | ((S Value) Value)
-// The following predicate says whether or not a given term is a value.
-
-function method IsValue(t: Term): bool
- ensures IsValue(t) && t.Apply? ==> IsValue(t.car) && IsValue(t.cdr);
-{
- match t
- case K => true
- case S => true
- case Apply(a, b) =>
- match a
- case K =>
- assert IsValue(a);
- IsValue(b)
- case S =>
- assert IsValue(a);
- IsValue(b)
- case Apply(x, y) =>
- assert x==S && IsValue(y) && IsValue(b) ==> IsValue(a);
- x==S && IsValue(y) && IsValue(b)
-}
-
-// A context is essentially a term with one missing subterm, a "hole". It
-// is defined as follows:
-
-datatype Context = Hole | C_term(Context, Term) | value_C(Term/*Value*/, Context);
-
-// The problem seems to suggest that the value_C form requires a value and
-// a context. To formalize that notion, we define a predicate that checks this
-// condition.
-
-function IsContext(C: Context): bool
-{
- match C
- case Hole => true // []
- case C_term(D, t) => IsContext(D) // (D t)
- case value_C(v, D) => IsValue(v) && IsContext(D) // (v D)
-}
-
-// The EvalExpr function replace the hole in a context with a given term.
-
-function EvalExpr(C: Context, t: Term): Term
- requires IsContext(C);
-{
- match C
- case Hole => t
- case C_term(D, u) => Apply(EvalExpr(D, t), u)
- case value_C(v, D) => Apply(v, EvalExpr(D, t))
-}
-
-// A term can be reduced. This reduction operation is defined via
-// a single-step reduction operation. In the problem, the single-step
-// reduction has the form:
-// C[t] --> C[r]
-// We formalize the single-step reduction by a function Step, which
-// performs the reduction if it applies or just returns the given term
-// if it does. We will say that "Step applies" to refer to the first
-// case, which is a slight abuse of language, since the function "Step"
-// is total.
-//
-// Since the context C is the same on both sides in the single-step
-// reduction above, we don't pass it to function Step. Rather, Step
-// just takes a term "t" and returns the following:
-// match t
-// case ((K v1) v2) => v1
-// case (((S v1) v2) v3) => ((v1 v3) (v2 v3))
-// else t
-// As you can see below, it takes more lines than shown here to express
-// this matching in Dafny, but this is all that Step does.
-//
-// Again, note that Step returns the given term if neither or the two
-// vs in the problem statement applies.
-//
-// One more thing: Step has a postcondition (and the body of Step
-// contains three asserts that act as lemmas in proving the postcondition).
-// The postcondition has been included for the benefit of Verification
-// Task 2, and we describe the functions used in the Step postcondition
-// only much later in this file. For now, the postcondition can be
-// ignored, since it is, after all, just a consequence of the body
-// of Step.
-
-function method Step(t: Term): Term
- ensures !ContainsS(t) ==>
- !ContainsS(Step(t)) &&
- (Step(t) == t || TermSize(Step(t)) < TermSize(t));
-{
- match t
- case S => t
- case K => t
- case Apply(x, y) =>
- match x
- case S => t
- case K => t
- case Apply(m, n) =>
- if m == K && IsValue(n) && IsValue(y) then
- // this is the case t == Apply(Apply(K, n), y)
- assert !ContainsS(t) ==> !ContainsS(x);
- assert TermSize(n) < TermSize(Apply(m, n));
- n
- else if m.Apply? && m.car == S && IsValue(m.cdr) && IsValue(n) && IsValue(y) then
- // t == Apply(Apply(Apply(S, m.cdr), n), y)
- assert ContainsS(m) && ContainsS(t);
- Apply(Apply(m.cdr, y), Apply(n, y))
- else
- t
-}
-
-// The single-step reduction operation may be applied to any subexpression
-// of a term that could be considered a hole. Function FindAndStep
-// searches for a (context, term) pair C[u] that denotes a given term "t"
-// such that Step applies to "u". If found, the function returns
-// C[Step(u)], which will necessarily be different from "t". If no such
-// C[u] pair exists, this function returns the given "t".
-//
-// Note, FindAndStep only applies one Step. We will get to repeated
-// applications of steps in the "reduction" method below.
-//
-// For all definitions above, it was necessary to check (manually) that
-// they correspond to the definitions intended in the problem statement.
-// That is, the definitions above are all part of the specification.
-// For function FindAndStep, the definition given does not require
-// such scrutiny. Rather, we will soon state a theorem that states
-// the properties of what FindAndStep returns.
-//
-// Like Step, FindAndStep has a postcondition, and it is also included to
-// support Verification Task 2.
-
-function method FindAndStep(t: Term): Term
- ensures !ContainsS(t) ==>
- !ContainsS(FindAndStep(t)) &&
- (FindAndStep(t) == t || TermSize(FindAndStep(t)) < TermSize(t));
-{
- if Step(t) != t then
- Step(t)
- else if !t.Apply? then
- t
- else if FindAndStep(t.car) != t.car then
- Apply(FindAndStep(t.car), t.cdr)
- else if IsValue(t.car) && FindAndStep(t.cdr) != t.cdr then
- Apply(t.car, FindAndStep(t.cdr))
- else
- t
-}
-
-// One part of the correctness of FindAndStep (and, indeed, of method
-// "reduction" below) is that a term can be terminal, meaning that there is
-// no way to apply Step to any part of it.
-
-function IsTerminal(t: Term): bool
-{
- !(exists C,u :: IsContext(C) && t == EvalExpr(C,u) && Step(u) != u)
-}
-
-// The following theorem states the correctness of the FindAndStep function:
-
-ghost method Theorem_FindAndStep(t: Term)
- // If FindAndStep returns the term it started from, then there is no
- // way to take a step. More precisely, there is no C[u] == t for which the
- // Step applies to "u".
- ensures FindAndStep(t) == t ==> IsTerminal(t);
- // If FindAndStep returns a term that's different from what it started with,
- // then it chose some C[u] == t for which the Step applies to "u", and then
- // it returned C[Step(u)].
- ensures FindAndStep(t) != t ==>
- exists C,u :: IsContext(C) && t == EvalExpr(C,u) && Step(u) != u &&
- FindAndStep(t) == EvalExpr(C, Step(u));
-{
- // The theorem follows from the following lemma, which itself is proved by
- // induction.
- var r, C, u := Lemma_FindAndStep(t);
-}
-
-// This is the lemma that proves the theorem above. Whereas the theorem talks
-// existentially about C and u, the lemma constructs C and u and returns them,
-// which is useful in the proof by induction. The computation inside the
-// lemma mimicks that done by function FindAndStep; indeed, the lemma
-// computes the value of FindAndStep(t) as it goes along and it returns
-// that value.
-
-ghost method Lemma_FindAndStep(t: Term) returns (r: Term, C: Context, u: Term)
- ensures r == FindAndStep(t);
- ensures r == t ==> IsTerminal(t);
- ensures r != t ==>
- IsContext(C) && t == EvalExpr(C,u) && Step(u) != u &&
- r == EvalExpr(C, Step(u));
-{
- Lemma_ContextPossibilities(t);
- if (Step(t) != t) {
- // t == Hole[t] and Step applies t. So, return Hole[Step(t)]
- return Step(t), Hole, t;
- } else if (!t.Apply?) {
- r := t;
- } else {
- r, C, u := Lemma_FindAndStep(t.car); // (*)
- if (r != t.car) {
- // t has the form (a b) where a==t.car and b==t.cdr, and a==C[u] for some
- // context C and some u to which the Step applies. t can therefore be
- // denoted by (C[u] b) == (C b)[u] and the Step applies to u. So, return
- // (C b)[Step(u)] == (C[Step(u)] b). Note that FindAndStep(a)
- // gives C[Step(u)].
- return Apply(r, t.cdr), C_term(C, t.cdr), u;
- } else if (IsValue(t.car)) {
- r, C, u := Lemma_FindAndStep(t.cdr);
- assert IsTerminal(t.car); // make sure this is still remembered from (*)
-
- if (r != t.cdr) {
- // t has the form (a b) where a==t.car and b==t.cdr and "a" is a Value,
- // and b==C[u] for some context C and some u to which the Step applies.
- // t can therefore be denoted by (a C[u]) == (C a)[u] and the Step
- // applies to u. So, return (C a)[Step(u)] == (a C[Step(u)]). Note
- // that FindAndStep(b) gives C[Step(u)].
- return Apply(t.car, r), value_C(t.car, C), u;
- } else {
- parallel (C,u | IsContext(C) && t == EvalExpr(C,u))
- ensures Step(u) == u;
- {
- // The following assert and the first assert of each "case" are
- // consequences of the Lemma_ContextPossibilities that was invoked
- // above.
- assert t.Apply? && IsValue(t.car);
- match (C) {
- case Hole =>
- assert t == u;
- case C_term(D, bt) =>
- assert bt == t.cdr && t.car == EvalExpr(D, u);
- case value_C(at, D) =>
- assert at == t.car && t.cdr == EvalExpr(D, u);
- }
- }
- r := t;
- }
- } else {
- r := t;
- }
- }
-}
-
-// The proof of the lemma above used one more lemma, namely one that enumerates
-// lays out the options for how to represent a term as a C[u] pair.
-
-ghost method Lemma_ContextPossibilities(t: Term)
- ensures forall C,u :: IsContext(C) && t == EvalExpr(C, u) ==>
- (C == Hole && t == u) ||
- (t.Apply? && exists D :: C == C_term(D, t.cdr) && t.car == EvalExpr(D, u)) ||
- (t.Apply? && IsValue(t.car) &&
- exists D :: C == value_C(t.car, D) && t.cdr == EvalExpr(D, u));
-{
- // Dafny's induction tactic rocks
-}
-
-// We now define a way to record a sequence of reduction steps.
-// IsTrace(trace, t, r) returns true iff "trace" gives witness to a
-// sequence of terms from "t" to "r", each term reducing to its
-// successor in the trace.
-
-datatype Trace = EmptyTrace | ReductionStep(Trace, Term);
-
-function IsTrace(trace: Trace, t: Term, r: Term): bool
-{
- match trace
- case EmptyTrace =>
- t == r
- case ReductionStep(tr, u) =>
- IsTrace(tr, t, u) && FindAndStep(u) == r
-}
-
-// Finally, we are ready to give the requested routine "reduction", which
-// keeps applying FindAndStep until quiescence, that is, until Step
-// no longer applies.
-//
-// As required by Verification Task 1, the "reduction" method has two
-// postconditions. One says that the term returned, "r", was obtained
-// from the original term, "t", by a sequence of reduction steps. The
-// other says that "r" cannot be reduced any further.
-//
-// Unlike the other competition problems, this one requested code
-// (for "reduction") that may not terminate. In order to allow reasoning
-// about algorithms that may never terminate, Dafny has a special loop
-// statement (a "while" loop with a declaration "decreases *") that
-// thus comes in handy for "reduction". (Dafny never allows recursion
-// to be non-terminating, only these special loops.) Note that use
-// of the special loop statement does not have any effect on the
-// specifications of the enclosing method (but this may change in a
-// future version of Dafny).
-
-method reduction(t: Term) returns (r: Term)
- // The result was obtained by a sequence of reductions:
- ensures exists trace :: IsTrace(trace, t, r);
- // The result "r" cannot be reduced any further:
- ensures IsTerminal(r);
-{
- r := t;
- ghost var trace := EmptyTrace;
- while (true)
- invariant IsTrace(trace, t, r);
- decreases *; // allow this statement to loop forever
- {
- var u := FindAndStep(r);
- if (u == r) {
- // we have found a fixpoint
- Theorem_FindAndStep(r);
- return;
- }
- r, trace := u, ReductionStep(trace, r);
- }
-}
-
-// -----------------------------------------------------------------------------
-// Verification Task 2
-//
-// This part of the problem asks us to consider the reduction of terms that
-// do not contain S. The following function formalizes what it means for a term
-// to contain S:
-
-function method ContainsS(t: Term): bool
-{
- match t
- case S => true
- case K => false
- case Apply(x, y) => ContainsS(x) || ContainsS(y)
-}
-
-// The verification task itself is to prove that "reduction" terminates on any
-// term that does not contain S. To prove this, we need to supply a loop variant
-// for the loop in "reduction". However, Dafny does not allow one loop to be
-// proved to terminate in some cases and allowed not to terminate in other cases.
-// There, we meet Verification Task 2 by manually copying the body of "reduction"
-// into a new method (called VerificationTask2) and proving that this new method
-// terminates. Of course, Dafny does not check that we copy the body correctly,
-// so that needs to be checked by a human.
-//
-// In method VerificationTask2, we added not just the precondition given in the
-// Verification Task and a loop variant, but we also added two loop invariants
-// and one more postcondition. One of the loop invariants keep track of that
-// there are no S's. The other loop invariant and the postcondition are for
-// the benefit of Verification Task 3, as we explain later.
-
-method VerificationTask2(t: Term) returns (r: Term)
- requires !ContainsS(t); // a sufficient condition for termination
- // The result was obtained by a sequence of reductions:
- ensures exists trace :: IsTrace(trace, t, r);
- // The result "r" cannot be reduced any further:
- ensures IsTerminal(r);
- // Later in this file, we define a function TerminatingReduction, and the
- // following postcondition says that TerminatingReduction computes the same
- // term as this method does.
- ensures r == TerminatingReduction(t);
-{
- r := t;
- ghost var trace := EmptyTrace;
- while (true)
- invariant IsTrace(trace, t, r) && !ContainsS(r);
- invariant TerminatingReduction(t) == TerminatingReduction(r);
- decreases TermSize(r);
- {
- var u := FindAndStep(r);
- if (u == r) {
- // we have found a fixpoint
- Theorem_FindAndStep(r);
- return;
- }
- r, trace := u, ReductionStep(trace, r);
- }
-}
-
-// What now follows is the definition TermSize, which is used in the
-// loop variant. When a Step is applied to a term without S, TermSize
-// is reduced, which is stated as a postcondition of both Step and
-// FindAndStep. That postcondition of FindAndStep is used in the
-// proof of termination of method VerificationTask2.
-
-// The loop variant is simply the count of nodes in the term:
-
-function TermSize(t: Term): nat
-{
- match t
- case S => 1
- case K => 1
- case Apply(x, y) => 1 + TermSize(x) + TermSize(y)
-}
-
-// We have already given two methods for computing a reduction:
-// method "reduction", which may or may not terminate, and method
-// "VerificationTask2", whose precondition is strong enough to let
-// us prove that the method will terminate. The correspondence
-// between the two methods is checked by hand, seeing that
-// VerificationTask2 includes the postconditions of "reduction" and
-// seeing that the code is the same.
-//
-// We now define a third way of computing reductions, this time
-// using a function (not a method). To prove that this function
-// computes the same thing as method VerificationTask2, we had
-// added a postcondition to VerificationTask2 above. This function
-// is introduced for the benefit of stating and verifying Verification
-// Task 3.
-
-function TerminatingReduction(t: Term): Term
- requires !ContainsS(t); // a sufficient condition for termination
- decreases TermSize(t);
-{
- if FindAndStep(t) == t then
- t // we have reached a fixpoint
- else
- TerminatingReduction(FindAndStep(t))
-}
-
-// -----------------------------------------------------------------------------
-// Verification Task 3
-
-// Here is the function "ks" from Verification Task 3. It produces a particular
-// family of terms that contain only Apply and K. Hence, we can establish, as a
-// postcondition of the function, that ks(n) does not contain S.
-
-function method ks(n: nat): Term
- ensures !ContainsS(ks(n));
-{
- if n == 0 then K else Apply(ks(n-1), K)
-}
-
-// Verification Task 3 is now established by the following theorem. It says
-// that reducing ks(n) results in either K and (K K), depending on the parity
-// of n. The theorem uses function TerminatingReduction to speak of the
-// reduction--remember that (by the last postcondition of method
-// VerificationTask2) it computes the same thing as method VerificationTask2
-// does.
-
-ghost method VerificationTask3()
- ensures forall n: nat ::
- TerminatingReduction(ks(n)) == if n % 2 == 0 then K else Apply(K, K);
-{
- parallel (n: nat) {
- VT3(n);
- }
-}
-
-ghost method VT3(n: nat)
- ensures TerminatingReduction(ks(n)) == if n % 2 == 0 then K else Apply(K, K);
-{
- // Dafny's (way cool) induction tactic kicks in and proves the following
- // assertion automatically:
- assert forall p :: 2 <= p ==> FindAndStep(ks(p)) == ks(p-2);
- // And then Dafny's (cool beyond words) induction tactic for ghost methods kicks
- // in to prove the postcondition. (If this got you curious, scope out Leino's
- // VMCAI 2012 paper "Automating Induction with an SMT Solver".)
-}
diff --git a/Test/vstte2012/RingBuffer.dfy b/Test/vstte2012/RingBuffer.dfy
deleted file mode 100644
index 5262e462..00000000
--- a/Test/vstte2012/RingBuffer.dfy
+++ /dev/null
@@ -1,93 +0,0 @@
-class RingBuffer<T>
-{
- // public fields that are used to define the abstraction:
- ghost var Contents: seq<T>; // the contents of the ring buffer
- ghost var N: nat; // the capacity of the ring buffer
- ghost var Repr: set<object>; // the set of objects used in the implementation
-
- // Valid encodes the consistency of RingBuffer objects (think, invariant).
- // An explanation of this idiom is explained in the README file.
- function Valid(): bool
- reads this, Repr;
- {
- this in Repr && null !in Repr &&
- data != null && data in Repr &&
- data.Length == N &&
- (N == 0 ==> len == first == 0 && Contents == []) &&
- (N != 0 ==> len <= N && first < N) &&
- Contents == if first + len <= N then data[first..first+len]
- else data[first..] + data[..first+len-N]
- }
-
- // private implementation:
- var data: array<T>;
- var first: nat;
- var len: nat;
-
- constructor Create(n: nat)
- modifies this;
- ensures Valid() && fresh(Repr - {this});
- ensures Contents == [] && N == n;
- {
- Repr := {this};
- data := new T[n];
- Repr := Repr + {data};
- first, len := 0, 0;
- Contents, N := [], n;
- }
-
- method Clear()
- requires Valid();
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == [] && N == old(N);
- {
- len := 0;
- Contents := [];
- }
-
- method Head() returns (x: T)
- requires Valid();
- requires Contents != [];
- ensures x == Contents[0];
- {
- x := data[first];
- }
-
- method Push(x: T)
- requires Valid();
- requires |Contents| != N;
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures Contents == old(Contents) + [x] && N == old(N);
- {
- var nextEmpty := if first + len < data.Length
- then first + len else first + len - data.Length;
- data[nextEmpty] := x;
- len := len + 1;
- Contents := Contents + [x];
- }
-
- method Pop() returns (x: T)
- requires Valid();
- requires Contents != [];
- modifies Repr;
- ensures Valid() && fresh(Repr - old(Repr));
- ensures x == old(Contents)[0] && Contents == old(Contents)[1..] && N == old(N);
- {
- x := data[first];
- first, len := if first + 1 == data.Length then 0 else first + 1, len - 1;
- Contents := Contents[1..];
- }
-}
-
-method TestHarness(x: int, y: int, z: int)
-{
- var b := new RingBuffer<int>.Create(2);
- b.Push(x);
- b.Push(y);
- var h := b.Pop(); assert h == x;
- b.Push(z);
- h := b.Pop(); assert h == y;
- h := b.Pop(); assert h == z;
-}
diff --git a/Test/vstte2012/RingBufferAuto.dfy b/Test/vstte2012/RingBufferAuto.dfy
deleted file mode 100644
index 712236a8..00000000
--- a/Test/vstte2012/RingBufferAuto.dfy
+++ /dev/null
@@ -1,75 +0,0 @@
-class {:autocontracts} RingBuffer<T>
-{
- // public view of the class:
- ghost var Contents: seq<T>; // the contents of the ring buffer
- ghost var N: nat; // the capacity of the ring buffer
-
- // private implementation:
- var data: array<T>;
- var first: nat;
- var len: nat;
-
- // Valid encodes the consistency of RingBuffer objects (think, invariant)
- predicate Valid
- {
- data != null &&
- data.Length == N &&
- (N == 0 ==> len == first == 0 && Contents == []) &&
- (N != 0 ==> len <= N && first < N) &&
- Contents == if first + len <= N then data[first..first+len]
- else data[first..] + data[..first+len-N]
- }
-
- constructor Create(n: nat)
- ensures Contents == [] && N == n;
- {
- data := new T[n];
- first, len := 0, 0;
- Contents, N := [], n;
- }
-
- method Clear()
- ensures Contents == [] && N == old(N);
- {
- len := 0;
- Contents := [];
- }
-
- method Head() returns (x: T)
- requires Contents != [];
- ensures x == Contents[0];
- {
- x := data[first];
- }
-
- method Enqueue(x: T)
- requires |Contents| != N;
- ensures Contents == old(Contents) + [x] && N == old(N);
- {
- var nextEmpty := if first + len < data.Length
- then first + len else first + len - data.Length;
- data[nextEmpty] := x;
- len := len + 1;
- Contents := Contents + [x];
- }
-
- method Dequeue() returns (x: T)
- requires Contents != [];
- ensures x == old(Contents)[0] && Contents == old(Contents)[1..] && N == old(N);
- {
- x := data[first];
- first, len := if first + 1 == data.Length then 0 else first + 1, len - 1;
- Contents := Contents[1..];
- }
-}
-
-method TestHarness(x: int, y: int, z: int)
-{
- var b := new RingBuffer.Create(2);
- b.Enqueue(x);
- b.Enqueue(y);
- var h := b.Dequeue(); assert h == x;
- b.Enqueue(z);
- h := b.Dequeue(); assert h == y;
- h := b.Dequeue(); assert h == z;
-}
diff --git a/Test/vstte2012/Tree.dfy b/Test/vstte2012/Tree.dfy
deleted file mode 100644
index 47ed19a4..00000000
--- a/Test/vstte2012/Tree.dfy
+++ /dev/null
@@ -1,172 +0,0 @@
-// The tree datatype
-datatype Tree = Leaf | Node(Tree, Tree);
-
-
-// This datatype is used for the result of the build functions.
-// These functions either fail or yield a tree. Since we use
-// a side-effect free implementation of the helper
-// build_rec, it also has to yield the rest of the sequence,
-// which still needs to be processed. For function build,
-// this part is not used.
-datatype Result = Fail | Res(t: Tree, sOut: seq<int>);
-
-
-// Function toList converts a tree to a sequence.
-// We use Dafny's built-in value type sequence rather than
-// an imperative implementation to simplify verification.
-// The argument d is added to each element of the sequence;
-// it is analogous to the argument d in build_rec.
-// The postconditions state properties that are needed
-// in the completeness proof.
-function toList(d: int, t: Tree): seq<int>
- ensures toList(d, t) != [] && toList(d, t)[0] >= d;
- ensures (toList(d, t)[0] == d) == (t == Leaf);
- decreases t;
-{
- match t
- case Leaf => [d]
- case Node(l, r) => toList(d+1, l) + toList(d+1, r)
-}
-
-
-// Function build_rec is a side-effect free implementation
-// of the code given in the problem statement.
-// The first postcondition is needed to show that the
-// termination measure indeed decreases.
-// The second postcondition specifies the soundness
-// property; converting the resulting tree back into a
-// sequence yields exactly that portion of the input
-// sequence that has been consumed.
-function method build_rec(d: int, s: seq<int>): Result
- ensures build_rec(d, s).Res? ==>
- |build_rec(d, s).sOut| < |s| &&
- build_rec(d, s).sOut == s[|s|-|build_rec(d, s).sOut|..];
- ensures build_rec(d, s).Res? ==>
- toList(d,build_rec(d, s).t) == s[..|s|-|build_rec(d, s).sOut|];
- decreases |s|, (if s==[] then 0 else s[0]-d);
-{
- if s==[] || s[0] < d then
- Fail
- else if s[0] == d then
- Res(Leaf, s[1..])
- else
- var left := build_rec(d+1, s);
- if left.Fail? then Fail else
- var right := build_rec(d+1, left.sOut);
- if right.Fail? then Fail else
- Res(Node(left.t, right.t), right.sOut)
-}
-
-
-// Function build is a side-effect free implementation
-// of the code given in the problem statement.
-// The postcondition specifies the soundness property;
-// converting the resulting tree back into a
-// sequence yields exactly the input sequence.
-// Completeness is proved as a lemma, see below.
-function method build(s: seq<int>): Result
- ensures build(s).Res? ==> toList(0,build(s).t) == s;
-{
- var r := build_rec(0, s);
- if r.Res? && r.sOut == [] then r else Fail
-}
-
-
-// This ghost methods encodes the main lemma for the
-// completeness theorem. If a sequence s starts with a
-// valid encoding of a tree t then build_rec yields a
-// result (i.e., does not fail) and the rest of the sequence.
-// The body of the method proves the lemma by structural
-// induction on t. Dafny proves termination (using the
-// height of the term t as termination measure), which
-// ensures that the induction hypothesis is applied
-// correctly (encoded by calls to this ghost method).
-ghost method lemma0(t: Tree, d: int, s: seq<int>)
- ensures build_rec(d, toList(d, t) + s).Res? &&
- build_rec(d, toList(d, t) + s).sOut == s;
-{
- match(t) {
- case Leaf =>
- assert toList(d, t) == [d];
- case Node(l, r) =>
- assert toList(d, t) + s == toList(d+1, l) + (toList(d+1, r) + s);
-
- lemma0(l, d+1, toList(d+1, r) + s); // apply the induction hypothesis
- lemma0(r, d+1, s); // apply the induction hypothesis
- }
-}
-
-
-// This ghost method encodes a lemma that states the
-// completeness property. It is proved by applying the
-// main lemma (lemma0). In this lemma, the bound variables
-// of the completeness theorem are passed as arguments;
-// the following two ghost methods replace these arguments
-// by quantified variables.
-ghost method lemma1(t: Tree, s:seq<int>)
- requires s == toList(0, t) + [];
- ensures build(s).Res?;
-{
- lemma0(t, 0, []);
-}
-
-
-// This ghost method encodes a lemma that introduces the
-// existential quantifier in the completeness property.
-ghost method lemma2(s: seq<int>)
- ensures (exists t: Tree :: toList(0,t) == s) ==> build(s).Res?;
-{
- parallel(t | toList(0,t) == s) {
- lemma1(t, s);
- }
-}
-
-
-// This ghost method encodes the completeness theorem.
-// For each sequence for which there is a corresponding
-// tree, function build yields a result different from Fail.
-// The body of the method converts the argument of lemma2
-// into a universally quantified variable.
-ghost method completeness()
- ensures forall s: seq<int> :: ((exists t: Tree :: toList(0,t) == s) ==> build(s).Res?);
-{
- parallel(s) {
- lemma2(s);
- }
-}
-
-
-// This method encodes the first test harness
-// given in the problem statement. The local
-// assertions are required by the verifier to
-// unfold the necessary definitions.
-method harness0()
- ensures build([1,3,3,2]).Res? &&
- build([1,3,3,2]).t == Node(Leaf, Node(Node(Leaf, Leaf), Leaf));
-{
- assert build_rec(2, [2]) ==
- Res(Leaf, []);
- assert build_rec(2, [3,3,2]) ==
- Res(Node(Leaf, Leaf), [2]);
- assert build_rec(1, [3,3,2]) ==
- Res(Node(Node(Leaf, Leaf), Leaf), []);
- assert build_rec(1, [1,3,3,2]) ==
- Res(Leaf, [3,3,2]);
- assert build_rec(0, [1,3,3,2]) ==
- Res(
- Node(build_rec(1, [1,3,3,2]).t,
- build_rec(1, [3,3,2]).t),
- []);
-}
-
-
-// This method encodes the second test harness
-// given in the problem statement. The local
-// assertions are required by the verifier to
-// unfold the necessary definitions.
-method harness1()
- ensures build([1,3,2,2]).Fail?;
-{
- assert build_rec(3, [2,2]).Fail?;
- assert build_rec(1, [3,2,2]).Fail?;
-}
diff --git a/Test/vstte2012/Two-Way-Sort.dfy b/Test/vstte2012/Two-Way-Sort.dfy
deleted file mode 100644
index 49ff29b4..00000000
--- a/Test/vstte2012/Two-Way-Sort.dfy
+++ /dev/null
@@ -1,58 +0,0 @@
-// This method is a slight generalization of the
-// code provided in the problem statement since it
-// is generic in the type of the array elements.
-method swap<T>(a: array<T>, i: int, j: int)
- requires a != null;
- requires 0 <= i < j < a.Length;
- modifies a;
- ensures a[i] == old(a[j]);
- ensures a[j] == old(a[i]);
- ensures forall m :: 0 <= m < a.Length && m != i && m != j ==> a[m] == old(a[m]);
- ensures multiset(a[..]) == old(multiset(a[..]));
-{
- var t := a[i];
- a[i] := a[j];
- a[j] := t;
-}
-
-// This method is a direct translation of the pseudo
-// code given in the problem statement.
-// The first postcondition expresses that the resulting
-// array is sorted, that is, all occurrences of "false"
-// come before all occurrences of "true".
-// The second postcondition expresses that the post-state
-// array is a permutation of the pre-state array. To express
-// this, we use Dafny's built-in multisets. The built-in
-// function "multiset" takes an array and yields the
-// multiset of the array elements.
-// Note that Dafny guesses a suitable ranking function
-// for the termination proof of the while loop.
-// We use the loop guard from the given pseudo-code. However,
-// the program also verifies with the stronger guard "i < j"
-// (without changing any of the other specifications or
-// annotations).
-method two_way_sort(a: array<bool>)
- requires a != null;
- modifies a;
- ensures forall m,n :: 0 <= m < n < a.Length ==> (!a[m] || a[n]);
- ensures multiset(a[..]) == old(multiset(a[..]));
-{
- var i := 0;
- var j := a.Length - 1;
- while (i <= j)
- invariant 0 <= i <= j + 1 <= a.Length;
- invariant forall m :: 0 <= m < i ==> !a[m];
- invariant forall n :: j < n < a.Length ==> a[n];
- invariant multiset(a[..]) == old(multiset(a[..]));
- {
- if (!a[i]) {
- i := i+1;
- } else if (a[j]) {
- j := j-1;
- } else {
- swap(a, i, j);
- i := i+1;
- j := j-1;
- }
- }
-}
diff --git a/Test/vstte2012/runtest.bat b/Test/vstte2012/runtest.bat
deleted file mode 100644
index 7f7c9b9f..00000000
--- a/Test/vstte2012/runtest.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@echo off
-setlocal
-
-set BOOGIEDIR=..\..\Binaries
-set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
-
-for %%f in (
- Two-Way-Sort.dfy
- Combinators.dfy
- RingBuffer.dfy RingBufferAuto.dfy
- Tree.dfy
- BreadthFirstSearch.dfy
- ) do (
- echo.
- echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 /dprint:out.dfy.tmp %* %%f
-)