From 962f8d5252b3f5ec4d19e0cd2a430934bd55cc6d Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 28 Jun 2015 01:44:30 +0100 Subject: Normalise line endings using a .gitattributes file. Unfortunately this required that this commit globally modify most files. If you want to use git blame to see the real author of a line use the ``-w`` flag so that whitespace changes are ignored. --- Test/test2/Arrays.bpl | 368 ++--- Test/test2/AssertVerifiedUnder0.bpl | 78 +- Test/test2/AssertVerifiedUnder0.bpl.expect | 22 +- Test/test2/AssumeEnsures.bpl | 142 +- Test/test2/AssumptionVariables0.bpl | 146 +- Test/test2/AssumptionVariables0.bpl.expect | 22 +- Test/test2/Axioms.bpl | 62 +- Test/test2/B.bpl | 176 +-- Test/test2/Call.bpl | 124 +- Test/test2/CallVerifiedUnder0.bpl | 84 +- Test/test2/CallVerifiedUnder0.bpl.expect | 28 +- Test/test2/ContractEvaluationOrder.bpl | 72 +- Test/test2/CutBackEdge.bpl | 84 +- Test/test2/Ensures.bpl | 154 +- Test/test2/False.bpl | 36 +- Test/test2/FormulaTerm.bpl | 282 ++-- Test/test2/FormulaTerm2.bpl | 102 +- Test/test2/FreeCall.bpl | 168 +-- Test/test2/IfThenElse1.bpl | 4 +- Test/test2/Implies.bpl | 76 +- Test/test2/InvariantVerifiedUnder0.bpl | 108 +- Test/test2/InvariantVerifiedUnder0.bpl.expect | 46 +- Test/test2/LambdaOldExpressions.bpl | 126 +- Test/test2/LambdaPoly.bpl | 4 +- Test/test2/LoopInvAssume.bpl | 44 +- Test/test2/NeverPattern.bpl | 140 +- Test/test2/NullaryMaps.bpl | 118 +- Test/test2/Old.bpl | 268 ++-- Test/test2/OldIllegal.bpl | 36 +- Test/test2/Passification.bpl | 342 ++--- Test/test2/Quantifiers.bpl | 312 ++-- Test/test2/SelectiveChecking.bpl | 4 +- Test/test2/Structured.bpl | 692 ++++----- Test/test2/Timeouts0.bpl | 170 +-- Test/test2/TypeEncodingM.bpl | 4 +- Test/test2/UpdateExpr.bpl | 166 +- Test/test2/Where.bpl | 330 ++-- Test/test2/sk_hack.bpl | 68 +- Test/test2/strings-no-where.bpl | 1994 ++++++++++++------------- Test/test2/strings-where.bpl | 1994 ++++++++++++------------- 40 files changed, 4598 insertions(+), 4598 deletions(-) (limited to 'Test/test2') diff --git a/Test/test2/Arrays.bpl b/Test/test2/Arrays.bpl index 5f4bd9c9..2b88be4a 100644 --- a/Test/test2/Arrays.bpl +++ b/Test/test2/Arrays.bpl @@ -1,184 +1,184 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// RUN: %boogie -noinfer -typeEncoding:m "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// -------------------- 1-dimensional arrays -------------------- - -var A: [ref]int; - -procedure P0(o: ref, q: ref, y: int) - requires o != q; - modifies A; - ensures A[o] == old(A[o]) + y; - ensures (forall p: ref :: A[p] == old(A[p]) || p == o); -{ - var k: int; - - start: - k := A[q]; - A[o] := y + A[o]; - A[q] := k; - return; -} - -procedure P1(o: ref, q: ref, y: int) - // This procedure does not have the assumption that o != q. - modifies A; - // It also does not ensures anything about A[o] - ensures (forall p: ref :: A[p] == old(A[p]) || p == o); -{ - var k: int; - - start: - k := A[q]; - A[o] := y + A[o]; - A[q] := k; - return; -} - -procedure P2(o: ref, q: ref, y: int) - // This procedure does not have the assumption that o != q. - modifies A; - ensures A[o] == old(A[o]) + y; -{ - var k: int; - - start: - k := A[q]; - A[o] := y + A[o]; - A[q] := k; - return; -} // error: postcondition violated (if o == q) - -// -------------------- 2-dimensional arrays -------------------- - -var B: [ref,name]int; -const F: name; - -procedure Q0(o: ref, q: ref, y: int, G: name) - requires o != q && F != G; - modifies B; - ensures B[o,F] == old(B[o,F]) + y; - ensures (forall p: ref, f: name :: B[p,f] == old(B[p,f]) || - (p == o && f == F)); -{ - var k: int; - - start: - k := B[q,G]; - B[o,F] := y + B[o,F]; - B[q,G] := k; - return; -} - -procedure Q1(o: ref, q: ref, y: int, G: name) - // This procedure does not have the assumption that o != q && F != G. - modifies B; - // It also does not ensures anything about B[o,F] - ensures (forall p: ref, f: name :: B[p,f] == old(B[p,f]) || - (p == o && f == F)); -{ - var k: int; - - start: - k := B[q,G]; - B[o,F] := y + B[o,F]; - B[q,G] := k; - return; -} - -procedure Q2(o: ref, q: ref, y: int, G: name) - requires F != G; - // This procedure does not have the assumption that o != q. - modifies B; - ensures B[o,F] == old(B[o,F]) + y; -{ - var k: int; - - start: - k := B[q,G]; - B[o,F] := y + B[o,F]; - B[q,G] := k; - return; -} - -procedure Q3(o: ref, q: ref, y: int, G: name) - requires o != q; - // This procedure does not have the assumption that F != G. - modifies B; - ensures B[o,F] == old(B[o,F]) + y; -{ - var k: int; - - start: - k := B[q,G]; - B[o,F] := y + B[o,F]; - B[q,G] := k; - return; -} - -procedure Q4(o: ref, q: ref, y: int, G: name) - // This procedure does not have either of the assumptions o != q and F != G. - modifies B; - ensures B[o,F] == old(B[o,F]) + y; -{ - var k: int; - - start: - k := B[q,G]; - B[o,F] := y + B[o,F]; - B[q,G] := k; - return; -} // error: postcondition violated - -// -------------------- more tests -------------------- - -procedure Skip0(o: ref, q: ref, G: name, H: name) - modifies A,B; - ensures (forall p: ref :: A[p] == old(A[p])); - ensures (forall p: ref, g: name :: B[p,g] == old(B[p,g])); -{ - start: - return; -} - -procedure Skip1(o: ref, q: ref, G: name, H: name) - modifies A,B; - ensures (forall p: ref :: A[p] == old(A[p])); - ensures (forall p: ref, g: name :: B[p,g] == old(B[p,g])); -{ - var k: int; - var l: int; - - start: - k := A[o]; - l := A[q]; - goto oneWay, theOtherWay; - - oneWay: - A[o] := k; - A[q] := l; - goto next; - - theOtherWay: - A[q] := l; - A[o] := k; - goto next; - - next: - k := B[o,G]; - l := B[q,H]; - goto Lx, Ly; - - Lx: - B[o,G] := k; - B[q,H] := l; - return; - - Ly: - B[q,H] := l; - B[o,G] := k; - return; -} - -type name, ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// RUN: %boogie -noinfer -typeEncoding:m "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// -------------------- 1-dimensional arrays -------------------- + +var A: [ref]int; + +procedure P0(o: ref, q: ref, y: int) + requires o != q; + modifies A; + ensures A[o] == old(A[o]) + y; + ensures (forall p: ref :: A[p] == old(A[p]) || p == o); +{ + var k: int; + + start: + k := A[q]; + A[o] := y + A[o]; + A[q] := k; + return; +} + +procedure P1(o: ref, q: ref, y: int) + // This procedure does not have the assumption that o != q. + modifies A; + // It also does not ensures anything about A[o] + ensures (forall p: ref :: A[p] == old(A[p]) || p == o); +{ + var k: int; + + start: + k := A[q]; + A[o] := y + A[o]; + A[q] := k; + return; +} + +procedure P2(o: ref, q: ref, y: int) + // This procedure does not have the assumption that o != q. + modifies A; + ensures A[o] == old(A[o]) + y; +{ + var k: int; + + start: + k := A[q]; + A[o] := y + A[o]; + A[q] := k; + return; +} // error: postcondition violated (if o == q) + +// -------------------- 2-dimensional arrays -------------------- + +var B: [ref,name]int; +const F: name; + +procedure Q0(o: ref, q: ref, y: int, G: name) + requires o != q && F != G; + modifies B; + ensures B[o,F] == old(B[o,F]) + y; + ensures (forall p: ref, f: name :: B[p,f] == old(B[p,f]) || + (p == o && f == F)); +{ + var k: int; + + start: + k := B[q,G]; + B[o,F] := y + B[o,F]; + B[q,G] := k; + return; +} + +procedure Q1(o: ref, q: ref, y: int, G: name) + // This procedure does not have the assumption that o != q && F != G. + modifies B; + // It also does not ensures anything about B[o,F] + ensures (forall p: ref, f: name :: B[p,f] == old(B[p,f]) || + (p == o && f == F)); +{ + var k: int; + + start: + k := B[q,G]; + B[o,F] := y + B[o,F]; + B[q,G] := k; + return; +} + +procedure Q2(o: ref, q: ref, y: int, G: name) + requires F != G; + // This procedure does not have the assumption that o != q. + modifies B; + ensures B[o,F] == old(B[o,F]) + y; +{ + var k: int; + + start: + k := B[q,G]; + B[o,F] := y + B[o,F]; + B[q,G] := k; + return; +} + +procedure Q3(o: ref, q: ref, y: int, G: name) + requires o != q; + // This procedure does not have the assumption that F != G. + modifies B; + ensures B[o,F] == old(B[o,F]) + y; +{ + var k: int; + + start: + k := B[q,G]; + B[o,F] := y + B[o,F]; + B[q,G] := k; + return; +} + +procedure Q4(o: ref, q: ref, y: int, G: name) + // This procedure does not have either of the assumptions o != q and F != G. + modifies B; + ensures B[o,F] == old(B[o,F]) + y; +{ + var k: int; + + start: + k := B[q,G]; + B[o,F] := y + B[o,F]; + B[q,G] := k; + return; +} // error: postcondition violated + +// -------------------- more tests -------------------- + +procedure Skip0(o: ref, q: ref, G: name, H: name) + modifies A,B; + ensures (forall p: ref :: A[p] == old(A[p])); + ensures (forall p: ref, g: name :: B[p,g] == old(B[p,g])); +{ + start: + return; +} + +procedure Skip1(o: ref, q: ref, G: name, H: name) + modifies A,B; + ensures (forall p: ref :: A[p] == old(A[p])); + ensures (forall p: ref, g: name :: B[p,g] == old(B[p,g])); +{ + var k: int; + var l: int; + + start: + k := A[o]; + l := A[q]; + goto oneWay, theOtherWay; + + oneWay: + A[o] := k; + A[q] := l; + goto next; + + theOtherWay: + A[q] := l; + A[o] := k; + goto next; + + next: + k := B[o,G]; + l := B[q,H]; + goto Lx, Ly; + + Lx: + B[o,G] := k; + B[q,H] := l; + return; + + Ly: + B[q,H] := l; + B[o,G] := k; + return; +} + +type name, ref; diff --git a/Test/test2/AssertVerifiedUnder0.bpl b/Test/test2/AssertVerifiedUnder0.bpl index 9e82545f..76d7660e 100644 --- a/Test/test2/AssertVerifiedUnder0.bpl +++ b/Test/test2/AssertVerifiedUnder0.bpl @@ -1,39 +1,39 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - -procedure Test0() -{ - assert {:verified_under false} false; // error -} - - -procedure Test1() -{ - assert {:verified_under true} false; -} - - -procedure Test2(P: bool, A: bool) -{ - assert {:verified_under A} P; // error -} - - -procedure Test3(P: bool, A: bool) - requires !A ==> P; -{ - assert {:verified_under A} P; -} - - -procedure Test4(P: bool, A: bool) -{ - assert {:verified_under A} {:verified_under true} P; // error -} - - -procedure Test5(P: bool, A: bool) - requires !A ==> P; -{ - assert {:verified_under A} {:verified_under true} P; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +procedure Test0() +{ + assert {:verified_under false} false; // error +} + + +procedure Test1() +{ + assert {:verified_under true} false; +} + + +procedure Test2(P: bool, A: bool) +{ + assert {:verified_under A} P; // error +} + + +procedure Test3(P: bool, A: bool) + requires !A ==> P; +{ + assert {:verified_under A} P; +} + + +procedure Test4(P: bool, A: bool) +{ + assert {:verified_under A} {:verified_under true} P; // error +} + + +procedure Test5(P: bool, A: bool) + requires !A ==> P; +{ + assert {:verified_under A} {:verified_under true} P; +} diff --git a/Test/test2/AssertVerifiedUnder0.bpl.expect b/Test/test2/AssertVerifiedUnder0.bpl.expect index 83016c63..7fa23f60 100644 --- a/Test/test2/AssertVerifiedUnder0.bpl.expect +++ b/Test/test2/AssertVerifiedUnder0.bpl.expect @@ -1,11 +1,11 @@ -AssertVerifiedUnder0.bpl(6,5): Error BP5001: This assertion might not hold. -Execution trace: - AssertVerifiedUnder0.bpl(6,5): anon0 -AssertVerifiedUnder0.bpl(18,5): Error BP5001: This assertion might not hold. -Execution trace: - AssertVerifiedUnder0.bpl(18,5): anon0 -AssertVerifiedUnder0.bpl(31,5): Error BP5001: This assertion might not hold. -Execution trace: - AssertVerifiedUnder0.bpl(31,5): anon0 - -Boogie program verifier finished with 3 verified, 3 errors +AssertVerifiedUnder0.bpl(6,5): Error BP5001: This assertion might not hold. +Execution trace: + AssertVerifiedUnder0.bpl(6,5): anon0 +AssertVerifiedUnder0.bpl(18,5): Error BP5001: This assertion might not hold. +Execution trace: + AssertVerifiedUnder0.bpl(18,5): anon0 +AssertVerifiedUnder0.bpl(31,5): Error BP5001: This assertion might not hold. +Execution trace: + AssertVerifiedUnder0.bpl(31,5): anon0 + +Boogie program verifier finished with 3 verified, 3 errors diff --git a/Test/test2/AssumeEnsures.bpl b/Test/test2/AssumeEnsures.bpl index 74789135..2c5ad6a2 100644 --- a/Test/test2/AssumeEnsures.bpl +++ b/Test/test2/AssumeEnsures.bpl @@ -1,71 +1,71 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -var g: int; - -procedure Foo() returns (); - modifies g; - free ensures 0 <= g; - -implementation Foo() returns () -{ - entry: - g := g + 1; - return; -} - -procedure BarGood() returns () - modifies g; -{ - entry: - call Foo(); - assert 0 <= g; - return; -} - -procedure BarBad() returns () - modifies g; -{ - entry: - call Foo(); - assert 0 < g; - return; -} - -// ----- Free preconditions - -procedure Proc() returns (); - free requires g == 15; - -implementation Proc() returns () -{ - entry: - assert g > 10; // yes, this condition can be used here - return; -} - -implementation Proc() returns () -{ - entry: - assert g < 10; // error - return; -} - -procedure Caller0() returns () -{ - entry: - call Proc(); // yes, legal, since the precondition is not checked - return; -} - -procedure Caller1() returns () -{ - entry: - call Proc(); - assert g > 10; // error, because: - // Free preconditions are ignored (that is, treated as "skip") for the caller. - // This is a BoogiePL design choice. Another alternative would be to treat free - // preconditions as assume commands also on the caller side, either in the order - // that all preconditions are given, or before or after all the checked preconditions - // have been checked. - return; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +var g: int; + +procedure Foo() returns (); + modifies g; + free ensures 0 <= g; + +implementation Foo() returns () +{ + entry: + g := g + 1; + return; +} + +procedure BarGood() returns () + modifies g; +{ + entry: + call Foo(); + assert 0 <= g; + return; +} + +procedure BarBad() returns () + modifies g; +{ + entry: + call Foo(); + assert 0 < g; + return; +} + +// ----- Free preconditions + +procedure Proc() returns (); + free requires g == 15; + +implementation Proc() returns () +{ + entry: + assert g > 10; // yes, this condition can be used here + return; +} + +implementation Proc() returns () +{ + entry: + assert g < 10; // error + return; +} + +procedure Caller0() returns () +{ + entry: + call Proc(); // yes, legal, since the precondition is not checked + return; +} + +procedure Caller1() returns () +{ + entry: + call Proc(); + assert g > 10; // error, because: + // Free preconditions are ignored (that is, treated as "skip") for the caller. + // This is a BoogiePL design choice. Another alternative would be to treat free + // preconditions as assume commands also on the caller side, either in the order + // that all preconditions are given, or before or after all the checked preconditions + // have been checked. + return; +} diff --git a/Test/test2/AssumptionVariables0.bpl b/Test/test2/AssumptionVariables0.bpl index 766c9d1e..84bf14ad 100644 --- a/Test/test2/AssumptionVariables0.bpl +++ b/Test/test2/AssumptionVariables0.bpl @@ -1,73 +1,73 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure Test0() -{ - var {:assumption} a0: bool; - - assert a0; -} - - -procedure Test1(n: int) -{ - var {:assumption} a0: bool; - - a0 := a0 && (0 <= n); - - assert a0; // error -} - - -procedure Test2() -{ - var {:assumption} a0: bool; - - havoc a0; - - assert a0; // error -} - - -var {:assumption} ga0: bool; - - -procedure Test3() - modifies ga0; -{ - ga0 := ga0 && true; - - assert ga0; // error -} - - -procedure Test4() -{ - var {:assumption} a0: bool; - var tmp: bool; - - tmp := a0; - - havoc a0; - - assert a0 ==> tmp; -} - - -procedure Test5(A: bool) -{ - var {:assumption} a0: bool; - var tmp0, tmp1: bool; - - a0 := a0 && A; - tmp0 := a0; - - havoc a0; - - assert a0 ==> tmp0; - - tmp1 := a0; - - havoc a0; - - assert a0 ==> tmp1; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure Test0() +{ + var {:assumption} a0: bool; + + assert a0; +} + + +procedure Test1(n: int) +{ + var {:assumption} a0: bool; + + a0 := a0 && (0 <= n); + + assert a0; // error +} + + +procedure Test2() +{ + var {:assumption} a0: bool; + + havoc a0; + + assert a0; // error +} + + +var {:assumption} ga0: bool; + + +procedure Test3() + modifies ga0; +{ + ga0 := ga0 && true; + + assert ga0; // error +} + + +procedure Test4() +{ + var {:assumption} a0: bool; + var tmp: bool; + + tmp := a0; + + havoc a0; + + assert a0 ==> tmp; +} + + +procedure Test5(A: bool) +{ + var {:assumption} a0: bool; + var tmp0, tmp1: bool; + + a0 := a0 && A; + tmp0 := a0; + + havoc a0; + + assert a0 ==> tmp0; + + tmp1 := a0; + + havoc a0; + + assert a0 ==> tmp1; +} diff --git a/Test/test2/AssumptionVariables0.bpl.expect b/Test/test2/AssumptionVariables0.bpl.expect index 44292082..284a41ad 100644 --- a/Test/test2/AssumptionVariables0.bpl.expect +++ b/Test/test2/AssumptionVariables0.bpl.expect @@ -1,11 +1,11 @@ -AssumptionVariables0.bpl(17,5): Error BP5001: This assertion might not hold. -Execution trace: - AssumptionVariables0.bpl(15,8): anon0 -AssumptionVariables0.bpl(27,5): Error BP5001: This assertion might not hold. -Execution trace: - AssumptionVariables0.bpl(25,5): anon0 -AssumptionVariables0.bpl(39,5): Error BP5001: This assertion might not hold. -Execution trace: - AssumptionVariables0.bpl(37,9): anon0 - -Boogie program verifier finished with 3 verified, 3 errors +AssumptionVariables0.bpl(17,5): Error BP5001: This assertion might not hold. +Execution trace: + AssumptionVariables0.bpl(15,8): anon0 +AssumptionVariables0.bpl(27,5): Error BP5001: This assertion might not hold. +Execution trace: + AssumptionVariables0.bpl(25,5): anon0 +AssumptionVariables0.bpl(39,5): Error BP5001: This assertion might not hold. +Execution trace: + AssumptionVariables0.bpl(37,9): anon0 + +Boogie program verifier finished with 3 verified, 3 errors diff --git a/Test/test2/Axioms.bpl b/Test/test2/Axioms.bpl index 1fa8fab3..51d9ed00 100644 --- a/Test/test2/Axioms.bpl +++ b/Test/test2/Axioms.bpl @@ -1,31 +1,31 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -const Seven: int; -axiom Seven == 7; - -function inc(int) returns (int); -axiom (forall j: int :: inc(j) == j+1); - -procedure P() -{ - start: - assert 4 <= Seven; - assert Seven < inc(Seven); - assert inc(5) + inc(inc(2)) == Seven + 3; - return; -} - -procedure Q() -{ - start: - assert inc(5) + inc(inc(2)) == Seven; // error - return; -} - -function inc2(x:int) returns(int) { x + 2 } - -procedure ExpandTest() -{ - var q:int; - assert inc(inc(q)) == inc2(q); -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +const Seven: int; +axiom Seven == 7; + +function inc(int) returns (int); +axiom (forall j: int :: inc(j) == j+1); + +procedure P() +{ + start: + assert 4 <= Seven; + assert Seven < inc(Seven); + assert inc(5) + inc(inc(2)) == Seven + 3; + return; +} + +procedure Q() +{ + start: + assert inc(5) + inc(inc(2)) == Seven; // error + return; +} + +function inc2(x:int) returns(int) { x + 2 } + +procedure ExpandTest() +{ + var q:int; + assert inc(inc(q)) == inc2(q); +} diff --git a/Test/test2/B.bpl b/Test/test2/B.bpl index 78f91915..c90c156b 100644 --- a/Test/test2/B.bpl +++ b/Test/test2/B.bpl @@ -1,88 +1,88 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// ----------- BEGIN PRELUDE - -var Heap: [ref, name]int; -const N: name; - -procedure Q0() -{ - var h: int; - - entry: - goto Else; - - Then: - h := 15; - goto end; - - Else: - assume h == 0; - goto end; - - end: - assert 0 <= h; - return; -} - -procedure Q1() -{ - var h: int; - - entry: - goto Else; - - Then: - h := -15; - goto end; - - Else: - assume h == 0; - goto end; - - end: - h := -h; - assert 0 <= h; - return; -} - -procedure P0(this: ref) - modifies Heap; -{ - entry: - goto Else; - - Then: - Heap[this, N] := 15; - goto end; - - Else: - assume Heap[this, N] == 0; - goto end; - - end: - assert 0 <= Heap[this, N]; - return; -} - -procedure P1(this: ref) - modifies Heap; -{ - entry: - goto Else; - - Then: - Heap[this, N] := -15; - goto end; - - Else: - assume Heap[this, N] == 0; - goto end; - - end: - Heap[this, N] := -Heap[this, N]; - assert 0 <= Heap[this, N]; - return; -} - -type name, ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// ----------- BEGIN PRELUDE + +var Heap: [ref, name]int; +const N: name; + +procedure Q0() +{ + var h: int; + + entry: + goto Else; + + Then: + h := 15; + goto end; + + Else: + assume h == 0; + goto end; + + end: + assert 0 <= h; + return; +} + +procedure Q1() +{ + var h: int; + + entry: + goto Else; + + Then: + h := -15; + goto end; + + Else: + assume h == 0; + goto end; + + end: + h := -h; + assert 0 <= h; + return; +} + +procedure P0(this: ref) + modifies Heap; +{ + entry: + goto Else; + + Then: + Heap[this, N] := 15; + goto end; + + Else: + assume Heap[this, N] == 0; + goto end; + + end: + assert 0 <= Heap[this, N]; + return; +} + +procedure P1(this: ref) + modifies Heap; +{ + entry: + goto Else; + + Then: + Heap[this, N] := -15; + goto end; + + Else: + assume Heap[this, N] == 0; + goto end; + + end: + Heap[this, N] := -Heap[this, N]; + assert 0 <= Heap[this, N]; + return; +} + +type name, ref; diff --git a/Test/test2/Call.bpl b/Test/test2/Call.bpl index bf2690cc..bb67c3dc 100644 --- a/Test/test2/Call.bpl +++ b/Test/test2/Call.bpl @@ -1,62 +1,62 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure Bar() returns (barresult: ref); - -procedure Foo(); - -implementation Foo() -{ - var x: ref; - - entry: - call x := Bar(); - assume x == null; - call x := Bar(); - assert x == null; - return; - -} - -procedure DifferentFormalNames(x: int, y: int) returns (z: int); - requires x < y; - ensures z == x; - -implementation DifferentFormalNames(x: int, y: int) returns (z: int) -{ - start: - assert x < y; - z := x; - return; -} - -implementation DifferentFormalNames(y: int, x: int) returns (w: int) -{ - start: - goto A, B; - A: - assert y < x; - assume false; - return; - B: - w := y; - return; -} - -implementation DifferentFormalNames(y: int, x: int) returns (w: int) -{ - start: - assert x < y; // error - w := y; - return; -} - -implementation DifferentFormalNames(y: int, x: int) returns (w: int) -{ - start: - w := x; - return; // error: postcondition violation -} - -type ref; - -const null : ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure Bar() returns (barresult: ref); + +procedure Foo(); + +implementation Foo() +{ + var x: ref; + + entry: + call x := Bar(); + assume x == null; + call x := Bar(); + assert x == null; + return; + +} + +procedure DifferentFormalNames(x: int, y: int) returns (z: int); + requires x < y; + ensures z == x; + +implementation DifferentFormalNames(x: int, y: int) returns (z: int) +{ + start: + assert x < y; + z := x; + return; +} + +implementation DifferentFormalNames(y: int, x: int) returns (w: int) +{ + start: + goto A, B; + A: + assert y < x; + assume false; + return; + B: + w := y; + return; +} + +implementation DifferentFormalNames(y: int, x: int) returns (w: int) +{ + start: + assert x < y; // error + w := y; + return; +} + +implementation DifferentFormalNames(y: int, x: int) returns (w: int) +{ + start: + w := x; + return; // error: postcondition violation +} + +type ref; + +const null : ref; diff --git a/Test/test2/CallVerifiedUnder0.bpl b/Test/test2/CallVerifiedUnder0.bpl index 9ac9dec7..5d99ec53 100644 --- a/Test/test2/CallVerifiedUnder0.bpl +++ b/Test/test2/CallVerifiedUnder0.bpl @@ -1,42 +1,42 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - -procedure A(P: bool); - requires P; - -procedure Test0() -{ - call {:verified_under false} A(false); // error -} - - -procedure Test1() -{ - call {:verified_under true} A(false); -} - - -procedure Test2(P: bool, A: bool) -{ - call {:verified_under A} A(P); // error -} - - -procedure Test3(P: bool, A: bool) - requires !A ==> P; -{ - call {:verified_under A} A(P); -} - - -procedure Test4(P: bool, A: bool) -{ - call {:verified_under A} {:verified_under true} A(P); // error -} - - -procedure Test5(P: bool, A: bool) - requires !A ==> P; -{ - call {:verified_under A} {:verified_under true} A(P); -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +procedure A(P: bool); + requires P; + +procedure Test0() +{ + call {:verified_under false} A(false); // error +} + + +procedure Test1() +{ + call {:verified_under true} A(false); +} + + +procedure Test2(P: bool, A: bool) +{ + call {:verified_under A} A(P); // error +} + + +procedure Test3(P: bool, A: bool) + requires !A ==> P; +{ + call {:verified_under A} A(P); +} + + +procedure Test4(P: bool, A: bool) +{ + call {:verified_under A} {:verified_under true} A(P); // error +} + + +procedure Test5(P: bool, A: bool) + requires !A ==> P; +{ + call {:verified_under A} {:verified_under true} A(P); +} diff --git a/Test/test2/CallVerifiedUnder0.bpl.expect b/Test/test2/CallVerifiedUnder0.bpl.expect index 5d407874..90949273 100644 --- a/Test/test2/CallVerifiedUnder0.bpl.expect +++ b/Test/test2/CallVerifiedUnder0.bpl.expect @@ -1,14 +1,14 @@ -CallVerifiedUnder0.bpl(9,5): Error BP5002: A precondition for this call might not hold. -CallVerifiedUnder0.bpl(5,3): Related location: This is the precondition that might not hold. -Execution trace: - CallVerifiedUnder0.bpl(9,5): anon0 -CallVerifiedUnder0.bpl(21,5): Error BP5002: A precondition for this call might not hold. -CallVerifiedUnder0.bpl(5,3): Related location: This is the precondition that might not hold. -Execution trace: - CallVerifiedUnder0.bpl(21,5): anon0 -CallVerifiedUnder0.bpl(34,5): Error BP5002: A precondition for this call might not hold. -CallVerifiedUnder0.bpl(5,3): Related location: This is the precondition that might not hold. -Execution trace: - CallVerifiedUnder0.bpl(34,5): anon0 - -Boogie program verifier finished with 3 verified, 3 errors +CallVerifiedUnder0.bpl(9,5): Error BP5002: A precondition for this call might not hold. +CallVerifiedUnder0.bpl(5,3): Related location: This is the precondition that might not hold. +Execution trace: + CallVerifiedUnder0.bpl(9,5): anon0 +CallVerifiedUnder0.bpl(21,5): Error BP5002: A precondition for this call might not hold. +CallVerifiedUnder0.bpl(5,3): Related location: This is the precondition that might not hold. +Execution trace: + CallVerifiedUnder0.bpl(21,5): anon0 +CallVerifiedUnder0.bpl(34,5): Error BP5002: A precondition for this call might not hold. +CallVerifiedUnder0.bpl(5,3): Related location: This is the precondition that might not hold. +Execution trace: + CallVerifiedUnder0.bpl(34,5): anon0 + +Boogie program verifier finished with 3 verified, 3 errors diff --git a/Test/test2/ContractEvaluationOrder.bpl b/Test/test2/ContractEvaluationOrder.bpl index 8719dcfa..4115c4b0 100644 --- a/Test/test2/ContractEvaluationOrder.bpl +++ b/Test/test2/ContractEvaluationOrder.bpl @@ -1,36 +1,36 @@ -// RUN: %boogie "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure P() returns (x, y: int) - ensures x == y; // ensured by the body - ensures x == 0; // error: not ensured by the body - ensures y == 0; // follows from the previous two ensures clauses (provided they are - // indeed evaluated in this order, which they are supposed to be) -{ - x := y; -} - -procedure Q() returns (x, y: int) -{ - x := y; - - assert x == y; // ensured by the body - assert x == 0; // error: not ensured by the body - assert y == 0; // follows from the previous two asserts (provided they are - // indeed evaluated in this order, which they are supposed to be) -} - -procedure R() -{ - var a, b: int; - a := b; - call S(a, b); -} - -procedure S(x, y: int) - // In the call from R: - requires x == y; // ensured by the body of R - requires x == 0; // error: not ensured by the body of R - requires y == 0; // follows from the previous two requires clauses (provided they are - // indeed evaluated in this order, which they are supposed to be) -{ -} +// RUN: %boogie "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure P() returns (x, y: int) + ensures x == y; // ensured by the body + ensures x == 0; // error: not ensured by the body + ensures y == 0; // follows from the previous two ensures clauses (provided they are + // indeed evaluated in this order, which they are supposed to be) +{ + x := y; +} + +procedure Q() returns (x, y: int) +{ + x := y; + + assert x == y; // ensured by the body + assert x == 0; // error: not ensured by the body + assert y == 0; // follows from the previous two asserts (provided they are + // indeed evaluated in this order, which they are supposed to be) +} + +procedure R() +{ + var a, b: int; + a := b; + call S(a, b); +} + +procedure S(x, y: int) + // In the call from R: + requires x == y; // ensured by the body of R + requires x == 0; // error: not ensured by the body of R + requires y == 0; // follows from the previous two requires clauses (provided they are + // indeed evaluated in this order, which they are supposed to be) +{ +} diff --git a/Test/test2/CutBackEdge.bpl b/Test/test2/CutBackEdge.bpl index 2ee7cd68..4d507c1e 100644 --- a/Test/test2/CutBackEdge.bpl +++ b/Test/test2/CutBackEdge.bpl @@ -1,42 +1,42 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure Test() -{ - var i: int; - - entry: - i := 0; - goto block850; - - block850: - assert i == 0; - havoc i; - goto block850; - -} - -// The following procedure once exhibited a bug in Boogie's DAG manipulations -procedure TightLoop0() -{ - L: - assert !true; // error - goto L; -} -procedure TightLoop1() -{ - L: - assert false; // error - goto L; -} -procedure TightLoop2() -{ - L: - assert true; // cool - goto L; -} -procedure TightLoop3(b: bool) -{ - L: - assert b; // error - goto L; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure Test() +{ + var i: int; + + entry: + i := 0; + goto block850; + + block850: + assert i == 0; + havoc i; + goto block850; + +} + +// The following procedure once exhibited a bug in Boogie's DAG manipulations +procedure TightLoop0() +{ + L: + assert !true; // error + goto L; +} +procedure TightLoop1() +{ + L: + assert false; // error + goto L; +} +procedure TightLoop2() +{ + L: + assert true; // cool + goto L; +} +procedure TightLoop3(b: bool) +{ + L: + assert b; // error + goto L; +} diff --git a/Test/test2/Ensures.bpl b/Test/test2/Ensures.bpl index c37e31a0..16f6105f 100644 --- a/Test/test2/Ensures.bpl +++ b/Test/test2/Ensures.bpl @@ -1,77 +1,77 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -var H: [ref,name]int; -var that: ref; - -const X: name; -const Y: name; - -procedure P(this: ref); - modifies H; - ensures H[this,X] == 5; - -implementation P(this: ref) { - start: - H[this,X] := 5; - return; -} - -procedure Q(this: ref); - modifies H; - ensures (forall o: ref, F: name :: o == this && F == X ==> H[o,F] == 5); - -implementation Q(this: ref) { - start: - H[this,X] := 5; - return; -} - -implementation Q(this: ref) { - start: - H[this,X] := 7; - return; // error -} - -implementation Q(this: ref) { - start: - return; // error -} - -implementation Q(this: ref) { - start: - H[that,X] := 5; - return; // error -} - -implementation Q(this: ref) { - start: - H[this,Y] := 5; - return; // error -} - -implementation Q(this: ref) { - start: - call P(this); - return; -} - -implementation Q(this: ref) { - start: - call Q(this); - return; -} - -implementation Q(this: ref) { - start: - call P(this); - call Q(this); - return; -} - -implementation Q(this: ref) { - start: - call P(that); - return; // error -} - -type name, ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +var H: [ref,name]int; +var that: ref; + +const X: name; +const Y: name; + +procedure P(this: ref); + modifies H; + ensures H[this,X] == 5; + +implementation P(this: ref) { + start: + H[this,X] := 5; + return; +} + +procedure Q(this: ref); + modifies H; + ensures (forall o: ref, F: name :: o == this && F == X ==> H[o,F] == 5); + +implementation Q(this: ref) { + start: + H[this,X] := 5; + return; +} + +implementation Q(this: ref) { + start: + H[this,X] := 7; + return; // error +} + +implementation Q(this: ref) { + start: + return; // error +} + +implementation Q(this: ref) { + start: + H[that,X] := 5; + return; // error +} + +implementation Q(this: ref) { + start: + H[this,Y] := 5; + return; // error +} + +implementation Q(this: ref) { + start: + call P(this); + return; +} + +implementation Q(this: ref) { + start: + call Q(this); + return; +} + +implementation Q(this: ref) { + start: + call P(this); + call Q(this); + return; +} + +implementation Q(this: ref) { + start: + call P(that); + return; // error +} + +type name, ref; diff --git a/Test/test2/False.bpl b/Test/test2/False.bpl index a0337182..54b95e2e 100644 --- a/Test/test2/False.bpl +++ b/Test/test2/False.bpl @@ -1,18 +1,18 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure Test1() -{ - entry: - assert !true == false; - return; -} - -procedure Test2() -{ - var b: bool; - - entry: - assume b != false; - assert b; - return; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure Test1() +{ + entry: + assert !true == false; + return; +} + +procedure Test2() +{ + var b: bool; + + entry: + assume b != false; + assert b; + return; +} diff --git a/Test/test2/FormulaTerm.bpl b/Test/test2/FormulaTerm.bpl index 7e762afe..41c2f441 100644 --- a/Test/test2/FormulaTerm.bpl +++ b/Test/test2/FormulaTerm.bpl @@ -1,141 +1,141 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// Test formula-term distinction in Simplify - -procedure plus(x: int, y: int) returns (z: int); - ensures z == x + y; - -implementation plus(x: int, y: int) returns (z: int) -{ -start: - assume z == 3; - return; // ERROR: postcondition possibly violated -} - -implementation plus(x: int, y: int) returns (z: int) -{ -start: - z := x + y; - return; -} - -implementation plus(x: int, y: int) returns (z: int) -{ -start: - z := x + y; - z := 0 + z; - return; -} - -procedure plus2(x: int, y: int) returns (z: int) - ensures z == x + y; -{ -start: - z := x + y; - return; -} - -procedure or(x: int, y: int, a: int, b: int) returns (z: int) - requires a == b; -{ -var t: bool; -start: - t := (x < y || x > y || x == y || x != y) && a >= b && a <= b; - assert (x < y || x > y || x == y || x != y) && a >= b && a <= b; - assert t; - return; -} - -procedure less(x: int, y: int) returns (z: bool); - requires x < y; - ensures z == (x < y); - -implementation less(x: int, y: int) returns (z: bool) -{ -start: - z := x < y; - return; -} - -implementation less(x: int, y: int) returns (z: bool) -{ -start: - goto yes, no; -yes: - assume x < y; - z := true; - return; -no: - assume !(x < y); - z := false; - return; -} - -implementation less(x: int, y: int) returns (z: bool) -{ -start: - goto yes, no; -yes: - assume x < y; - z := true; - return; -no: - assume x >= y; - z := false; - return; -} - -procedure LESS(x: int, y: int) returns (z: bool); - requires x < y; - ensures z <==> (x < y); - -implementation LESS(x: int, y: int) returns (z: bool) -{ -start: - z := x < y; - return; -} - -implementation LESS(x: int, y: int) returns (z: bool) -{ -start: - goto yes, no; -yes: - assume x < y; - z := true; - return; -no: - assume !(x < y); - z := false; - return; -} - -implementation LESS(x: int, y: int) returns (z: bool) -{ -start: - goto yes, no; -yes: - assume x < y; - z := true; - return; -no: - assume x >= y; - z := false; - return; -} - -procedure Assignments() -{ - var b: bool; - var c: bool; - var d: bool; - var x: bool, y: bool; - - entry: - b := c || d; - b := c && d; - x := c <==> d; - y := c ==> d; - assert x ==> y; - return; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// Test formula-term distinction in Simplify + +procedure plus(x: int, y: int) returns (z: int); + ensures z == x + y; + +implementation plus(x: int, y: int) returns (z: int) +{ +start: + assume z == 3; + return; // ERROR: postcondition possibly violated +} + +implementation plus(x: int, y: int) returns (z: int) +{ +start: + z := x + y; + return; +} + +implementation plus(x: int, y: int) returns (z: int) +{ +start: + z := x + y; + z := 0 + z; + return; +} + +procedure plus2(x: int, y: int) returns (z: int) + ensures z == x + y; +{ +start: + z := x + y; + return; +} + +procedure or(x: int, y: int, a: int, b: int) returns (z: int) + requires a == b; +{ +var t: bool; +start: + t := (x < y || x > y || x == y || x != y) && a >= b && a <= b; + assert (x < y || x > y || x == y || x != y) && a >= b && a <= b; + assert t; + return; +} + +procedure less(x: int, y: int) returns (z: bool); + requires x < y; + ensures z == (x < y); + +implementation less(x: int, y: int) returns (z: bool) +{ +start: + z := x < y; + return; +} + +implementation less(x: int, y: int) returns (z: bool) +{ +start: + goto yes, no; +yes: + assume x < y; + z := true; + return; +no: + assume !(x < y); + z := false; + return; +} + +implementation less(x: int, y: int) returns (z: bool) +{ +start: + goto yes, no; +yes: + assume x < y; + z := true; + return; +no: + assume x >= y; + z := false; + return; +} + +procedure LESS(x: int, y: int) returns (z: bool); + requires x < y; + ensures z <==> (x < y); + +implementation LESS(x: int, y: int) returns (z: bool) +{ +start: + z := x < y; + return; +} + +implementation LESS(x: int, y: int) returns (z: bool) +{ +start: + goto yes, no; +yes: + assume x < y; + z := true; + return; +no: + assume !(x < y); + z := false; + return; +} + +implementation LESS(x: int, y: int) returns (z: bool) +{ +start: + goto yes, no; +yes: + assume x < y; + z := true; + return; +no: + assume x >= y; + z := false; + return; +} + +procedure Assignments() +{ + var b: bool; + var c: bool; + var d: bool; + var x: bool, y: bool; + + entry: + b := c || d; + b := c && d; + x := c <==> d; + y := c ==> d; + assert x ==> y; + return; +} diff --git a/Test/test2/FormulaTerm2.bpl b/Test/test2/FormulaTerm2.bpl index 14ae5dab..8a2b0ceb 100644 --- a/Test/test2/FormulaTerm2.bpl +++ b/Test/test2/FormulaTerm2.bpl @@ -1,51 +1,51 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// This file has been created to test some of the formula/term issues in Zap. -// However, the test harness does not specify any particular prover to be used, -// since these tests should pass regardless of which prover is used. - -procedure P() -{ - var a: int, b: int, t: bool; - - start: - assume a == b; - t := a == b; - assert t; - return; -} - -function f(bool) returns (int); -const A: int; -const B: int; - -axiom f(A < B) == 5; - -procedure Q() -{ - start: - assume A < B; - assert f(true) == 5; - return; -} - -// ----- and now some erroneous procedures - -procedure PX() -{ - var a: int, b: int, t: bool; - - start: - assume a == b; - t := a == b; - assert !t; // error - return; -} - -procedure QX() -{ - start: - assume A < B; - assert f(true) < 2; // error - return; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// This file has been created to test some of the formula/term issues in Zap. +// However, the test harness does not specify any particular prover to be used, +// since these tests should pass regardless of which prover is used. + +procedure P() +{ + var a: int, b: int, t: bool; + + start: + assume a == b; + t := a == b; + assert t; + return; +} + +function f(bool) returns (int); +const A: int; +const B: int; + +axiom f(A < B) == 5; + +procedure Q() +{ + start: + assume A < B; + assert f(true) == 5; + return; +} + +// ----- and now some erroneous procedures + +procedure PX() +{ + var a: int, b: int, t: bool; + + start: + assume a == b; + t := a == b; + assert !t; // error + return; +} + +procedure QX() +{ + start: + assume A < B; + assert f(true) < 2; // error + return; +} diff --git a/Test/test2/FreeCall.bpl b/Test/test2/FreeCall.bpl index 16f182d9..3bd21e21 100644 --- a/Test/test2/FreeCall.bpl +++ b/Test/test2/FreeCall.bpl @@ -1,84 +1,84 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// Test the implementation of free calls. These calls don't check the preconditions of the -// called procedure in the caller. - - -procedure Uncallable(i: int) - requires 0 <= i; - free requires true; - requires false; -{ - -} - -procedure UncallableReturn(i: int) returns (b: bool) - requires 0 <= i; - free requires true; - requires false; -{ - b := true; -} - -function T(b: bool) : bool -{ - b == true -} - -procedure TestCallForall(b: bool) - requires T(b); - free requires true; - ensures T(b); -{ - -} - - -procedure NormalCall0() -{ - call Uncallable(0); // error: precondition violation -} - -procedure NormalCall1() -{ - call Uncallable(-1); // error: precondition violation -} - -procedure FreeCall0() -{ - free call Uncallable(0); -} - -procedure FreeCall1() -{ - free call Uncallable(-1); -} - -procedure NormalCall2() -{ - var b: bool; - - call b := UncallableReturn(0); // error: precondition violation -} - -procedure NormalCall3() -{ - var b: bool; - - call b := UncallableReturn(-1); // error: precondition violation -} - -procedure FreeCall3() -{ - var b: bool; - - free call b := UncallableReturn(0); -} - -procedure FreeCall4() -{ - var b: bool; - - free call b := UncallableReturn(-1); -} - +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// Test the implementation of free calls. These calls don't check the preconditions of the +// called procedure in the caller. + + +procedure Uncallable(i: int) + requires 0 <= i; + free requires true; + requires false; +{ + +} + +procedure UncallableReturn(i: int) returns (b: bool) + requires 0 <= i; + free requires true; + requires false; +{ + b := true; +} + +function T(b: bool) : bool +{ + b == true +} + +procedure TestCallForall(b: bool) + requires T(b); + free requires true; + ensures T(b); +{ + +} + + +procedure NormalCall0() +{ + call Uncallable(0); // error: precondition violation +} + +procedure NormalCall1() +{ + call Uncallable(-1); // error: precondition violation +} + +procedure FreeCall0() +{ + free call Uncallable(0); +} + +procedure FreeCall1() +{ + free call Uncallable(-1); +} + +procedure NormalCall2() +{ + var b: bool; + + call b := UncallableReturn(0); // error: precondition violation +} + +procedure NormalCall3() +{ + var b: bool; + + call b := UncallableReturn(-1); // error: precondition violation +} + +procedure FreeCall3() +{ + var b: bool; + + free call b := UncallableReturn(0); +} + +procedure FreeCall4() +{ + var b: bool; + + free call b := UncallableReturn(-1); +} + diff --git a/Test/test2/IfThenElse1.bpl b/Test/test2/IfThenElse1.bpl index 5c12c1f4..1f27a9a9 100644 --- a/Test/test2/IfThenElse1.bpl +++ b/Test/test2/IfThenElse1.bpl @@ -1,5 +1,5 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" type t1; procedure ok() diff --git a/Test/test2/Implies.bpl b/Test/test2/Implies.bpl index 36c4a134..09337d40 100644 --- a/Test/test2/Implies.bpl +++ b/Test/test2/Implies.bpl @@ -1,38 +1,38 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - -const a:bool; -const b:bool; -const c:bool; -const d:bool; - -function f(int) returns (bool); -axiom (forall x:int :: f(x) <== x >= 0); - -procedure P() { - assert (a ==> (b ==> c) ==> d) == (d <== (c <== b) <== a); - assert (a ==> b ==> c) == (c <== (a ==> b)); // error - - assert f(23); - assert f(-5); // error -} - -procedure Q0(x: int) { - assert x == 2; // error - assert x == 2; // nothing reported for this line, since control cannot reach here -} - -procedure Q1(x: int) { - assert {:subsumption 0} x == 2; // error - assert x == 2; // error (because the subsumption attribute above makes the execution 'forget' the condition) -} - -procedure Q2(x: int) { - assert x == 2; // error - assert {:subsumption 0} x == 2; // nothing reported for this line, since control cannot reach here -} - -procedure Q3(x: int) { - assert {:subsumption 0} x == 2; // error - assert {:subsumption 0} x == 2; // error (because the subsumption attribute above makes the execution 'forget' the condition) -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +const a:bool; +const b:bool; +const c:bool; +const d:bool; + +function f(int) returns (bool); +axiom (forall x:int :: f(x) <== x >= 0); + +procedure P() { + assert (a ==> (b ==> c) ==> d) == (d <== (c <== b) <== a); + assert (a ==> b ==> c) == (c <== (a ==> b)); // error + + assert f(23); + assert f(-5); // error +} + +procedure Q0(x: int) { + assert x == 2; // error + assert x == 2; // nothing reported for this line, since control cannot reach here +} + +procedure Q1(x: int) { + assert {:subsumption 0} x == 2; // error + assert x == 2; // error (because the subsumption attribute above makes the execution 'forget' the condition) +} + +procedure Q2(x: int) { + assert x == 2; // error + assert {:subsumption 0} x == 2; // nothing reported for this line, since control cannot reach here +} + +procedure Q3(x: int) { + assert {:subsumption 0} x == 2; // error + assert {:subsumption 0} x == 2; // error (because the subsumption attribute above makes the execution 'forget' the condition) +} diff --git a/Test/test2/InvariantVerifiedUnder0.bpl b/Test/test2/InvariantVerifiedUnder0.bpl index 6cade5a5..dc8e0d4a 100644 --- a/Test/test2/InvariantVerifiedUnder0.bpl +++ b/Test/test2/InvariantVerifiedUnder0.bpl @@ -1,54 +1,54 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - -procedure Test0() -{ - while (*) - invariant {:verified_under false} false; // error - {} -} - - -procedure Test1() -{ - while (*) - invariant {:verified_under true} false; - {} -} - - -procedure Test2(P: bool, Q: bool, A: bool) -{ - while (*) - invariant {:verified_under A} P; // error - invariant {:verified_under A} Q; // error - {} -} - - -procedure Test3(P: bool, Q: bool, A: bool) - requires !A ==> P; -{ - while (*) - invariant {:verified_under A} P; - invariant {:verified_under A} Q; // error - {} -} - -procedure Test4(P: bool, Q: bool, A: bool) -{ - while (*) - invariant {:verified_under A} {:verified_under true} P; // error - invariant {:verified_under A} {:verified_under true} Q; // error - {} -} - - -procedure Test5(P: bool, Q: bool, A: bool) - requires !A ==> Q; -{ - while (*) - invariant {:verified_under A} {:verified_under true} P; // error - invariant {:verified_under A} {:verified_under true} Q; - {} -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +procedure Test0() +{ + while (*) + invariant {:verified_under false} false; // error + {} +} + + +procedure Test1() +{ + while (*) + invariant {:verified_under true} false; + {} +} + + +procedure Test2(P: bool, Q: bool, A: bool) +{ + while (*) + invariant {:verified_under A} P; // error + invariant {:verified_under A} Q; // error + {} +} + + +procedure Test3(P: bool, Q: bool, A: bool) + requires !A ==> P; +{ + while (*) + invariant {:verified_under A} P; + invariant {:verified_under A} Q; // error + {} +} + +procedure Test4(P: bool, Q: bool, A: bool) +{ + while (*) + invariant {:verified_under A} {:verified_under true} P; // error + invariant {:verified_under A} {:verified_under true} Q; // error + {} +} + + +procedure Test5(P: bool, Q: bool, A: bool) + requires !A ==> Q; +{ + while (*) + invariant {:verified_under A} {:verified_under true} P; // error + invariant {:verified_under A} {:verified_under true} Q; + {} +} diff --git a/Test/test2/InvariantVerifiedUnder0.bpl.expect b/Test/test2/InvariantVerifiedUnder0.bpl.expect index 171a6760..a95a10e1 100644 --- a/Test/test2/InvariantVerifiedUnder0.bpl.expect +++ b/Test/test2/InvariantVerifiedUnder0.bpl.expect @@ -1,23 +1,23 @@ -InvariantVerifiedUnder0.bpl(7,7): Error BP5001: This assertion might not hold. -Execution trace: - InvariantVerifiedUnder0.bpl(6,5): anon0 -InvariantVerifiedUnder0.bpl(23,7): Error BP5004: This loop invariant might not hold on entry. -Execution trace: - InvariantVerifiedUnder0.bpl(22,5): anon0 -InvariantVerifiedUnder0.bpl(24,7): Error BP5004: This loop invariant might not hold on entry. -Execution trace: - InvariantVerifiedUnder0.bpl(22,5): anon0 -InvariantVerifiedUnder0.bpl(34,7): Error BP5004: This loop invariant might not hold on entry. -Execution trace: - InvariantVerifiedUnder0.bpl(32,5): anon0 -InvariantVerifiedUnder0.bpl(41,7): Error BP5004: This loop invariant might not hold on entry. -Execution trace: - InvariantVerifiedUnder0.bpl(40,5): anon0 -InvariantVerifiedUnder0.bpl(42,7): Error BP5004: This loop invariant might not hold on entry. -Execution trace: - InvariantVerifiedUnder0.bpl(40,5): anon0 -InvariantVerifiedUnder0.bpl(51,7): Error BP5004: This loop invariant might not hold on entry. -Execution trace: - InvariantVerifiedUnder0.bpl(50,5): anon0 - -Boogie program verifier finished with 1 verified, 7 errors +InvariantVerifiedUnder0.bpl(7,7): Error BP5001: This assertion might not hold. +Execution trace: + InvariantVerifiedUnder0.bpl(6,5): anon0 +InvariantVerifiedUnder0.bpl(23,7): Error BP5004: This loop invariant might not hold on entry. +Execution trace: + InvariantVerifiedUnder0.bpl(22,5): anon0 +InvariantVerifiedUnder0.bpl(24,7): Error BP5004: This loop invariant might not hold on entry. +Execution trace: + InvariantVerifiedUnder0.bpl(22,5): anon0 +InvariantVerifiedUnder0.bpl(34,7): Error BP5004: This loop invariant might not hold on entry. +Execution trace: + InvariantVerifiedUnder0.bpl(32,5): anon0 +InvariantVerifiedUnder0.bpl(41,7): Error BP5004: This loop invariant might not hold on entry. +Execution trace: + InvariantVerifiedUnder0.bpl(40,5): anon0 +InvariantVerifiedUnder0.bpl(42,7): Error BP5004: This loop invariant might not hold on entry. +Execution trace: + InvariantVerifiedUnder0.bpl(40,5): anon0 +InvariantVerifiedUnder0.bpl(51,7): Error BP5004: This loop invariant might not hold on entry. +Execution trace: + InvariantVerifiedUnder0.bpl(50,5): anon0 + +Boogie program verifier finished with 1 verified, 7 errors diff --git a/Test/test2/LambdaOldExpressions.bpl b/Test/test2/LambdaOldExpressions.bpl index e865f4ab..24ce498d 100644 --- a/Test/test2/LambdaOldExpressions.bpl +++ b/Test/test2/LambdaOldExpressions.bpl @@ -1,63 +1,63 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -var b: bool; - - -procedure p0(); - requires b; - modifies b; - ensures (lambda x: bool :: {:MyAttr "put an attr here", !b} old(b))[true]; - ensures !(lambda x: bool :: {:AnotherAttr "yes, why not", b} {:ABC b, b, old(b)} b)[true]; - -implementation p0() -{ - b := !b; - assert (lambda x: bool :: old(b))[true]; - assert !(lambda x: bool :: b)[true]; -} - - -procedure p1(); - requires !b; - modifies b; - ensures (lambda x: bool :: old(b))[true]; // error - -implementation p1() -{ - b := !b; - assert !(lambda x: bool :: old(b))[true]; -} - - -procedure p2(); - requires b; - modifies b; - ensures (lambda x: bool :: old(b) != b)[true]; - -implementation p2() -{ - b := !b; - assert (lambda x: bool :: old(b) != b)[true]; -} - - -procedure p3(); - requires b; - modifies b; - ensures (lambda x: int :: old(old(b)) != b)[15]; - -implementation p3() -{ - b := !b; - assert (lambda x: int :: old(old(b)) != b)[15]; -} - -// Note that variables (inside and outside old expressions) mentioned -// in attributes (even if they are not mentioned in the body of the -// lambda) are also picked up by the auto-generated lambda functions, -// so that the attributes can be copied to the function and axiom. -var h: int; -procedure TestAttributeParameters() - ensures (lambda x: int :: {:MyAttribute old(h), h} x < 100)[23]; -{ -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +var b: bool; + + +procedure p0(); + requires b; + modifies b; + ensures (lambda x: bool :: {:MyAttr "put an attr here", !b} old(b))[true]; + ensures !(lambda x: bool :: {:AnotherAttr "yes, why not", b} {:ABC b, b, old(b)} b)[true]; + +implementation p0() +{ + b := !b; + assert (lambda x: bool :: old(b))[true]; + assert !(lambda x: bool :: b)[true]; +} + + +procedure p1(); + requires !b; + modifies b; + ensures (lambda x: bool :: old(b))[true]; // error + +implementation p1() +{ + b := !b; + assert !(lambda x: bool :: old(b))[true]; +} + + +procedure p2(); + requires b; + modifies b; + ensures (lambda x: bool :: old(b) != b)[true]; + +implementation p2() +{ + b := !b; + assert (lambda x: bool :: old(b) != b)[true]; +} + + +procedure p3(); + requires b; + modifies b; + ensures (lambda x: int :: old(old(b)) != b)[15]; + +implementation p3() +{ + b := !b; + assert (lambda x: int :: old(old(b)) != b)[15]; +} + +// Note that variables (inside and outside old expressions) mentioned +// in attributes (even if they are not mentioned in the body of the +// lambda) are also picked up by the auto-generated lambda functions, +// so that the attributes can be copied to the function and axiom. +var h: int; +procedure TestAttributeParameters() + ensures (lambda x: int :: {:MyAttribute old(h), h} x < 100)[23]; +{ +} diff --git a/Test/test2/LambdaPoly.bpl b/Test/test2/LambdaPoly.bpl index a850d43b..9bbab100 100644 --- a/Test/test2/LambdaPoly.bpl +++ b/Test/test2/LambdaPoly.bpl @@ -1,5 +1,5 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" type set a = [a]bool; function union(a:set T, b:set T) : set T; axiom (forall a,b:set T :: union(a,b) == (lambda x:T :: a[x] || b[x])); diff --git a/Test/test2/LoopInvAssume.bpl b/Test/test2/LoopInvAssume.bpl index fd95c52e..a1e9a894 100644 --- a/Test/test2/LoopInvAssume.bpl +++ b/Test/test2/LoopInvAssume.bpl @@ -1,22 +1,22 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// Check that assumes in loop invariants are handled correctly - -var x : int; - -procedure Test() - modifies x; -{ - entry: - goto loophead, exit; - - loophead: - assume x >= 0; - x := 0; - goto loophead, exit; - - exit: - assume x < 0; - assert false; - return; -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// Check that assumes in loop invariants are handled correctly + +var x : int; + +procedure Test() + modifies x; +{ + entry: + goto loophead, exit; + + loophead: + assume x >= 0; + x := 0; + goto loophead, exit; + + exit: + assume x < 0; + assert false; + return; +} diff --git a/Test/test2/NeverPattern.bpl b/Test/test2/NeverPattern.bpl index aa301129..5b8fc241 100644 --- a/Test/test2/NeverPattern.bpl +++ b/Test/test2/NeverPattern.bpl @@ -1,70 +1,70 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -function {:never_pattern true} f1(x:int) returns(int); -function {:never_pattern false} f2(x:int) returns(int); -function f3(x:int) returns(int); - - -procedure foo() -{ - assume (forall x : int :: f1(x) > 0 && f2(x) > 0 && f3(x) > 0); - assert f2(3) > 0; - assert f3(4) > 0; -} - -procedure bar() -{ - assume (forall x : int :: f1(x) > 0 && f2(x) > 0 && f3(x) > 0 && f1(7) == 3); - assert f1(3) > 0; -} - -procedure bar1() -{ - assume (forall x : int :: {:nopats f2(x)} f1(x) > 0 && f2(x) > 0 && f3(x) > 0 && f1(7) == 3); - assert f1(3) > 0; -} - -procedure bar2() -{ - assume (forall x : int :: {:nopats f2(x)} f1(x) > 0 && f2(x) > 0 && f3(x) > 0 && f1(7) == 3); - assert f2(3) > 0; -} - -// ----- nested binders ----- - -function {:never_pattern} P(int): bool; -function F(int, int): int; -function G(int): bool; - -procedure NestedBinders() -{ - goto A, B, C, D; - A: - assume (forall s: int :: - // the occurrence of P in the next line had once caused a crash - (forall x: int :: { F(s, x) } P(F(s, x))) - ==> G(s)); // this places the nested forall in a negative position - goto End; - - B: - assume (forall s: int :: - // the occurrence of P in the next line had once caused a crash - (exists x: int :: { F(s, x) } P(F(s, x)))); - goto End; - - C: - assume (forall s: int, m: [int]bool :: - // the occurrence of P in the next line had once caused a crash - (lambda x: int :: P(F(s, x))) == m); - goto End; - - D: - assume (forall x0: int :: - // The following quantifier will get a {:nopats P(x1,s)}, which is good. - // But that added trigger expression had once caused the outer quantifier - // to crash. - (forall x1: int :: P(x1))); - goto End; - - End: -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +function {:never_pattern true} f1(x:int) returns(int); +function {:never_pattern false} f2(x:int) returns(int); +function f3(x:int) returns(int); + + +procedure foo() +{ + assume (forall x : int :: f1(x) > 0 && f2(x) > 0 && f3(x) > 0); + assert f2(3) > 0; + assert f3(4) > 0; +} + +procedure bar() +{ + assume (forall x : int :: f1(x) > 0 && f2(x) > 0 && f3(x) > 0 && f1(7) == 3); + assert f1(3) > 0; +} + +procedure bar1() +{ + assume (forall x : int :: {:nopats f2(x)} f1(x) > 0 && f2(x) > 0 && f3(x) > 0 && f1(7) == 3); + assert f1(3) > 0; +} + +procedure bar2() +{ + assume (forall x : int :: {:nopats f2(x)} f1(x) > 0 && f2(x) > 0 && f3(x) > 0 && f1(7) == 3); + assert f2(3) > 0; +} + +// ----- nested binders ----- + +function {:never_pattern} P(int): bool; +function F(int, int): int; +function G(int): bool; + +procedure NestedBinders() +{ + goto A, B, C, D; + A: + assume (forall s: int :: + // the occurrence of P in the next line had once caused a crash + (forall x: int :: { F(s, x) } P(F(s, x))) + ==> G(s)); // this places the nested forall in a negative position + goto End; + + B: + assume (forall s: int :: + // the occurrence of P in the next line had once caused a crash + (exists x: int :: { F(s, x) } P(F(s, x)))); + goto End; + + C: + assume (forall s: int, m: [int]bool :: + // the occurrence of P in the next line had once caused a crash + (lambda x: int :: P(F(s, x))) == m); + goto End; + + D: + assume (forall x0: int :: + // The following quantifier will get a {:nopats P(x1,s)}, which is good. + // But that added trigger expression had once caused the outer quantifier + // to crash. + (forall x1: int :: P(x1))); + goto End; + + End: +} diff --git a/Test/test2/NullaryMaps.bpl b/Test/test2/NullaryMaps.bpl index a02f4594..142d18f2 100644 --- a/Test/test2/NullaryMaps.bpl +++ b/Test/test2/NullaryMaps.bpl @@ -1,59 +1,59 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// aren't these cool! - -var m: []int; -var p: []a; - -type ref; -const null: ref; - -procedure P() - requires m[] == 5; - modifies m; - modifies p; - ensures m[] == 30; - ensures p[] == null; -{ - m[] := 12; - p[] := 12; - p[] := true; - assert p[] == m[]; - assert p[]; - m := m[:= 30]; - p := p[:=null]; -} - -procedure Q() - modifies m; -{ - assert m[] == 5; // error - m[] := 30; - assert m[] == 5; // error -} - -procedure R() - modifies p; -{ - assert p[] < 3; // error -} - -// ---- - -type Field a; -type HeapType = [ref, Field a]a; -const F0: Field int; -const F1: Field bool; -const alloc: Field bool; -var Heap: HeapType; -procedure FrameCondition(this: ref) - modifies Heap; - ensures (forall o: ref, f: Field a :: - Heap[o,f] == old(Heap)[o,f] || - !old(Heap)[o,alloc] || - (o == this && f == F0) || - (o == this && f == F1) - ); -{ -} - +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// aren't these cool! + +var m: []int; +var p: []a; + +type ref; +const null: ref; + +procedure P() + requires m[] == 5; + modifies m; + modifies p; + ensures m[] == 30; + ensures p[] == null; +{ + m[] := 12; + p[] := 12; + p[] := true; + assert p[] == m[]; + assert p[]; + m := m[:= 30]; + p := p[:=null]; +} + +procedure Q() + modifies m; +{ + assert m[] == 5; // error + m[] := 30; + assert m[] == 5; // error +} + +procedure R() + modifies p; +{ + assert p[] < 3; // error +} + +// ---- + +type Field a; +type HeapType = [ref, Field a]a; +const F0: Field int; +const F1: Field bool; +const alloc: Field bool; +var Heap: HeapType; +procedure FrameCondition(this: ref) + modifies Heap; + ensures (forall o: ref, f: Field a :: + Heap[o,f] == old(Heap)[o,f] || + !old(Heap)[o,alloc] || + (o == this && f == F0) || + (o == this && f == F1) + ); +{ +} + diff --git a/Test/test2/Old.bpl b/Test/test2/Old.bpl index beb98d40..017dcd85 100644 --- a/Test/test2/Old.bpl +++ b/Test/test2/Old.bpl @@ -1,134 +1,134 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -var x: int; -var y: int; - -procedure P() - modifies x; - ensures x == old(x) + 1; -{ - start: - x := 1 + x; - return; -} - -procedure Q(); - modifies x; - ensures x == old(x) + 1; - -implementation Q() -{ - start: - x := 1 + x; - return; -} - -procedure R() - modifies x; - ensures x == old(x) + 1; -{ - start: - return; -} // error: does not establish postcondition - -procedure Swap() - modifies x, y; - ensures x == old(y) && y == old(x); -{ - var t: int; - - start: - goto A, B; - A: - t := x; - x := y; - y := t; - goto end; - B: - x := x - y; // x == old(x) - old(y) - y := y + x; // y == old(y) + (old(x) - old(y)) == old(x) - x := y - x; // x == old(x) - (old(x) - old(y)) == old(y) - goto end; - end: - return; -} - -procedure OutParam0(x: int) returns (y: int) - ensures y == x + 1; -{ - start: - y := x + 1; - return; -} - -// OutParam1 is like OutParam0, except that there's now a separate -// implementation declaration, which means that the specification -// and body use different AST nodes for the formal parameters. This -// may make a difference in the various substitutions going on. -// (Indeed, a previous bug caused OutParam0 to verify but not OutParam1.) -procedure OutParam1(x: int) returns (y: int); - ensures y == x + 1; -implementation OutParam1(x: int) returns (y: int) -{ - start: - y := x + 1; - return; -} - -var a: [ref]int; -var b: [ref]int; - -procedure SwapElems(o: ref) returns (p: ref) - modifies a, b; - ensures a[o] == old(b[p]) && b[o] == old(a[p]); -{ - var ta: int, tb: int; - - start: - goto A, B, C; - A: - havoc p; - goto B, C; - B: - ta := a[p]; - tb := b[p]; - a[o] := tb; - b[o] := ta; - return; - C: - assume a[o] == b[o];assume false; - - p := o; - return; -} - - - -//------------------------------------------------------------------------- -// Test old in Boogie PL code -//------------------------------------------------------------------------- - -var Global0: int; - -// Good -procedure OldInCode0() - requires Global0 >= 0; - ensures Global0 <= old(Global0) + 1; - modifies Global0; -{ - var local0: int; - - start: - goto A,B; - A: - assert Global0 == old(Global0); - return; - - B: - local0 := Global0 + 1; - local0 := local0 - 1; - Global0 := old(local0 + 1); - return; -} - -type ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +var x: int; +var y: int; + +procedure P() + modifies x; + ensures x == old(x) + 1; +{ + start: + x := 1 + x; + return; +} + +procedure Q(); + modifies x; + ensures x == old(x) + 1; + +implementation Q() +{ + start: + x := 1 + x; + return; +} + +procedure R() + modifies x; + ensures x == old(x) + 1; +{ + start: + return; +} // error: does not establish postcondition + +procedure Swap() + modifies x, y; + ensures x == old(y) && y == old(x); +{ + var t: int; + + start: + goto A, B; + A: + t := x; + x := y; + y := t; + goto end; + B: + x := x - y; // x == old(x) - old(y) + y := y + x; // y == old(y) + (old(x) - old(y)) == old(x) + x := y - x; // x == old(x) - (old(x) - old(y)) == old(y) + goto end; + end: + return; +} + +procedure OutParam0(x: int) returns (y: int) + ensures y == x + 1; +{ + start: + y := x + 1; + return; +} + +// OutParam1 is like OutParam0, except that there's now a separate +// implementation declaration, which means that the specification +// and body use different AST nodes for the formal parameters. This +// may make a difference in the various substitutions going on. +// (Indeed, a previous bug caused OutParam0 to verify but not OutParam1.) +procedure OutParam1(x: int) returns (y: int); + ensures y == x + 1; +implementation OutParam1(x: int) returns (y: int) +{ + start: + y := x + 1; + return; +} + +var a: [ref]int; +var b: [ref]int; + +procedure SwapElems(o: ref) returns (p: ref) + modifies a, b; + ensures a[o] == old(b[p]) && b[o] == old(a[p]); +{ + var ta: int, tb: int; + + start: + goto A, B, C; + A: + havoc p; + goto B, C; + B: + ta := a[p]; + tb := b[p]; + a[o] := tb; + b[o] := ta; + return; + C: + assume a[o] == b[o];assume false; + + p := o; + return; +} + + + +//------------------------------------------------------------------------- +// Test old in Boogie PL code +//------------------------------------------------------------------------- + +var Global0: int; + +// Good +procedure OldInCode0() + requires Global0 >= 0; + ensures Global0 <= old(Global0) + 1; + modifies Global0; +{ + var local0: int; + + start: + goto A,B; + A: + assert Global0 == old(Global0); + return; + + B: + local0 := Global0 + 1; + local0 := local0 - 1; + Global0 := old(local0 + 1); + return; +} + +type ref; diff --git a/Test/test2/OldIllegal.bpl b/Test/test2/OldIllegal.bpl index b9f7bd75..0a9b9b54 100644 --- a/Test/test2/OldIllegal.bpl +++ b/Test/test2/OldIllegal.bpl @@ -1,18 +1,18 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// Test old appearing in illegal locations - -var Global0: int; - -// Bad -procedure OldInCode1() - requires old(Global0) == 0; -{ - start: - return; -} - -// Bad -axiom (forall o:ref :: old(o) == o); - -type ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// Test old appearing in illegal locations + +var Global0: int; + +// Bad +procedure OldInCode1() + requires old(Global0) == 0; +{ + start: + return; +} + +// Bad +axiom (forall o:ref :: old(o) == o); + +type ref; diff --git a/Test/test2/Passification.bpl b/Test/test2/Passification.bpl index a248ca97..05912565 100644 --- a/Test/test2/Passification.bpl +++ b/Test/test2/Passification.bpl @@ -1,171 +1,171 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// VC generation tests: passification - -procedure good0(x: int) returns (y: int, z: int) - ensures z == 4 || z == 4+x; -{ -var t: int; -A: - t := y; - z := 3; - goto B, C; -B: - z := z + x; - goto D; -C: - goto D; -D: - z := z + 1; - y := t; - return; -} - -procedure good1(x: int) returns (y: int, z: int) - ensures z == x + 4; -{ -var t: int; -A: - t := y; - z := 3; - z := z + x; - z := z + 1; - y := t; - return; -} - -procedure bad0(x: int) returns (y: int, z: int) - ensures y == 4; // ERROR: postcondition violation -{ -var t: int; -A: - t := z; - z := 3; - z := z + 1; - y := t; - return; -} - -procedure Loop() -{ -start: - goto start; -} - -procedure UnreachableBlock() -{ -start: - return; -notReached: - goto start; -reallyNeverReached: - goto reallyNeverReached; -} - -procedure Loop0() returns (z: int) - ensures 10 <= z; -{ -var x: int; -A: - goto B, C; -B: - assume x < 10; - x := x + 1; - goto A; -C: - assume !(x < 10); - z := x; - return; -} - -const unique A0: name; -const unique A1: name; -const unique A2: name; - -procedure Array0() returns (z: int) - ensures z >= 5; -{ -var a: [name,name]int; -L0: - a[A0,A2] := 5; - a[A0,A1] := 20; - assert a[A0,A1] == 20; - goto L1,L2; -L1: - a[A0,A2] := 18; - assert a[A0,A2] == 18; - goto L2; -L2: - assert a[A0,A1] == 20; - z := a[A0,A2]; - return; -} - -procedure Array1(o0: ref, o1: ref) returns (z: int) - ensures z >= 5; -{ -var a: [ref,name]int; -L0: - a[o1,A0] := 5; - a[o0,A0] := 20; - assert a[o0,A0] == 20; - goto L1,L2; -L1: - a[o1,A0] := 18; - assert a[o1,A0] == 18; - goto L2; -L2: - assert a[o0,A0] == 20; // ERROR: assertion failure - z := a[o1,A0]; - return; -} - -procedure Array2(o0: ref, o1: ref) returns (z: int) - ensures z >= 5; -{ -var a: [ref,name]int; -L0: - assume o1 != o0; - a[o1,A0] := 5; - a[o0,A0] := 20; - assert a[o0,A0] == 20; - goto L1,L2; -L1: - a[o1,A0] := 18; - assert a[o1,A0] == 18; - goto L2; -L2: - assert a[o0,A0] == 20; - z := a[o1,A0]; - return; -} - -procedure P() -{ -var t: int; -L0: - t := 0; - goto L1, L2; -L1: - t := 1; - goto L2; -L2: - assert t == 1; // ERROR: assert failure - return; -} - -procedure Q() -{ -var t: int; -L0: - t := 0; - goto L1, L2; -L1: - t := 1; - goto L2; -L2: - assert t == 0; // ERROR: assert failure - return; -} - -type name, ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// VC generation tests: passification + +procedure good0(x: int) returns (y: int, z: int) + ensures z == 4 || z == 4+x; +{ +var t: int; +A: + t := y; + z := 3; + goto B, C; +B: + z := z + x; + goto D; +C: + goto D; +D: + z := z + 1; + y := t; + return; +} + +procedure good1(x: int) returns (y: int, z: int) + ensures z == x + 4; +{ +var t: int; +A: + t := y; + z := 3; + z := z + x; + z := z + 1; + y := t; + return; +} + +procedure bad0(x: int) returns (y: int, z: int) + ensures y == 4; // ERROR: postcondition violation +{ +var t: int; +A: + t := z; + z := 3; + z := z + 1; + y := t; + return; +} + +procedure Loop() +{ +start: + goto start; +} + +procedure UnreachableBlock() +{ +start: + return; +notReached: + goto start; +reallyNeverReached: + goto reallyNeverReached; +} + +procedure Loop0() returns (z: int) + ensures 10 <= z; +{ +var x: int; +A: + goto B, C; +B: + assume x < 10; + x := x + 1; + goto A; +C: + assume !(x < 10); + z := x; + return; +} + +const unique A0: name; +const unique A1: name; +const unique A2: name; + +procedure Array0() returns (z: int) + ensures z >= 5; +{ +var a: [name,name]int; +L0: + a[A0,A2] := 5; + a[A0,A1] := 20; + assert a[A0,A1] == 20; + goto L1,L2; +L1: + a[A0,A2] := 18; + assert a[A0,A2] == 18; + goto L2; +L2: + assert a[A0,A1] == 20; + z := a[A0,A2]; + return; +} + +procedure Array1(o0: ref, o1: ref) returns (z: int) + ensures z >= 5; +{ +var a: [ref,name]int; +L0: + a[o1,A0] := 5; + a[o0,A0] := 20; + assert a[o0,A0] == 20; + goto L1,L2; +L1: + a[o1,A0] := 18; + assert a[o1,A0] == 18; + goto L2; +L2: + assert a[o0,A0] == 20; // ERROR: assertion failure + z := a[o1,A0]; + return; +} + +procedure Array2(o0: ref, o1: ref) returns (z: int) + ensures z >= 5; +{ +var a: [ref,name]int; +L0: + assume o1 != o0; + a[o1,A0] := 5; + a[o0,A0] := 20; + assert a[o0,A0] == 20; + goto L1,L2; +L1: + a[o1,A0] := 18; + assert a[o1,A0] == 18; + goto L2; +L2: + assert a[o0,A0] == 20; + z := a[o1,A0]; + return; +} + +procedure P() +{ +var t: int; +L0: + t := 0; + goto L1, L2; +L1: + t := 1; + goto L2; +L2: + assert t == 1; // ERROR: assert failure + return; +} + +procedure Q() +{ +var t: int; +L0: + t := 0; + goto L1, L2; +L1: + t := 1; + goto L2; +L2: + assert t == 0; // ERROR: assert failure + return; +} + +type name, ref; diff --git a/Test/test2/Quantifiers.bpl b/Test/test2/Quantifiers.bpl index 659a0c47..0392ca23 100644 --- a/Test/test2/Quantifiers.bpl +++ b/Test/test2/Quantifiers.bpl @@ -1,156 +1,156 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -// ----------------------------------------------------------------------- single trigger - -function f(int, int) returns (int); - -axiom (forall x: int, y: int :: f(x,y) < x+y); -axiom (forall x: int :: { f(x,10) } f(x,10) == 3); - -procedure P(a: int, b: int) - requires a <= 25 && b <= 30; -{ - start: - assert f(a,b) <= 100; - return; -} - -procedure Q(a: int, b: int) - requires a + 2 <= b; -{ - start: - assert f(a,b) == 3; // not provable with the trigger given above - return; -} - -procedure R(a: int, b: int) - requires a + 2 <= b; -{ - start: - assume b <= 10 && 8 <= a; - assert f(a,b) == 3; // now, the trigger should fire - return; -} - -// ----------------------------------------------------------------------- multi trigger - -function g(int, int) returns (int); - -axiom (forall x: int, y: int :: { g(x,10),g(x,y) } g(x,y) == 3); // multi-trigger - -procedure S(a: int, b: int) - requires a + 2 <= b; -{ - start: - assert g(a,b) == 3; // not provable with the trigger given above - return; -} - -procedure T(a: int, b: int) - requires a + 2 <= b; -{ - start: - assume b <= 10 && 8 <= a; - assert g(a,b) == 3; // this should trigger - return; -} - -// ----------------------------------------------------------------------- several triggers - -function h(int, int) returns (int); - -axiom (forall y: int :: { g(y,y) } { h(y,h(y,10)) } h(y, h(y,y)) == y); // several triggers - -procedure U0(a: int) -{ - start: - assert h(a,h(a,a)) == a; // not provable with the triggers given above - return; -} - -procedure U1(a: int, b: int) -{ - start: - assume g(a,b) == 5; - assert h(a,h(a,a)) == a; // not provable with the triggers given above - return; -} - -procedure V0(a: int, b: int) - requires a == b; -{ - start: - assume g(a,b) == 5; - assert h(a,h(a,a)) == a; // this should trigger - return; -} - -procedure V1(a: int, b: int) -{ - start: - assume a == 10; - assert h(a,h(a,a)) == a; // this should trigger - return; -} - -procedure V2(a: int, b: int) -{ - start: - assume 0 <= h(a,h(a,10)); - assume a == 17; - assert h(a,h(a,a)) == a; // this should trigger - return; -} - -// ----------------------------------------------------------------------- negated triggers - -function ka(ref) returns (int); -function kb(ref) returns (int); -function kbSynonym(ref) returns (int); -function isA(ref, name) returns (bool); -function isB(ref, name) returns (bool); -const $T: name; - -axiom (forall o: ref :: - isA(o, $T) ==> ka(o) < ka(o)); // automatically inferred triggers can be both isA(o,$T) and ka(o) - -axiom (forall o: ref :: - {:nopats isB(o, $T) } - isB(o, $T) ==> kb(o) < kbSynonym(o)); // prevent isB(o,$T) from being used as a trigger - -axiom (forall o: ref :: kb(o) == kbSynonym(o)); - -procedure W(o: ref, e: int) - requires isB(o, $T); -{ - start: - assert e > 20; // the isB axiom should not trigger, so this cannot be proved - return; -} - -procedure X0(o: ref, e: int) - requires isA(o, $T); -{ - start: - assert e > 20; // this should trigger the isA axiom, so anything is provable - return; -} - -procedure X1(o: ref, e: int, u: int) - requires isB(o, $T); -{ - start: - assume f(kb(o), kb(o)) == u; - assert e > 20; // this should now trigger the isB axiom, so anything is provable - return; -} - -procedure X2(o: ref, e: int, u: int) - requires isB(o, $T); -{ - start: - assert e > 20; // error is report here, providing evidence that the isB axiom has not been triggered - return; -} - -type name, ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +// ----------------------------------------------------------------------- single trigger + +function f(int, int) returns (int); + +axiom (forall x: int, y: int :: f(x,y) < x+y); +axiom (forall x: int :: { f(x,10) } f(x,10) == 3); + +procedure P(a: int, b: int) + requires a <= 25 && b <= 30; +{ + start: + assert f(a,b) <= 100; + return; +} + +procedure Q(a: int, b: int) + requires a + 2 <= b; +{ + start: + assert f(a,b) == 3; // not provable with the trigger given above + return; +} + +procedure R(a: int, b: int) + requires a + 2 <= b; +{ + start: + assume b <= 10 && 8 <= a; + assert f(a,b) == 3; // now, the trigger should fire + return; +} + +// ----------------------------------------------------------------------- multi trigger + +function g(int, int) returns (int); + +axiom (forall x: int, y: int :: { g(x,10),g(x,y) } g(x,y) == 3); // multi-trigger + +procedure S(a: int, b: int) + requires a + 2 <= b; +{ + start: + assert g(a,b) == 3; // not provable with the trigger given above + return; +} + +procedure T(a: int, b: int) + requires a + 2 <= b; +{ + start: + assume b <= 10 && 8 <= a; + assert g(a,b) == 3; // this should trigger + return; +} + +// ----------------------------------------------------------------------- several triggers + +function h(int, int) returns (int); + +axiom (forall y: int :: { g(y,y) } { h(y,h(y,10)) } h(y, h(y,y)) == y); // several triggers + +procedure U0(a: int) +{ + start: + assert h(a,h(a,a)) == a; // not provable with the triggers given above + return; +} + +procedure U1(a: int, b: int) +{ + start: + assume g(a,b) == 5; + assert h(a,h(a,a)) == a; // not provable with the triggers given above + return; +} + +procedure V0(a: int, b: int) + requires a == b; +{ + start: + assume g(a,b) == 5; + assert h(a,h(a,a)) == a; // this should trigger + return; +} + +procedure V1(a: int, b: int) +{ + start: + assume a == 10; + assert h(a,h(a,a)) == a; // this should trigger + return; +} + +procedure V2(a: int, b: int) +{ + start: + assume 0 <= h(a,h(a,10)); + assume a == 17; + assert h(a,h(a,a)) == a; // this should trigger + return; +} + +// ----------------------------------------------------------------------- negated triggers + +function ka(ref) returns (int); +function kb(ref) returns (int); +function kbSynonym(ref) returns (int); +function isA(ref, name) returns (bool); +function isB(ref, name) returns (bool); +const $T: name; + +axiom (forall o: ref :: + isA(o, $T) ==> ka(o) < ka(o)); // automatically inferred triggers can be both isA(o,$T) and ka(o) + +axiom (forall o: ref :: + {:nopats isB(o, $T) } + isB(o, $T) ==> kb(o) < kbSynonym(o)); // prevent isB(o,$T) from being used as a trigger + +axiom (forall o: ref :: kb(o) == kbSynonym(o)); + +procedure W(o: ref, e: int) + requires isB(o, $T); +{ + start: + assert e > 20; // the isB axiom should not trigger, so this cannot be proved + return; +} + +procedure X0(o: ref, e: int) + requires isA(o, $T); +{ + start: + assert e > 20; // this should trigger the isA axiom, so anything is provable + return; +} + +procedure X1(o: ref, e: int, u: int) + requires isB(o, $T); +{ + start: + assume f(kb(o), kb(o)) == u; + assert e > 20; // this should now trigger the isB axiom, so anything is provable + return; +} + +procedure X2(o: ref, e: int, u: int) + requires isB(o, $T); +{ + start: + assert e > 20; // error is report here, providing evidence that the isB axiom has not been triggered + return; +} + +type name, ref; diff --git a/Test/test2/SelectiveChecking.bpl b/Test/test2/SelectiveChecking.bpl index 188243c8..1c505abb 100644 --- a/Test/test2/SelectiveChecking.bpl +++ b/Test/test2/SelectiveChecking.bpl @@ -1,5 +1,5 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" procedure {:selective_checking} foo() { var x, y, z : int; diff --git a/Test/test2/Structured.bpl b/Test/test2/Structured.bpl index 55ee847a..a5aebaa9 100644 --- a/Test/test2/Structured.bpl +++ b/Test/test2/Structured.bpl @@ -1,346 +1,346 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - -const K: int; - -function f(int) returns (int); - -axiom (exists k: int :: f(k) == K); - -procedure Find(a: int, b: int) returns (k: int); - requires a <= b && (forall j: int :: a < j && j < b ==> f(j) != K); - ensures f(k) == K; - -// nondeterministic, unstructured, recursive version -implementation Find(a: int, b: int) returns (k: int) -{ - entry: - goto A, B, C; - - A: - assume f(a) == K; - k := a; - return; - - B: - assume f(b) == K; - k := b; - return; - - C: - assume f(a) != K && f(b) != K; - call k := Find(a-1, b+1); - return; -} - -// nondeterministic, recursive version -implementation Find(a: int, b: int) returns (k: int) -{ - if (*) { - assume f(a) == K; - k := a; - } else if (*) { - assume f(b) == K; - k := b; - } else { - assume f(a) != K && f(b) != K; - call k := Find(a-1, b+1); - } -} - -// deterministic, structured, recursive version -implementation Find(a: int, b: int) returns (k: int) -{ - if (f(a) == K) { - k := a; - } else if (f(b) == K) { - k := b; - } else { - call k := Find(a-1, b+1); - } -} - -// deterministic, structured, iterative version -implementation Find(a: int, b: int) returns (k: int) -{ - var x: int, y: int; - - x := a; - y := b; - - while (f(x) != K && f(y) != K) - invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); - { - x := x-1; - y := y+1; - } - - if (f(x) == K) { - k := x; - } else { - k := y; - } -} - -// deterministic, structured, iterative version with breaks -implementation Find(a: int, b: int) returns (k: int) -{ - var x: int, y: int; - - x := a; - y := b; - - while (true) - invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); - { - if (f(x) == K) { - k := x; - break; - } else if (f(y) == K) { - k := y; - break; - } - x := x-1; - y := y+1; - } -} - -// deterministic, somewhat structured, iterative version -implementation Find(a: int, b: int) returns (k: int) -{ - var x: int, y: int; - - x := a; - y := b; - - while (true) - invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); - { - if (f(x) == K) { - goto FoundX; - } else if (f(y) == K) { - goto FoundY; - } - x := x-1; - y := y+1; - } - - FoundX: - k := x; - return; - - FoundY: - k := y; - return; -} - -// deterministic, structured, iterative version with breaks -implementation Find(a: int, b: int) returns (k: int) -{ - var x: int, y: int; - - x := a; - y := b; - - outer: - if (true) { - inner: - while (true) - invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); - { - if (f(x) == K) { - break inner; - } else if (f(y) == K) { - break outer; - } - x := x-1; - y := y+1; - } - - k := x; - return; - } - k := y; -} - -// ----- free invariant ----- - -function Teal(int) returns (bool); -function ShadeOfGreen(int) returns (bool); -axiom (forall w: int :: Teal(w) ==> ShadeOfGreen(w)); - -procedure P(x: int) returns (y: int) - requires Teal(x); - ensures ShadeOfGreen(y); -{ - y := x; - while (y < 100) - free invariant Teal(y); - { - y := y + 5; - } -} - -// ----- run off the end of the BigBlock ----- - -procedure RunOffEnd0() returns (x: int) - ensures x == 3; -{ - x := 0; - Label0: - x := x + 1; - Label1: - x := x + 1; - Label2: - Label3: - Label4: - x := x + 1; -} - -procedure RunOffEnd1() returns (x: int) - ensures x == 4; -{ - x := 0; - Label0: - x := x + 1; - Label1: - if (*) { - Label2: - x := x + 2; - } else if (*) { - Label3: - x := 2; - x := x + 2; - Label4: - Label5: - x := x - 1; - } else { - if (*) { - x := 0; - while (x < 3) - invariant x <= 3; - { x := x + 1; } - } else { - x := x + 2; - } - } - x := x + 1; -} - -procedure RunOffEnd2() returns (x: int) - ensures x == 10; -{ - while (true) { - while (true) { - if (*) { - x := 10; - break; - } - } - if (*) { break; } - } -} - -procedure RunOffEnd3() returns (x: int) - ensures x == 9; -{ x := 9; - while (true) { - while (true) { - if (*) { - x := 10; - break; - } - } - if (*) { break; } - } // error: violated postcondition -} - -procedure RunOffEnd4() returns (x: int) -{ - var y: int; - var bad: bool; - - while (true) { - y := x; - bad := false; - if (*) { - x := x + 1; - bad := true; - } - if (x == y) { break; } - } - assert !bad; -} - -procedure RunOffEnd5() returns (x: int) -{ - while (true) { - if (x == 5) { } - } - assert false; -} - -procedure RunOffEnd6() returns (x: int) -{ - x := 7; - while (true) - invariant x == 7; - { - x := 5; - MyLabel: - x := 7; - } -} - -// ----- jump optimizations ----- - -procedure Q0() -{ - var x: int; - - x := 0; - if (*) { - x := 1; - } - assert x == 1; // error -} - -procedure Q1() returns (x: int) -{ - if (x == 0) { - A: - x := x + 0; - assert x == 0; // error - B: - x := x + 1; - goto A; - } -} - -procedure Q2() returns (x: int) -{ - if (x == 0) { - while (x < 10) - invariant x <= 10; - { - x := x + 1; - } - } -} - -// There was once a bug in Boogie's handling of the following break statement. -procedure BreakIssue(x: int) returns (curr: int) - ensures x == 18 || curr == 100; // holds, because the procedure doesn't - // actually ever terminate if x != 18 -{ - while (x != 18) { - while (x != 19) { - call curr := Read(); - if (curr == 0) { - break; - } - } - } -} - -procedure Read() returns (val: int); +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +const K: int; + +function f(int) returns (int); + +axiom (exists k: int :: f(k) == K); + +procedure Find(a: int, b: int) returns (k: int); + requires a <= b && (forall j: int :: a < j && j < b ==> f(j) != K); + ensures f(k) == K; + +// nondeterministic, unstructured, recursive version +implementation Find(a: int, b: int) returns (k: int) +{ + entry: + goto A, B, C; + + A: + assume f(a) == K; + k := a; + return; + + B: + assume f(b) == K; + k := b; + return; + + C: + assume f(a) != K && f(b) != K; + call k := Find(a-1, b+1); + return; +} + +// nondeterministic, recursive version +implementation Find(a: int, b: int) returns (k: int) +{ + if (*) { + assume f(a) == K; + k := a; + } else if (*) { + assume f(b) == K; + k := b; + } else { + assume f(a) != K && f(b) != K; + call k := Find(a-1, b+1); + } +} + +// deterministic, structured, recursive version +implementation Find(a: int, b: int) returns (k: int) +{ + if (f(a) == K) { + k := a; + } else if (f(b) == K) { + k := b; + } else { + call k := Find(a-1, b+1); + } +} + +// deterministic, structured, iterative version +implementation Find(a: int, b: int) returns (k: int) +{ + var x: int, y: int; + + x := a; + y := b; + + while (f(x) != K && f(y) != K) + invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); + { + x := x-1; + y := y+1; + } + + if (f(x) == K) { + k := x; + } else { + k := y; + } +} + +// deterministic, structured, iterative version with breaks +implementation Find(a: int, b: int) returns (k: int) +{ + var x: int, y: int; + + x := a; + y := b; + + while (true) + invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); + { + if (f(x) == K) { + k := x; + break; + } else if (f(y) == K) { + k := y; + break; + } + x := x-1; + y := y+1; + } +} + +// deterministic, somewhat structured, iterative version +implementation Find(a: int, b: int) returns (k: int) +{ + var x: int, y: int; + + x := a; + y := b; + + while (true) + invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); + { + if (f(x) == K) { + goto FoundX; + } else if (f(y) == K) { + goto FoundY; + } + x := x-1; + y := y+1; + } + + FoundX: + k := x; + return; + + FoundY: + k := y; + return; +} + +// deterministic, structured, iterative version with breaks +implementation Find(a: int, b: int) returns (k: int) +{ + var x: int, y: int; + + x := a; + y := b; + + outer: + if (true) { + inner: + while (true) + invariant x <= y && (forall j: int :: x < j && j < y ==> f(j) != K); + { + if (f(x) == K) { + break inner; + } else if (f(y) == K) { + break outer; + } + x := x-1; + y := y+1; + } + + k := x; + return; + } + k := y; +} + +// ----- free invariant ----- + +function Teal(int) returns (bool); +function ShadeOfGreen(int) returns (bool); +axiom (forall w: int :: Teal(w) ==> ShadeOfGreen(w)); + +procedure P(x: int) returns (y: int) + requires Teal(x); + ensures ShadeOfGreen(y); +{ + y := x; + while (y < 100) + free invariant Teal(y); + { + y := y + 5; + } +} + +// ----- run off the end of the BigBlock ----- + +procedure RunOffEnd0() returns (x: int) + ensures x == 3; +{ + x := 0; + Label0: + x := x + 1; + Label1: + x := x + 1; + Label2: + Label3: + Label4: + x := x + 1; +} + +procedure RunOffEnd1() returns (x: int) + ensures x == 4; +{ + x := 0; + Label0: + x := x + 1; + Label1: + if (*) { + Label2: + x := x + 2; + } else if (*) { + Label3: + x := 2; + x := x + 2; + Label4: + Label5: + x := x - 1; + } else { + if (*) { + x := 0; + while (x < 3) + invariant x <= 3; + { x := x + 1; } + } else { + x := x + 2; + } + } + x := x + 1; +} + +procedure RunOffEnd2() returns (x: int) + ensures x == 10; +{ + while (true) { + while (true) { + if (*) { + x := 10; + break; + } + } + if (*) { break; } + } +} + +procedure RunOffEnd3() returns (x: int) + ensures x == 9; +{ x := 9; + while (true) { + while (true) { + if (*) { + x := 10; + break; + } + } + if (*) { break; } + } // error: violated postcondition +} + +procedure RunOffEnd4() returns (x: int) +{ + var y: int; + var bad: bool; + + while (true) { + y := x; + bad := false; + if (*) { + x := x + 1; + bad := true; + } + if (x == y) { break; } + } + assert !bad; +} + +procedure RunOffEnd5() returns (x: int) +{ + while (true) { + if (x == 5) { } + } + assert false; +} + +procedure RunOffEnd6() returns (x: int) +{ + x := 7; + while (true) + invariant x == 7; + { + x := 5; + MyLabel: + x := 7; + } +} + +// ----- jump optimizations ----- + +procedure Q0() +{ + var x: int; + + x := 0; + if (*) { + x := 1; + } + assert x == 1; // error +} + +procedure Q1() returns (x: int) +{ + if (x == 0) { + A: + x := x + 0; + assert x == 0; // error + B: + x := x + 1; + goto A; + } +} + +procedure Q2() returns (x: int) +{ + if (x == 0) { + while (x < 10) + invariant x <= 10; + { + x := x + 1; + } + } +} + +// There was once a bug in Boogie's handling of the following break statement. +procedure BreakIssue(x: int) returns (curr: int) + ensures x == 18 || curr == 100; // holds, because the procedure doesn't + // actually ever terminate if x != 18 +{ + while (x != 18) { + while (x != 19) { + call curr := Read(); + if (curr == 0) { + break; + } + } + } +} + +procedure Read() returns (val: int); diff --git a/Test/test2/Timeouts0.bpl b/Test/test2/Timeouts0.bpl index 6fa379d9..ee2ad566 100644 --- a/Test/test2/Timeouts0.bpl +++ b/Test/test2/Timeouts0.bpl @@ -1,85 +1,85 @@ -// RUN: %boogie -timeLimit:4 "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure TestTimeouts0(in: [int]int, len: int) returns (out: [int]int) - requires in[0] == 0 && (forall i: int :: 0 <= i ==> in[i + 1] == in[i] + 1); - requires 0 < len; - ensures (forall j: int :: 0 <= j && j < len ==> out[j] == j); -{ - var i : int; - - i := 0; - out[i] := 0; - while (i < len) - invariant 0 <= i && i <= len; - invariant out[0] == 0 && (forall j: int :: 0 <= j && j < i ==> out[j + 1] == out[j] + 1); - { - out[i + 1] := out[i] + 1; - i := i + 1; - } - - i := 0; - while (i < len) - invariant 0 <= i && i <= len; - invariant (forall j: int :: 0 <= j && j < i ==> out[j] == in[j]); - { - i := i + 1; - } -} - - -procedure TestTimeouts1(in: [int]int, len: int) returns (out: [int]int); - requires in[0] == 0 && (forall i: int :: 0 <= i ==> in[i + 1] == in[i] + 1); - requires 0 < len; - ensures (forall j: int :: 0 <= j && j < len ==> out[j] == j); - -implementation {:timeLimit 8} TestTimeouts1(in: [int]int, len: int) returns (out: [int]int) -{ - var i : int; - - i := 0; - out[i] := 0; - while (i < len) - invariant 0 <= i && i <= len; - invariant out[0] == 0 && (forall j: int :: 0 <= j && j < i ==> out[j + 1] == out[j] + 1); - { - out[i + 1] := out[i] + 1; - i := i + 1; - } - - i := 0; - while (i < len) - invariant 0 <= i && i <= len; - invariant (forall j: int :: 0 <= j && j < i ==> out[j] == in[j]); - { - i := i + 1; - } -} - - -procedure TestTimeouts2(in: [int]int, len: int) returns (out: [int]int); - requires in[0] == 0 && (forall i: int :: 0 <= i ==> in[i + 1] == in[i] + 1); - requires 0 < len; - ensures (forall j: int :: 0 <= j && j < len ==> out[j] == j); - -implementation {:timeLimit 2} TestTimeouts2(in: [int]int, len: int) returns (out: [int]int) -{ - var i : int; - - i := 0; - out[i] := 0; - while (i < len) - invariant 0 <= i && i <= len; - invariant out[0] == 0 && (forall j: int :: 0 <= j && j < i ==> out[j + 1] == out[j] + 1); - { - out[i + 1] := out[i] + 1; - i := i + 1; - } - - i := 0; - while (i < len) - invariant 0 <= i && i <= len; - invariant (forall j: int :: 0 <= j && j < i ==> out[j] == in[j]); - { - i := i + 1; - } -} +// RUN: %boogie -timeLimit:4 "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure TestTimeouts0(in: [int]int, len: int) returns (out: [int]int) + requires in[0] == 0 && (forall i: int :: 0 <= i ==> in[i + 1] == in[i] + 1); + requires 0 < len; + ensures (forall j: int :: 0 <= j && j < len ==> out[j] == j); +{ + var i : int; + + i := 0; + out[i] := 0; + while (i < len) + invariant 0 <= i && i <= len; + invariant out[0] == 0 && (forall j: int :: 0 <= j && j < i ==> out[j + 1] == out[j] + 1); + { + out[i + 1] := out[i] + 1; + i := i + 1; + } + + i := 0; + while (i < len) + invariant 0 <= i && i <= len; + invariant (forall j: int :: 0 <= j && j < i ==> out[j] == in[j]); + { + i := i + 1; + } +} + + +procedure TestTimeouts1(in: [int]int, len: int) returns (out: [int]int); + requires in[0] == 0 && (forall i: int :: 0 <= i ==> in[i + 1] == in[i] + 1); + requires 0 < len; + ensures (forall j: int :: 0 <= j && j < len ==> out[j] == j); + +implementation {:timeLimit 8} TestTimeouts1(in: [int]int, len: int) returns (out: [int]int) +{ + var i : int; + + i := 0; + out[i] := 0; + while (i < len) + invariant 0 <= i && i <= len; + invariant out[0] == 0 && (forall j: int :: 0 <= j && j < i ==> out[j + 1] == out[j] + 1); + { + out[i + 1] := out[i] + 1; + i := i + 1; + } + + i := 0; + while (i < len) + invariant 0 <= i && i <= len; + invariant (forall j: int :: 0 <= j && j < i ==> out[j] == in[j]); + { + i := i + 1; + } +} + + +procedure TestTimeouts2(in: [int]int, len: int) returns (out: [int]int); + requires in[0] == 0 && (forall i: int :: 0 <= i ==> in[i + 1] == in[i] + 1); + requires 0 < len; + ensures (forall j: int :: 0 <= j && j < len ==> out[j] == j); + +implementation {:timeLimit 2} TestTimeouts2(in: [int]int, len: int) returns (out: [int]int) +{ + var i : int; + + i := 0; + out[i] := 0; + while (i < len) + invariant 0 <= i && i <= len; + invariant out[0] == 0 && (forall j: int :: 0 <= j && j < i ==> out[j + 1] == out[j] + 1); + { + out[i + 1] := out[i] + 1; + i := i + 1; + } + + i := 0; + while (i < len) + invariant 0 <= i && i <= len; + invariant (forall j: int :: 0 <= j && j < i ==> out[j] == in[j]); + { + i := i + 1; + } +} diff --git a/Test/test2/TypeEncodingM.bpl b/Test/test2/TypeEncodingM.bpl index 0287da12..40e60cf5 100644 --- a/Test/test2/TypeEncodingM.bpl +++ b/Test/test2/TypeEncodingM.bpl @@ -1,5 +1,5 @@ -// RUN: %boogie -noinfer -typeEncoding:m "%s" > "%t" -// RUN: %diff "%s.expect" "%t" +// RUN: %boogie -noinfer -typeEncoding:m "%s" > "%t" +// RUN: %diff "%s.expect" "%t" type TT; procedure A() diff --git a/Test/test2/UpdateExpr.bpl b/Test/test2/UpdateExpr.bpl index eb5ba2e1..fb858a44 100644 --- a/Test/test2/UpdateExpr.bpl +++ b/Test/test2/UpdateExpr.bpl @@ -1,83 +1,83 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - -const a: [int]bool; - -// element 5 of a stores the value true -axiom a == a[5 := true]; - -procedure P() -{ - assert a[5]; -} - -procedure Q() -{ - assert a[4]; // error -} - -procedure R() -{ - assert !a[5]; // error -} - -procedure S(y: int, t: bool) - requires y <= 5; -{ - if (a[y := t][5] == false) { - assert y == 5; - } -} - -procedure T0(aa: [int,ref]bool) -{ - assert aa[5,null := true] != aa[2,null := false]; // error -} - -procedure T1(aa: [int,ref]bool) - requires aa[5,null] && !aa[2,null]; -{ - assert aa[5,null := true] == aa[2,null := false]; // error, because we have no extensionality -} - -procedure T2(aa: [int,ref]bool) - requires aa[5,null] && !aa[2,null]; -{ - assert (forall x: int, y: ref :: aa[5,null := true][x,y] == aa[2,null := false][x,y]); -} - -procedure U0(a: [int]int) -{ - var b: [int]int; - - b := a[5 := 12]; - assert a == b; // error -} - -procedure U1() returns (a: [int]int) -{ - var b: [int]int; - - b := a[5 := 12]; - a[5] := 12; - assert a == b; -} - -type Field a; -const unique IntField: Field int; -const unique RefField: Field ref; -const unique SomeField: Field int; - -procedure FieldProc(H: [ref,Field a]a, this: ref) -{ - var i: int, r: ref, y: any; - var K: [ref,Field a]a; - - K := H[this, IntField := 5][this, RefField := null][this, SomeField := 100][this, IntField := 7]; - assert K[this, IntField] == 7; - assert K[this, RefField] == null; - assert K[this, SomeField] == 100; -} - -type ref, any; -const null : ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +const a: [int]bool; + +// element 5 of a stores the value true +axiom a == a[5 := true]; + +procedure P() +{ + assert a[5]; +} + +procedure Q() +{ + assert a[4]; // error +} + +procedure R() +{ + assert !a[5]; // error +} + +procedure S(y: int, t: bool) + requires y <= 5; +{ + if (a[y := t][5] == false) { + assert y == 5; + } +} + +procedure T0(aa: [int,ref]bool) +{ + assert aa[5,null := true] != aa[2,null := false]; // error +} + +procedure T1(aa: [int,ref]bool) + requires aa[5,null] && !aa[2,null]; +{ + assert aa[5,null := true] == aa[2,null := false]; // error, because we have no extensionality +} + +procedure T2(aa: [int,ref]bool) + requires aa[5,null] && !aa[2,null]; +{ + assert (forall x: int, y: ref :: aa[5,null := true][x,y] == aa[2,null := false][x,y]); +} + +procedure U0(a: [int]int) +{ + var b: [int]int; + + b := a[5 := 12]; + assert a == b; // error +} + +procedure U1() returns (a: [int]int) +{ + var b: [int]int; + + b := a[5 := 12]; + a[5] := 12; + assert a == b; +} + +type Field a; +const unique IntField: Field int; +const unique RefField: Field ref; +const unique SomeField: Field int; + +procedure FieldProc(H: [ref,Field a]a, this: ref) +{ + var i: int, r: ref, y: any; + var K: [ref,Field a]a; + + K := H[this, IntField := 5][this, RefField := null][this, SomeField := 100][this, IntField := 7]; + assert K[this, IntField] == 7; + assert K[this, RefField] == null; + assert K[this, SomeField] == 100; +} + +type ref, any; +const null : ref; diff --git a/Test/test2/Where.bpl b/Test/test2/Where.bpl index fed05d76..762da163 100644 --- a/Test/test2/Where.bpl +++ b/Test/test2/Where.bpl @@ -1,165 +1,165 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -procedure P0() -{ - var x: int where 0 <= x; - var y: int where x <= y; - - assert 0 <= x; - assert x <= y; - assert y < 5; // error -} - -procedure P1() -{ - var x: int where 0 <= x; - var y: int where x <= y; - - x := 5; - havoc y; - assert 5 <= y; - - havoc x; - assert 0 <= x; - assert x <= y; // error -} - -procedure P2() -{ - var x: int where 0 <= x; - var y: int where x <= y; - - havoc y; // y first - havoc x; - assert x <= y; // error -} - -procedure P3() -{ - var x: int where 0 <= x; - var y: int where x <= y; - - x := 5; - havoc x; // this time, x first - havoc y; - assert x <= y; // yeah! - assert 5 <= y; // error -} - -procedure P4() -{ - var x: int where 0 <= x; - var y: int where x <= y; - - havoc x, y; // both at the same time - assert 0 <= x && x <= y; - havoc y, x; // or in the other order - assert 0 <= x && x <= y; - - assert x == 7; // error -} - -procedure R0() returns (wProc: int where wProc == xProc, - xProc: int where 0 <= xProc, - yProc: int where xProc <= yProc); -implementation R0() returns (w: int, x: int, y: int) -{ - while (*) { - assert w == x; - assert 0 <= x; - assert x <= y; - } - while (*) { - assert w == x; - assert 0 <= x; - assert x <= y; - // the following makes w, x, y loop targets - w := w + 1; - havoc x; - y := w; - } - assert w == x; - assert 0 <= x; - assert x <= y; -} - -procedure R1() -{ - var a: int; - var b: int; - var c: int; - - call a, b, c := R0(); - assert a == b; - assert 0 <= b; - assert b <= c; -} - -procedure R2() -{ - var w: int where w == x; - var x: int where 0 <= x; - var y: int where x <= y; - - x := 5; - y := 10; - while (*) { - w := w + 1; - assert w == 6; - y := y + 2; - assert 7 <= y; - } - assert x == 5 && 0 <= y - w; - assert y == 10; // error -} - -procedure R3() -{ - var w: int where w == x; - var x: int where 0 <= x; - var y: int where x <= y; - - // change w and x - y := 10; - while (*) { - w := w; x := x; - } - assert w == x; - assert 0 <= x; - assert y == 10; - assert w <= 10; // error -} - -procedure R4() -{ - var w: int where w == x; - var x: int where 0 <= x; - var y: int where x <= y; - - // change x and y - w := 12; - while (*) { - x := x; y := y; - } - assert 0 <= x; - assert x <= y; - assert w == 12; - assert 8 <= y; // error -} - -procedure R5(K: int) -{ - var w: int where w == x; - var x: int where 0 <= x; - var y: int where x <= y; - - // change w and y - x := K; - while (*) { - w := w; y := y; - } - assert w == K; - assert K <= y; - assert x == K; - assert 0 <= x; // error -} +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +procedure P0() +{ + var x: int where 0 <= x; + var y: int where x <= y; + + assert 0 <= x; + assert x <= y; + assert y < 5; // error +} + +procedure P1() +{ + var x: int where 0 <= x; + var y: int where x <= y; + + x := 5; + havoc y; + assert 5 <= y; + + havoc x; + assert 0 <= x; + assert x <= y; // error +} + +procedure P2() +{ + var x: int where 0 <= x; + var y: int where x <= y; + + havoc y; // y first + havoc x; + assert x <= y; // error +} + +procedure P3() +{ + var x: int where 0 <= x; + var y: int where x <= y; + + x := 5; + havoc x; // this time, x first + havoc y; + assert x <= y; // yeah! + assert 5 <= y; // error +} + +procedure P4() +{ + var x: int where 0 <= x; + var y: int where x <= y; + + havoc x, y; // both at the same time + assert 0 <= x && x <= y; + havoc y, x; // or in the other order + assert 0 <= x && x <= y; + + assert x == 7; // error +} + +procedure R0() returns (wProc: int where wProc == xProc, + xProc: int where 0 <= xProc, + yProc: int where xProc <= yProc); +implementation R0() returns (w: int, x: int, y: int) +{ + while (*) { + assert w == x; + assert 0 <= x; + assert x <= y; + } + while (*) { + assert w == x; + assert 0 <= x; + assert x <= y; + // the following makes w, x, y loop targets + w := w + 1; + havoc x; + y := w; + } + assert w == x; + assert 0 <= x; + assert x <= y; +} + +procedure R1() +{ + var a: int; + var b: int; + var c: int; + + call a, b, c := R0(); + assert a == b; + assert 0 <= b; + assert b <= c; +} + +procedure R2() +{ + var w: int where w == x; + var x: int where 0 <= x; + var y: int where x <= y; + + x := 5; + y := 10; + while (*) { + w := w + 1; + assert w == 6; + y := y + 2; + assert 7 <= y; + } + assert x == 5 && 0 <= y - w; + assert y == 10; // error +} + +procedure R3() +{ + var w: int where w == x; + var x: int where 0 <= x; + var y: int where x <= y; + + // change w and x + y := 10; + while (*) { + w := w; x := x; + } + assert w == x; + assert 0 <= x; + assert y == 10; + assert w <= 10; // error +} + +procedure R4() +{ + var w: int where w == x; + var x: int where 0 <= x; + var y: int where x <= y; + + // change x and y + w := 12; + while (*) { + x := x; y := y; + } + assert 0 <= x; + assert x <= y; + assert w == 12; + assert 8 <= y; // error +} + +procedure R5(K: int) +{ + var w: int where w == x; + var x: int where 0 <= x; + var y: int where x <= y; + + // change w and y + x := K; + while (*) { + w := w; y := y; + } + assert w == K; + assert K <= y; + assert x == K; + assert 0 <= x; // error +} diff --git a/Test/test2/sk_hack.bpl b/Test/test2/sk_hack.bpl index 7ce8e4dc..163bbc26 100644 --- a/Test/test2/sk_hack.bpl +++ b/Test/test2/sk_hack.bpl @@ -1,34 +1,34 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" -function in_set(int) returns(bool); -function next(int) returns(int); -function f(int) returns(bool); -function g(int) returns(bool); - -// this function is treated specially by Z3 when used in triggers -// sk_hack(f(x)) means to activate the e-node f(x0) when trying to prove -// !(forall x : T :: {sk_hack(f(x))} p(x)) by proving !p(x0) -// (i.e., after skolemization of x to x0). -function sk_hack(bool) returns(bool); - -// PR: sk_hack cannot be defined as a polymorphic function -// when using /quantifierTypePremisses:a, because then it would -// get an additional explicit type parameter, and Z3 would -// no longer recognise it. - -procedure foo() -{ - assume (forall x:int :: {in_set(next(x))} - in_set(x) ==> in_set(next(x))); - - assume (forall x:int :: {in_set(x)} - in_set(x) ==> f(x)); - - assume (forall x:int :: {f(next(x))} - f(next(x)) ==> g(x)); - - assert (forall x:int :: - { sk_hack(in_set(next(x))) } - in_set(x) ==> g(x)); - } - +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" +function in_set(int) returns(bool); +function next(int) returns(int); +function f(int) returns(bool); +function g(int) returns(bool); + +// this function is treated specially by Z3 when used in triggers +// sk_hack(f(x)) means to activate the e-node f(x0) when trying to prove +// !(forall x : T :: {sk_hack(f(x))} p(x)) by proving !p(x0) +// (i.e., after skolemization of x to x0). +function sk_hack(bool) returns(bool); + +// PR: sk_hack cannot be defined as a polymorphic function +// when using /quantifierTypePremisses:a, because then it would +// get an additional explicit type parameter, and Z3 would +// no longer recognise it. + +procedure foo() +{ + assume (forall x:int :: {in_set(next(x))} + in_set(x) ==> in_set(next(x))); + + assume (forall x:int :: {in_set(x)} + in_set(x) ==> f(x)); + + assume (forall x:int :: {f(next(x))} + f(next(x)) ==> g(x)); + + assert (forall x:int :: + { sk_hack(in_set(next(x))) } + in_set(x) ==> g(x)); + } + diff --git a/Test/test2/strings-no-where.bpl b/Test/test2/strings-no-where.bpl index 6a89a9b2..79dd2ddb 100644 --- a/Test/test2/strings-no-where.bpl +++ b/Test/test2/strings-no-where.bpl @@ -1,997 +1,997 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - - -type elements; - -type struct; - -var $Heap: [ref,name]any; -function cast(S) returns (T); -function IsHeap(h: [ref,name]any) returns (bool); - -const unique $allocated: name; - -const unique $elements: name; - -const unique $inv: name; - -const unique $writable: name; - -const unique $sharingMode: name; - -const unique $SharingMode_Unshared: name; - -const unique $SharingMode_LockProtected: name; - -function ClassRepr(class: name) returns (ref); - -axiom (forall c0: name, c1: name :: c0 != c1 ==> ClassRepr(c0) != ClassRepr(c1)); - -axiom (forall T: name :: !($typeof(ClassRepr(T)) <: System.Object)); - -axiom (forall T: name :: ClassRepr(T) != null); - -axiom (forall T: name, h: [ref,name]any :: { h[ClassRepr(T), $writable] } IsHeap(h) ==> cast(h[ClassRepr(T), $writable]):bool); - -function IsDirectlyModifiableField(f: name) returns (bool); - -axiom !IsDirectlyModifiableField($allocated); - -axiom IsDirectlyModifiableField($elements); - -axiom !IsDirectlyModifiableField($inv); - -axiom !IsDirectlyModifiableField($writable); - -function IsStaticField(f: name) returns (bool); - -axiom !IsStaticField($allocated); - -axiom !IsStaticField($elements); - -axiom !IsStaticField($inv); - -axiom !IsStaticField($writable); - -function ValueArrayGet(elements, int) returns (any); - -function ValueArraySet(elements, int, any) returns (elements); - -function RefArrayGet(elements, int) returns (ref); - -function RefArraySet(elements, int, ref) returns (elements); - -axiom (forall A: elements, i: int, x: any :: ValueArrayGet(ValueArraySet(A, i, x), i) == x); - -axiom (forall A: elements, i: int, j: int, x: any :: i != j ==> ValueArrayGet(ValueArraySet(A, i, x), j) == ValueArrayGet(A, j)); - -axiom (forall A: elements, i: int, x: ref :: RefArrayGet(RefArraySet(A, i, x), i) == x); - -axiom (forall A: elements, i: int, j: int, x: ref :: i != j ==> RefArrayGet(RefArraySet(A, i, x), j) == RefArrayGet(A, j)); - -function ArrayIndex(arr: ref, dim: int, indexAtDim: int, remainingIndexContribution: int) returns (int); - -axiom (forall a: ref, d: int, x: int, y: int, x': int, y': int :: ArrayIndex(a, d, x, y) == ArrayIndex(a, d, x', y') ==> x == x' && y == y'); - -axiom (forall a: ref, T: name, i: int, r: int, heap: [ref,name]any :: $typeof(a) <: RefArray(T, r) ==> $Is(RefArrayGet(cast(heap[a, $elements]):elements, i), T)); - -function $Rank(ref) returns (int); - -axiom (forall a: ref :: 1 <= $Rank(a)); - -axiom (forall a: ref, T: name, r: int :: { $Is(a, ValueArray(T, r)) } $Is(a, ValueArray(T, r)) ==> $Rank(a) == r); - -axiom (forall a: ref, T: name, r: int :: { $Is(a, RefArray(T, r)) } $Is(a, RefArray(T, r)) ==> $Rank(a) == r); - -function $Length(ref) returns (int); - -axiom (forall a: ref :: { $Length(a) } 0 <= $Length(a)); - -function $DimLength(ref, int) returns (int); - -axiom (forall a: ref, i: int :: 0 <= $DimLength(a, i)); - -axiom (forall a: ref :: $Rank(a) == 1 ==> $DimLength(a, 0) == $Length(a)); - -function $LBound(ref, int) returns (int); - -function $UBound(ref, int) returns (int); - -axiom (forall a: ref, i: int :: { $LBound(a, i) } $LBound(a, i) == 0); - -axiom (forall a: ref, i: int :: { $UBound(a, i) } $UBound(a, i) == $DimLength(a, i) - 1); - -const unique System.Array: name; - -axiom $IsClass(System.Array); - -axiom System.Array <: System.Object; - -function $ElementType(name) returns (name); - -function ValueArray(elementType: name, rank: int) returns (name); - -axiom (forall T: name, r: int :: { ValueArray(T, r) } ValueArray(T, r) <: System.Array); - -function RefArray(elementType: name, rank: int) returns (name); - -axiom (forall T: name, r: int :: { RefArray(T, r) } RefArray(T, r) <: System.Array); - -axiom (forall T: name, U: name, r: int :: U <: T ==> RefArray(U, r) <: RefArray(T, r)); - -axiom (forall A: name, r: int :: $ElementType(ValueArray(A, r)) == A); - -axiom (forall A: name, r: int :: $ElementType(RefArray(A, r)) == A); - -axiom (forall A: name, r: int, T: name :: { T <: RefArray(A, r) } T <: RefArray(A, r) ==> T == RefArray($ElementType(T), r) && $ElementType(T) <: A); - -axiom (forall A: name, r: int, T: name :: { T <: ValueArray(A, r) } T <: ValueArray(A, r) ==> T == ValueArray(A, r)); - -axiom (forall A: name, r: int, T: name :: RefArray(A, r) <: T ==> System.Array <: T || (T == RefArray($ElementType(T), r) && A <: $ElementType(T))); - -axiom (forall A: name, r: int, T: name :: ValueArray(A, r) <: T ==> System.Array <: T || T == ValueArray(A, r)); - -function $ArrayPtr(elementType: name) returns (name); - -function $StructGet(struct, name) returns (any); - -function $StructSet(struct, name, any) returns (struct); - -axiom (forall s: struct, f: name, x: any :: $StructGet($StructSet(s, f, x), f) == x); - -axiom (forall s: struct, f: name, f': name, x: any :: f != f' ==> $StructGet($StructSet(s, f, x), f') == $StructGet(s, f')); - -function ZeroInit(s: struct, typ: name) returns (bool); - -function $typeof(ref) returns (name); - -function Implements(class: name, interface: name) returns (bool); - -axiom (forall T: name, J: name :: { Implements(T, J) } Implements(T, J) ==> T <: J); - -function InterfaceExtends(subIntf: name, superIntf: name) returns (bool); - -axiom (forall J: name, K: name :: { InterfaceExtends(J, K) } InterfaceExtends(J, K) ==> J <: K); - -function $IsClass(name) returns (bool); - -axiom (forall C: name :: { $IsClass(C) } $IsClass(C) ==> C <: C); - -function AsDirectSubClass(sub: name, base: name) returns (sub': name); - -function OneClassDown(sub: name, base: name) returns (directSub: name); - -axiom (forall A: name, B: name, C: name :: { C <: AsDirectSubClass(B, A) } C <: AsDirectSubClass(B, A) ==> OneClassDown(C, A) == B); - -function $IsInterface(name) returns (bool); - -axiom (forall J: name :: { $IsInterface(J) } $IsInterface(J) ==> J <: System.Object); - -function $IsValueType(name) returns (bool); - -axiom (forall T: name :: $IsValueType(T) ==> (forall U: name :: T <: U ==> T == U) && (forall U: name :: U <: T ==> T == U)); - -const unique System.Object: name; - -axiom $IsClass(System.Object); - -function $IsTokenForType(struct, name) returns (bool); - -function TypeObject(name) returns (ref); - -const unique System.Type: name; - -axiom System.Type <: System.Object; - -axiom (forall T: name :: { TypeObject(T) } $IsNotNull(TypeObject(T), System.Type)); - -function $Is(ref, name) returns (bool); - -axiom (forall o: ref, T: name :: { $Is(o, T) } $Is(o, T) <==> o == null || $typeof(o) <: T); - -function $IsNotNull(ref, name) returns (bool); - -axiom (forall o: ref, T: name :: { $IsNotNull(o, T) } $IsNotNull(o, T) <==> o != null && $Is(o, T)); - -function $As(ref, name) returns (ref); - -axiom (forall o: ref, T: name :: $Is(o, T) ==> $As(o, T) == o); - -axiom (forall o: ref, T: name :: !$Is(o, T) ==> $As(o, T) == null); - -axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, RefArray(A, r)) ==> heap[o, $inv] == $typeof(o)); - -axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, ValueArray(A, r)) ==> heap[o, $inv] == $typeof(o)); - -function IsAllocated(h: [ref,name]any, o: any) returns (bool); - -axiom (forall h: [ref,name]any, o: ref, f: name :: { IsAllocated(h, h[o, f]) } IsHeap(h) ==> IsAllocated(h, h[o, f])); - -axiom (forall h: [ref,name]any, s: struct, f: name :: { IsAllocated(h, $StructGet(s, f)) } IsAllocated(h, s) ==> IsAllocated(h, $StructGet(s, f))); - -axiom (forall h: [ref,name]any, e: elements, i: int :: { IsAllocated(h, RefArrayGet(e, i)) } IsAllocated(h, e) ==> IsAllocated(h, RefArrayGet(e, i))); - -axiom (forall h: [ref,name]any, o: ref :: { h[o, $allocated] } IsAllocated(h, o) ==> cast(h[o, $allocated]):bool); - -axiom (forall h: [ref,name]any, c: name :: { h[ClassRepr(c), $allocated] } IsHeap(h) ==> cast(h[ClassRepr(c), $allocated]):bool); - -function DeclType(field: name) returns (class: name); - -function AsNonNullRefField(field: name, T: name) returns (f: name); - -function AsRefField(field: name, T: name) returns (f: name); - -function AsRangeField(field: name, T: name) returns (f: name); - -axiom (forall f: name, T: name :: { AsNonNullRefField(f, T) } AsNonNullRefField(f, T) == f ==> AsRefField(f, T) == f); - -axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRefField(f, T)] } IsHeap(h) ==> $Is(cast(h[o, AsRefField(f, T)]):ref, T)); - -axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsNonNullRefField(f, T)] } IsHeap(h) ==> cast(h[o, AsNonNullRefField(f, T)]):ref != null); - -axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRangeField(f, T)] } IsHeap(h) ==> InRange(cast(h[o, AsRangeField(f, T)]):int, T)); - -const unique System.String: name; - -axiom (forall h: [ref,name]any, s: ref :: IsHeap(h) && $typeof(s) == System.String ==> h[s, $inv] == $typeof(s) && cast(h[s, $writable]):bool); - -function AsOwnedField(f: name) returns (name); - -axiom (forall h: [ref,name]any, o: ref, f: name :: { h[o, AsOwnedField(f)] } IsHeap(h) && cast(h[o, $inv]):name <: DeclType(AsOwnedField(f)) ==> cast(h[o, AsOwnedField(f)]):ref == null || $typeof(cast(h[o, AsOwnedField(f)]):ref) == System.String || !cast(h[cast(h[o, AsOwnedField(f)]):ref, $writable]):bool); - -axiom (forall h: [ref,name]any, o: ref :: { h[o, $writable] } IsHeap(h) && !cast(h[o, $writable]):bool ==> cast(h[o, $inv]):name == $typeof(o)); - -function Box(any, ref) returns (ref); - -function Unbox(ref) returns (any); - -axiom (forall x: any, p: ref :: { Unbox(Box(x, p)) } Unbox(Box(x, p)) == x); - -axiom (forall heap: [ref,name]any, x: any, p: ref :: { heap[Box(x, p), $inv] } IsHeap(heap) ==> heap[Box(x, p), $inv] == $typeof(Box(x, p))); - -function UnboxedType(ref) returns (name); - -function BoxTester(p: ref, typ: name) returns (ref); - -axiom (forall p: ref, typ: name :: { BoxTester(p, typ) } UnboxedType(p) == typ <==> BoxTester(p, typ) != null); - -const unique System.Int16: name; - -axiom $IsValueType(System.Int16); - -const unique System.Int32: name; - -axiom $IsValueType(System.Int32); - -const unique System.Int64: name; - -axiom $IsValueType(System.Int64); - -const unique System.Byte: name; - -axiom $IsValueType(System.Byte); - -const unique System.Int16.MinValue: int; - -const unique System.Int16.MaxValue: int; - -const unique System.Int32.MinValue: int; - -const unique System.Int32.MaxValue: int; - -const unique System.Int64.MinValue: int; - -const unique System.Int64.MaxValue: int; - -axiom System.Int64.MinValue < System.Int32.MinValue; - -axiom System.Int32.MinValue < System.Int16.MinValue; - -axiom System.Int16.MinValue < System.Int16.MaxValue; - -axiom System.Int16.MaxValue < System.Int32.MaxValue; - -axiom System.Int32.MaxValue < System.Int64.MaxValue; - -function InRange(i: int, T: name) returns (bool); - -axiom (forall i: int :: InRange(i, System.Int16) <==> System.Int16.MinValue <= i && i <= System.Int16.MaxValue); - -axiom (forall i: int :: InRange(i, System.Int32) <==> System.Int32.MinValue <= i && i <= System.Int32.MaxValue); - -axiom (forall i: int :: InRange(i, System.Int64) <==> System.Int64.MinValue <= i && i <= System.Int64.MaxValue); - -axiom (forall i: int :: { InRange(i, System.Byte) } InRange(i, System.Byte) <==> 0 <= i && i < 256); - -function $RealToInt(real) returns (int); - -function $IntToReal(int) returns (real); - -function $SizeIs(name, int) returns (bool); - -function $IfThenElse(bool, any, any) returns (any); - -axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } b ==> $IfThenElse(b, x, y) == x); - -axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } !b ==> $IfThenElse(b, x, y) == y); - -function #neg(int) returns (int); - -function #rneg(real) returns (real); - -function #rdiv(real, real) returns (real); - -function #and(int, int) returns (int); - -function #or(int, int) returns (int); - -function #xor(int, int) returns (int); - -function #shl(int, int) returns (int); - -function #shr(int, int) returns (int); - -axiom (forall x: int, y: int :: { x mod y } { x div y } x mod y == x - x div y * y); - -axiom (forall x: int, y: int :: { x mod y } 0 <= x && 0 < y ==> 0 <= x mod y && x mod y < y); - -axiom (forall x: int, y: int :: { x mod y } 0 <= x && y < 0 ==> 0 <= x mod y && x mod y < 0 - y); - -axiom (forall x: int, y: int :: { x mod y } x <= 0 && 0 < y ==> 0 - y < x mod y && x mod y <= 0); - -axiom (forall x: int, y: int :: { x mod y } x <= 0 && y < 0 ==> y < x mod y && x mod y <= 0); - -axiom (forall x: int, y: int :: { (x + y) mod y } 0 <= x && 0 <= y ==> (x + y) mod y == x mod y); - -axiom (forall x: int, y: int :: { (y + x) mod y } 0 <= x && 0 <= y ==> (y + x) mod y == x mod y); - -axiom (forall x: int, y: int :: { (x - y) mod y } 0 <= x - y && 0 <= y ==> (x - y) mod y == x mod y); - -axiom (forall a: int, b: int, d: int :: { a mod d,b mod d } 2 <= d && a mod d == b mod d && a < b ==> a + d <= b); - -axiom (forall i: int :: { #shl(i, 0) } #shl(i, 0) == i); - -axiom (forall i: int, j: int :: 0 <= j ==> #shl(i, j + 1) == #shl(i, j) * 2); - -axiom (forall i: int :: { #shr(i, 0) } #shr(i, 0) == i); - -axiom (forall i: int, j: int :: 0 <= j ==> #shr(i, j + 1) == #shr(i, j) div 2); - -const unique $UnknownRef: ref; - -const unique System.IComparable: name; - -const unique Microsoft.Singularity.Applications.ThreadTest: name; - -const unique System.Threading.Thread: name; - -const unique System.Collections.IEnumerable: name; - -const unique System.Threading.ThreadStart: name; - -const unique System.ICloneable: name; - -const unique System.MulticastDelegate: name; - -const unique System.Delegate: name; - -const unique $stringLiteral0: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral0, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral0, $allocated]):bool) && $IsNotNull($stringLiteral0, System.String) && $Length($stringLiteral0) == 13; - -const unique $stringLiteral1: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral1, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral1, $allocated]):bool) && $IsNotNull($stringLiteral1, System.String) && $Length($stringLiteral1) == 14; - -const unique $stringLiteral2: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral2, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral2, $allocated]):bool) && $IsNotNull($stringLiteral2, System.String) && $Length($stringLiteral2) == 11; - -const unique $stringLiteral3: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral3, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral3, $allocated]):bool) && $IsNotNull($stringLiteral3, System.String) && $Length($stringLiteral3) == 18; - -const unique $stringLiteral4: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral4, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral4, $allocated]):bool) && $IsNotNull($stringLiteral4, System.String) && $Length($stringLiteral4) == 19; - -const unique $stringLiteral5: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral5, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral5, $allocated]):bool) && $IsNotNull($stringLiteral5, System.String) && $Length($stringLiteral5) == 14; - -const unique $stringLiteral6: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral6, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral6, $allocated]):bool) && $IsNotNull($stringLiteral6, System.String) && $Length($stringLiteral6) == 15; - -const unique $stringLiteral7: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral7, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral7, $allocated]):bool) && $IsNotNull($stringLiteral7, System.String) && $Length($stringLiteral7) == 11; - -const unique $stringLiteral8: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral8, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral8, $allocated]):bool) && $IsNotNull($stringLiteral8, System.String) && $Length($stringLiteral8) == 19; - -const unique $stringLiteral9: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral9, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral9, $allocated]):bool) && $IsNotNull($stringLiteral9, System.String) && $Length($stringLiteral9) == 20; - -const unique $stringLiteral10: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral10, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral10, $allocated]):bool) && $IsNotNull($stringLiteral10, System.String) && $Length($stringLiteral10) == 22; - -const unique $stringLiteral11: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral11, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral11, $allocated]):bool) && $IsNotNull($stringLiteral11, System.String) && $Length($stringLiteral11) == 21; - -const unique $stringLiteral12: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral12, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral12, $allocated]):bool) && $IsNotNull($stringLiteral12, System.String) && $Length($stringLiteral12) == 23; - -const unique $stringLiteral13: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral13, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral13, $allocated]):bool) && $IsNotNull($stringLiteral13, System.String) && $Length($stringLiteral13) == 22; - -axiom $IsClass(Microsoft.Singularity.Applications.ThreadTest); - -axiom Microsoft.Singularity.Applications.ThreadTest <: System.Object && AsDirectSubClass(Microsoft.Singularity.Applications.ThreadTest, System.Object) == Microsoft.Singularity.Applications.ThreadTest; - -axiom (forall $K: name :: { Microsoft.Singularity.Applications.ThreadTest <: $K } Microsoft.Singularity.Applications.ThreadTest <: $K <==> Microsoft.Singularity.Applications.ThreadTest == $K || System.Object <: $K); - -function Inv_Microsoft.Singularity.Applications.ThreadTest(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) } Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest } { Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest ==> Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap)); - -procedure Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod(); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -implementation Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod() -{ - var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block1513$LoopPreheader: [ref,name]any; - - entry: - assume IsHeap($Heap); - goto block1479; - - block1479: - goto block1496; - - block1496: - // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) - stack0o := $stringLiteral0; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) - stack0o := $stringLiteral1; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,18) - i := 0; - goto block1513$LoopPreheader; - - block1513: - // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - assert (forall $o: ref :: $Heap$block1513$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool != true); - assert (forall $o: ref :: cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - stack0i := 10; - // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - stack0b := i >= stack0i; - // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - goto true1513to1547, false1513to1530; - - true1513to1547: - assume stack0b == true; - goto block1547; - - false1513to1530: - assume stack0b == false; - goto block1530; - - block1547: - // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) - stack0o := $stringLiteral3; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) - stack0o := $stringLiteral4; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(31,10) - return; - - block1530: - // ----- load constant [0] ... ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) - stack0o := $stringLiteral2; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) - // Commented out, to avoid problems with the theorem prover nondeterministically choosing this error over the one 12 lines above: call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(26,17) - call System.Threading.Thread.Yield(); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,37) - local1 := i; - // ----- load constant 1 - stack0i := 1; - // ----- binary operator - stack0i := local1 + stack0i; - // ----- copy - i := stack0i; - // ----- copy - stack0i := local1; - // ----- branch - goto block1513; - - block1513$LoopPreheader: - $Heap$block1513$LoopPreheader := $Heap; - goto block1513; - -} - - - -axiom $IsClass(System.String); - -axiom System.String <: System.Object && AsDirectSubClass(System.String, System.Object) == System.String; - -axiom $IsInterface(System.IComparable); - -axiom (forall $K: name :: { System.IComparable <: $K } System.IComparable <: $K <==> System.IComparable == $K || System.Object == $K); - -axiom Implements(System.String, System.IComparable); - -axiom $IsInterface(System.ICloneable); - -axiom (forall $K: name :: { System.ICloneable <: $K } System.ICloneable <: $K <==> System.ICloneable == $K || System.Object == $K); - -axiom Implements(System.String, System.ICloneable); - -axiom $IsInterface(System.Collections.IEnumerable); - -axiom (forall $K: name :: { System.Collections.IEnumerable <: $K } System.Collections.IEnumerable <: $K <==> System.Collections.IEnumerable == $K || System.Object == $K); - -axiom Implements(System.String, System.Collections.IEnumerable); - -axiom (forall $K: name :: { System.String <: $K } System.String <: $K <==> System.String == $K || System.Object <: $K || System.IComparable <: $K || System.ICloneable <: $K || System.Collections.IEnumerable <: $K); - -axiom (forall $U: name :: { $U <: System.String } $U <: System.String ==> $U == System.String); - -function Inv_System.String(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.String(this, heap) } Inv_System.String(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.String } { Inv_System.String($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.String ==> Inv_System.String($o, heap)); - -procedure System.Console.WriteLine$System.String(value$in: ref); - requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure Microsoft.Singularity.DebugStub.Print$System.String(value$in: ref); - requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure System.Threading.Thread.Yield(); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod(); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -implementation Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod() -{ - var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block2516$LoopPreheader: [ref,name]any; - - entry: - assume IsHeap($Heap); - goto block2482; - - block2482: - goto block2499; - - block2499: - // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) - stack0o := $stringLiteral5; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) - stack0o := $stringLiteral6; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,18) - i := 0; - goto block2516$LoopPreheader; - - block2516: - // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - assert (forall $o: ref :: $Heap$block2516$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool != true); - assert (forall $o: ref :: cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - stack0i := 10; - // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - stack0b := i >= stack0i; - // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - goto true2516to2550, false2516to2533; - - true2516to2550: - assume stack0b == true; - goto block2550; - - false2516to2533: - assume stack0b == false; - goto block2533; - - block2550: - // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) - stack0o := $stringLiteral8; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) - stack0o := $stringLiteral9; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(46,10) - return; - - block2533: - // ----- load constant ... [1] ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) - stack0o := $stringLiteral7; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) - // Commented out, to avoid problems with the theorem prover nondeterministically choosing this error over the one 12 lines above: call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(41,17) - call System.Threading.Thread.Yield(); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,37) - local1 := i; - // ----- load constant 1 - stack0i := 1; - // ----- binary operator - stack0i := local1 + stack0i; - // ----- copy - i := stack0i; - // ----- copy - stack0i := local1; - // ----- branch - goto block2516; - - block2516$LoopPreheader: - $Heap$block2516$LoopPreheader := $Heap; - goto block2516; - -} - - - -procedure Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int); - requires args$in == null || (cast($Heap[args$in, $writable]):bool == true && cast($Heap[args$in, $inv]):name == $typeof(args$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures IsAllocated($Heap, $result); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -implementation Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int) -{ - var args: ref, stack0o: ref, stack1o: ref, stack50000o: ref, t1: ref, t2: ref, i: int, stack0i: int, stack0b: bool, local3: int, return.value: int, SS$Display.Return.Local: int, $Heap$block3825$LoopPreheader: [ref,name]any; - - entry: - assume IsHeap($Heap); - args := args$in; - assume $Is(args, RefArray(System.String, 1)); - assume cast($Heap[args$in, $allocated]):bool == true; - goto block3791; - - block3791: - goto block3808; - - block3808: - stack0o := null; - // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - havoc stack1o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - assert stack50000o != null; - call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - stack0o := stack50000o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - assert stack50000o != null; - call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - stack0o := stack50000o; - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - t1 := stack0o; - stack0o := null; - // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - havoc stack1o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - assert stack50000o != null; - call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - stack0o := stack50000o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - assert stack50000o != null; - call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - stack0o := stack50000o; - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - t2 := stack0o; - // ----- load constant Starting first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) - stack0o := $stringLiteral10; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(55,13) - assert t1 != null; - call System.Threading.Thread.Start(t1); - // ----- load constant Started first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) - stack0o := $stringLiteral11; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant Starting second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) - stack0o := $stringLiteral12; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(59,13) - assert t2 != null; - call System.Threading.Thread.Start(t2); - // ----- load constant Started second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) - stack0o := $stringLiteral13; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,18) - i := 0; - goto block3825$LoopPreheader; - - block3825: - // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - assert (forall $o: ref :: $Heap$block3825$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool != true); - assert (forall $o: ref :: cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - // ----- load constant 30 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - stack0i := 30; - // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - stack0b := i >= stack0i; - // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - goto true3825to3859, false3825to3842; - - true3825to3859: - assume stack0b == true; - goto block3859; - - false3825to3842: - assume stack0b == false; - goto block3842; - - block3859: - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(66,13) - return.value := 0; - // ----- branch - goto block3876; - - block3842: - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(64,17) - call System.Threading.Thread.Yield(); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,37) - local3 := i; - // ----- load constant 1 - stack0i := 1; - // ----- binary operator - stack0i := local3 + stack0i; - // ----- copy - i := stack0i; - // ----- copy - stack0i := local3; - // ----- branch - goto block3825; - - block3876: - // ----- copy - SS$Display.Return.Local := return.value; - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) - stack0i := return.value; - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) - $result := stack0i; - return; - - block3825$LoopPreheader: - $Heap$block3825$LoopPreheader := $Heap; - goto block3825; - -} - - - -axiom $IsClass(System.Threading.ThreadStart); - -axiom $IsClass(System.MulticastDelegate); - -axiom $IsClass(System.Delegate); - -axiom System.Delegate <: System.Object && AsDirectSubClass(System.Delegate, System.Object) == System.Delegate; - -axiom Implements(System.Delegate, System.ICloneable); - -axiom (forall $K: name :: { System.Delegate <: $K } System.Delegate <: $K <==> System.Delegate == $K || System.Object <: $K || System.ICloneable <: $K); - -function Inv_System.Delegate(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Delegate(this, heap) } Inv_System.Delegate(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Delegate } { Inv_System.Delegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Delegate ==> Inv_System.Delegate($o, heap)); - -axiom System.MulticastDelegate <: System.Delegate && AsDirectSubClass(System.MulticastDelegate, System.Delegate) == System.MulticastDelegate; - -axiom (forall $K: name :: { System.MulticastDelegate <: $K } System.MulticastDelegate <: $K <==> System.MulticastDelegate == $K || System.Delegate <: $K); - -function Inv_System.MulticastDelegate(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.MulticastDelegate(this, heap) } Inv_System.MulticastDelegate(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.MulticastDelegate } { Inv_System.MulticastDelegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.MulticastDelegate ==> Inv_System.MulticastDelegate($o, heap)); - -axiom System.Threading.ThreadStart <: System.MulticastDelegate && AsDirectSubClass(System.Threading.ThreadStart, System.MulticastDelegate) == System.Threading.ThreadStart; - -axiom (forall $K: name :: { System.Threading.ThreadStart <: $K } System.Threading.ThreadStart <: $K <==> System.Threading.ThreadStart == $K || System.MulticastDelegate <: $K); - -axiom (forall $U: name :: { $U <: System.Threading.ThreadStart } $U <: System.Threading.ThreadStart ==> $U == System.Threading.ThreadStart); - -function Inv_System.Threading.ThreadStart(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.ThreadStart(this, heap) } Inv_System.Threading.ThreadStart(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.ThreadStart } { Inv_System.Threading.ThreadStart($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.ThreadStart ==> Inv_System.Threading.ThreadStart($o, heap)); - -procedure System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(this: ref, object$in: ref, method$in: ref); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.ThreadStart; - - - -axiom $IsClass(System.Threading.Thread); - -axiom System.Threading.Thread <: System.Object && AsDirectSubClass(System.Threading.Thread, System.Object) == System.Threading.Thread; - -axiom (forall $K: name :: { System.Threading.Thread <: $K } System.Threading.Thread <: $K <==> System.Threading.Thread == $K || System.Object <: $K); - -axiom (forall $U: name :: { $U <: System.Threading.Thread } $U <: System.Threading.Thread ==> $U == System.Threading.Thread); - -function Inv_System.Threading.Thread(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.Thread(this, heap) } Inv_System.Threading.Thread(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.Thread } { Inv_System.Threading.Thread($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.Thread ==> Inv_System.Threading.Thread($o, heap)); - -procedure System.Threading.Thread..ctor$System.Threading.ThreadStart(this: ref, start$in: ref); - requires start$in == null || (cast($Heap[start$in, $writable]):bool == true && cast($Heap[start$in, $inv]):name == $typeof(start$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Threading.Thread <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.Thread; - ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; - - - -procedure System.Threading.Thread.Start(this: ref); - requires cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == $typeof(this); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(Microsoft.Singularity.Applications.ThreadTest <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == Microsoft.Singularity.Applications.ThreadTest; - ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; - - - -implementation Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref) -{ - - entry: - assume IsHeap($Heap); - assume $IsNotNull(this, Microsoft.Singularity.Applications.ThreadTest); - assume cast($Heap[this, $allocated]):bool == true; - assume cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; - goto block4777; - - block4777: - goto block4794; - - block4794: - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,18) - assert this != null; - call System.Object..ctor(this); - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,28) - assert this != null; - assert cast($Heap[this, $writable]):bool == true && System.Object <: cast($Heap[this, $inv]):name; - assert cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; - assert Inv_Microsoft.Singularity.Applications.ThreadTest(this, $Heap); - $Heap[this, $inv] := Microsoft.Singularity.Applications.ThreadTest; - return; - -} - - - -procedure System.Object..ctor(this: ref); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Object <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; - ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; - - - -type ref, name, any; -const null : ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + + +type elements; + +type struct; + +var $Heap: [ref,name]any; +function cast(S) returns (T); +function IsHeap(h: [ref,name]any) returns (bool); + +const unique $allocated: name; + +const unique $elements: name; + +const unique $inv: name; + +const unique $writable: name; + +const unique $sharingMode: name; + +const unique $SharingMode_Unshared: name; + +const unique $SharingMode_LockProtected: name; + +function ClassRepr(class: name) returns (ref); + +axiom (forall c0: name, c1: name :: c0 != c1 ==> ClassRepr(c0) != ClassRepr(c1)); + +axiom (forall T: name :: !($typeof(ClassRepr(T)) <: System.Object)); + +axiom (forall T: name :: ClassRepr(T) != null); + +axiom (forall T: name, h: [ref,name]any :: { h[ClassRepr(T), $writable] } IsHeap(h) ==> cast(h[ClassRepr(T), $writable]):bool); + +function IsDirectlyModifiableField(f: name) returns (bool); + +axiom !IsDirectlyModifiableField($allocated); + +axiom IsDirectlyModifiableField($elements); + +axiom !IsDirectlyModifiableField($inv); + +axiom !IsDirectlyModifiableField($writable); + +function IsStaticField(f: name) returns (bool); + +axiom !IsStaticField($allocated); + +axiom !IsStaticField($elements); + +axiom !IsStaticField($inv); + +axiom !IsStaticField($writable); + +function ValueArrayGet(elements, int) returns (any); + +function ValueArraySet(elements, int, any) returns (elements); + +function RefArrayGet(elements, int) returns (ref); + +function RefArraySet(elements, int, ref) returns (elements); + +axiom (forall A: elements, i: int, x: any :: ValueArrayGet(ValueArraySet(A, i, x), i) == x); + +axiom (forall A: elements, i: int, j: int, x: any :: i != j ==> ValueArrayGet(ValueArraySet(A, i, x), j) == ValueArrayGet(A, j)); + +axiom (forall A: elements, i: int, x: ref :: RefArrayGet(RefArraySet(A, i, x), i) == x); + +axiom (forall A: elements, i: int, j: int, x: ref :: i != j ==> RefArrayGet(RefArraySet(A, i, x), j) == RefArrayGet(A, j)); + +function ArrayIndex(arr: ref, dim: int, indexAtDim: int, remainingIndexContribution: int) returns (int); + +axiom (forall a: ref, d: int, x: int, y: int, x': int, y': int :: ArrayIndex(a, d, x, y) == ArrayIndex(a, d, x', y') ==> x == x' && y == y'); + +axiom (forall a: ref, T: name, i: int, r: int, heap: [ref,name]any :: $typeof(a) <: RefArray(T, r) ==> $Is(RefArrayGet(cast(heap[a, $elements]):elements, i), T)); + +function $Rank(ref) returns (int); + +axiom (forall a: ref :: 1 <= $Rank(a)); + +axiom (forall a: ref, T: name, r: int :: { $Is(a, ValueArray(T, r)) } $Is(a, ValueArray(T, r)) ==> $Rank(a) == r); + +axiom (forall a: ref, T: name, r: int :: { $Is(a, RefArray(T, r)) } $Is(a, RefArray(T, r)) ==> $Rank(a) == r); + +function $Length(ref) returns (int); + +axiom (forall a: ref :: { $Length(a) } 0 <= $Length(a)); + +function $DimLength(ref, int) returns (int); + +axiom (forall a: ref, i: int :: 0 <= $DimLength(a, i)); + +axiom (forall a: ref :: $Rank(a) == 1 ==> $DimLength(a, 0) == $Length(a)); + +function $LBound(ref, int) returns (int); + +function $UBound(ref, int) returns (int); + +axiom (forall a: ref, i: int :: { $LBound(a, i) } $LBound(a, i) == 0); + +axiom (forall a: ref, i: int :: { $UBound(a, i) } $UBound(a, i) == $DimLength(a, i) - 1); + +const unique System.Array: name; + +axiom $IsClass(System.Array); + +axiom System.Array <: System.Object; + +function $ElementType(name) returns (name); + +function ValueArray(elementType: name, rank: int) returns (name); + +axiom (forall T: name, r: int :: { ValueArray(T, r) } ValueArray(T, r) <: System.Array); + +function RefArray(elementType: name, rank: int) returns (name); + +axiom (forall T: name, r: int :: { RefArray(T, r) } RefArray(T, r) <: System.Array); + +axiom (forall T: name, U: name, r: int :: U <: T ==> RefArray(U, r) <: RefArray(T, r)); + +axiom (forall A: name, r: int :: $ElementType(ValueArray(A, r)) == A); + +axiom (forall A: name, r: int :: $ElementType(RefArray(A, r)) == A); + +axiom (forall A: name, r: int, T: name :: { T <: RefArray(A, r) } T <: RefArray(A, r) ==> T == RefArray($ElementType(T), r) && $ElementType(T) <: A); + +axiom (forall A: name, r: int, T: name :: { T <: ValueArray(A, r) } T <: ValueArray(A, r) ==> T == ValueArray(A, r)); + +axiom (forall A: name, r: int, T: name :: RefArray(A, r) <: T ==> System.Array <: T || (T == RefArray($ElementType(T), r) && A <: $ElementType(T))); + +axiom (forall A: name, r: int, T: name :: ValueArray(A, r) <: T ==> System.Array <: T || T == ValueArray(A, r)); + +function $ArrayPtr(elementType: name) returns (name); + +function $StructGet(struct, name) returns (any); + +function $StructSet(struct, name, any) returns (struct); + +axiom (forall s: struct, f: name, x: any :: $StructGet($StructSet(s, f, x), f) == x); + +axiom (forall s: struct, f: name, f': name, x: any :: f != f' ==> $StructGet($StructSet(s, f, x), f') == $StructGet(s, f')); + +function ZeroInit(s: struct, typ: name) returns (bool); + +function $typeof(ref) returns (name); + +function Implements(class: name, interface: name) returns (bool); + +axiom (forall T: name, J: name :: { Implements(T, J) } Implements(T, J) ==> T <: J); + +function InterfaceExtends(subIntf: name, superIntf: name) returns (bool); + +axiom (forall J: name, K: name :: { InterfaceExtends(J, K) } InterfaceExtends(J, K) ==> J <: K); + +function $IsClass(name) returns (bool); + +axiom (forall C: name :: { $IsClass(C) } $IsClass(C) ==> C <: C); + +function AsDirectSubClass(sub: name, base: name) returns (sub': name); + +function OneClassDown(sub: name, base: name) returns (directSub: name); + +axiom (forall A: name, B: name, C: name :: { C <: AsDirectSubClass(B, A) } C <: AsDirectSubClass(B, A) ==> OneClassDown(C, A) == B); + +function $IsInterface(name) returns (bool); + +axiom (forall J: name :: { $IsInterface(J) } $IsInterface(J) ==> J <: System.Object); + +function $IsValueType(name) returns (bool); + +axiom (forall T: name :: $IsValueType(T) ==> (forall U: name :: T <: U ==> T == U) && (forall U: name :: U <: T ==> T == U)); + +const unique System.Object: name; + +axiom $IsClass(System.Object); + +function $IsTokenForType(struct, name) returns (bool); + +function TypeObject(name) returns (ref); + +const unique System.Type: name; + +axiom System.Type <: System.Object; + +axiom (forall T: name :: { TypeObject(T) } $IsNotNull(TypeObject(T), System.Type)); + +function $Is(ref, name) returns (bool); + +axiom (forall o: ref, T: name :: { $Is(o, T) } $Is(o, T) <==> o == null || $typeof(o) <: T); + +function $IsNotNull(ref, name) returns (bool); + +axiom (forall o: ref, T: name :: { $IsNotNull(o, T) } $IsNotNull(o, T) <==> o != null && $Is(o, T)); + +function $As(ref, name) returns (ref); + +axiom (forall o: ref, T: name :: $Is(o, T) ==> $As(o, T) == o); + +axiom (forall o: ref, T: name :: !$Is(o, T) ==> $As(o, T) == null); + +axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, RefArray(A, r)) ==> heap[o, $inv] == $typeof(o)); + +axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, ValueArray(A, r)) ==> heap[o, $inv] == $typeof(o)); + +function IsAllocated(h: [ref,name]any, o: any) returns (bool); + +axiom (forall h: [ref,name]any, o: ref, f: name :: { IsAllocated(h, h[o, f]) } IsHeap(h) ==> IsAllocated(h, h[o, f])); + +axiom (forall h: [ref,name]any, s: struct, f: name :: { IsAllocated(h, $StructGet(s, f)) } IsAllocated(h, s) ==> IsAllocated(h, $StructGet(s, f))); + +axiom (forall h: [ref,name]any, e: elements, i: int :: { IsAllocated(h, RefArrayGet(e, i)) } IsAllocated(h, e) ==> IsAllocated(h, RefArrayGet(e, i))); + +axiom (forall h: [ref,name]any, o: ref :: { h[o, $allocated] } IsAllocated(h, o) ==> cast(h[o, $allocated]):bool); + +axiom (forall h: [ref,name]any, c: name :: { h[ClassRepr(c), $allocated] } IsHeap(h) ==> cast(h[ClassRepr(c), $allocated]):bool); + +function DeclType(field: name) returns (class: name); + +function AsNonNullRefField(field: name, T: name) returns (f: name); + +function AsRefField(field: name, T: name) returns (f: name); + +function AsRangeField(field: name, T: name) returns (f: name); + +axiom (forall f: name, T: name :: { AsNonNullRefField(f, T) } AsNonNullRefField(f, T) == f ==> AsRefField(f, T) == f); + +axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRefField(f, T)] } IsHeap(h) ==> $Is(cast(h[o, AsRefField(f, T)]):ref, T)); + +axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsNonNullRefField(f, T)] } IsHeap(h) ==> cast(h[o, AsNonNullRefField(f, T)]):ref != null); + +axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRangeField(f, T)] } IsHeap(h) ==> InRange(cast(h[o, AsRangeField(f, T)]):int, T)); + +const unique System.String: name; + +axiom (forall h: [ref,name]any, s: ref :: IsHeap(h) && $typeof(s) == System.String ==> h[s, $inv] == $typeof(s) && cast(h[s, $writable]):bool); + +function AsOwnedField(f: name) returns (name); + +axiom (forall h: [ref,name]any, o: ref, f: name :: { h[o, AsOwnedField(f)] } IsHeap(h) && cast(h[o, $inv]):name <: DeclType(AsOwnedField(f)) ==> cast(h[o, AsOwnedField(f)]):ref == null || $typeof(cast(h[o, AsOwnedField(f)]):ref) == System.String || !cast(h[cast(h[o, AsOwnedField(f)]):ref, $writable]):bool); + +axiom (forall h: [ref,name]any, o: ref :: { h[o, $writable] } IsHeap(h) && !cast(h[o, $writable]):bool ==> cast(h[o, $inv]):name == $typeof(o)); + +function Box(any, ref) returns (ref); + +function Unbox(ref) returns (any); + +axiom (forall x: any, p: ref :: { Unbox(Box(x, p)) } Unbox(Box(x, p)) == x); + +axiom (forall heap: [ref,name]any, x: any, p: ref :: { heap[Box(x, p), $inv] } IsHeap(heap) ==> heap[Box(x, p), $inv] == $typeof(Box(x, p))); + +function UnboxedType(ref) returns (name); + +function BoxTester(p: ref, typ: name) returns (ref); + +axiom (forall p: ref, typ: name :: { BoxTester(p, typ) } UnboxedType(p) == typ <==> BoxTester(p, typ) != null); + +const unique System.Int16: name; + +axiom $IsValueType(System.Int16); + +const unique System.Int32: name; + +axiom $IsValueType(System.Int32); + +const unique System.Int64: name; + +axiom $IsValueType(System.Int64); + +const unique System.Byte: name; + +axiom $IsValueType(System.Byte); + +const unique System.Int16.MinValue: int; + +const unique System.Int16.MaxValue: int; + +const unique System.Int32.MinValue: int; + +const unique System.Int32.MaxValue: int; + +const unique System.Int64.MinValue: int; + +const unique System.Int64.MaxValue: int; + +axiom System.Int64.MinValue < System.Int32.MinValue; + +axiom System.Int32.MinValue < System.Int16.MinValue; + +axiom System.Int16.MinValue < System.Int16.MaxValue; + +axiom System.Int16.MaxValue < System.Int32.MaxValue; + +axiom System.Int32.MaxValue < System.Int64.MaxValue; + +function InRange(i: int, T: name) returns (bool); + +axiom (forall i: int :: InRange(i, System.Int16) <==> System.Int16.MinValue <= i && i <= System.Int16.MaxValue); + +axiom (forall i: int :: InRange(i, System.Int32) <==> System.Int32.MinValue <= i && i <= System.Int32.MaxValue); + +axiom (forall i: int :: InRange(i, System.Int64) <==> System.Int64.MinValue <= i && i <= System.Int64.MaxValue); + +axiom (forall i: int :: { InRange(i, System.Byte) } InRange(i, System.Byte) <==> 0 <= i && i < 256); + +function $RealToInt(real) returns (int); + +function $IntToReal(int) returns (real); + +function $SizeIs(name, int) returns (bool); + +function $IfThenElse(bool, any, any) returns (any); + +axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } b ==> $IfThenElse(b, x, y) == x); + +axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } !b ==> $IfThenElse(b, x, y) == y); + +function #neg(int) returns (int); + +function #rneg(real) returns (real); + +function #rdiv(real, real) returns (real); + +function #and(int, int) returns (int); + +function #or(int, int) returns (int); + +function #xor(int, int) returns (int); + +function #shl(int, int) returns (int); + +function #shr(int, int) returns (int); + +axiom (forall x: int, y: int :: { x mod y } { x div y } x mod y == x - x div y * y); + +axiom (forall x: int, y: int :: { x mod y } 0 <= x && 0 < y ==> 0 <= x mod y && x mod y < y); + +axiom (forall x: int, y: int :: { x mod y } 0 <= x && y < 0 ==> 0 <= x mod y && x mod y < 0 - y); + +axiom (forall x: int, y: int :: { x mod y } x <= 0 && 0 < y ==> 0 - y < x mod y && x mod y <= 0); + +axiom (forall x: int, y: int :: { x mod y } x <= 0 && y < 0 ==> y < x mod y && x mod y <= 0); + +axiom (forall x: int, y: int :: { (x + y) mod y } 0 <= x && 0 <= y ==> (x + y) mod y == x mod y); + +axiom (forall x: int, y: int :: { (y + x) mod y } 0 <= x && 0 <= y ==> (y + x) mod y == x mod y); + +axiom (forall x: int, y: int :: { (x - y) mod y } 0 <= x - y && 0 <= y ==> (x - y) mod y == x mod y); + +axiom (forall a: int, b: int, d: int :: { a mod d,b mod d } 2 <= d && a mod d == b mod d && a < b ==> a + d <= b); + +axiom (forall i: int :: { #shl(i, 0) } #shl(i, 0) == i); + +axiom (forall i: int, j: int :: 0 <= j ==> #shl(i, j + 1) == #shl(i, j) * 2); + +axiom (forall i: int :: { #shr(i, 0) } #shr(i, 0) == i); + +axiom (forall i: int, j: int :: 0 <= j ==> #shr(i, j + 1) == #shr(i, j) div 2); + +const unique $UnknownRef: ref; + +const unique System.IComparable: name; + +const unique Microsoft.Singularity.Applications.ThreadTest: name; + +const unique System.Threading.Thread: name; + +const unique System.Collections.IEnumerable: name; + +const unique System.Threading.ThreadStart: name; + +const unique System.ICloneable: name; + +const unique System.MulticastDelegate: name; + +const unique System.Delegate: name; + +const unique $stringLiteral0: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral0, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral0, $allocated]):bool) && $IsNotNull($stringLiteral0, System.String) && $Length($stringLiteral0) == 13; + +const unique $stringLiteral1: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral1, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral1, $allocated]):bool) && $IsNotNull($stringLiteral1, System.String) && $Length($stringLiteral1) == 14; + +const unique $stringLiteral2: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral2, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral2, $allocated]):bool) && $IsNotNull($stringLiteral2, System.String) && $Length($stringLiteral2) == 11; + +const unique $stringLiteral3: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral3, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral3, $allocated]):bool) && $IsNotNull($stringLiteral3, System.String) && $Length($stringLiteral3) == 18; + +const unique $stringLiteral4: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral4, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral4, $allocated]):bool) && $IsNotNull($stringLiteral4, System.String) && $Length($stringLiteral4) == 19; + +const unique $stringLiteral5: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral5, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral5, $allocated]):bool) && $IsNotNull($stringLiteral5, System.String) && $Length($stringLiteral5) == 14; + +const unique $stringLiteral6: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral6, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral6, $allocated]):bool) && $IsNotNull($stringLiteral6, System.String) && $Length($stringLiteral6) == 15; + +const unique $stringLiteral7: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral7, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral7, $allocated]):bool) && $IsNotNull($stringLiteral7, System.String) && $Length($stringLiteral7) == 11; + +const unique $stringLiteral8: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral8, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral8, $allocated]):bool) && $IsNotNull($stringLiteral8, System.String) && $Length($stringLiteral8) == 19; + +const unique $stringLiteral9: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral9, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral9, $allocated]):bool) && $IsNotNull($stringLiteral9, System.String) && $Length($stringLiteral9) == 20; + +const unique $stringLiteral10: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral10, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral10, $allocated]):bool) && $IsNotNull($stringLiteral10, System.String) && $Length($stringLiteral10) == 22; + +const unique $stringLiteral11: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral11, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral11, $allocated]):bool) && $IsNotNull($stringLiteral11, System.String) && $Length($stringLiteral11) == 21; + +const unique $stringLiteral12: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral12, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral12, $allocated]):bool) && $IsNotNull($stringLiteral12, System.String) && $Length($stringLiteral12) == 23; + +const unique $stringLiteral13: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral13, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral13, $allocated]):bool) && $IsNotNull($stringLiteral13, System.String) && $Length($stringLiteral13) == 22; + +axiom $IsClass(Microsoft.Singularity.Applications.ThreadTest); + +axiom Microsoft.Singularity.Applications.ThreadTest <: System.Object && AsDirectSubClass(Microsoft.Singularity.Applications.ThreadTest, System.Object) == Microsoft.Singularity.Applications.ThreadTest; + +axiom (forall $K: name :: { Microsoft.Singularity.Applications.ThreadTest <: $K } Microsoft.Singularity.Applications.ThreadTest <: $K <==> Microsoft.Singularity.Applications.ThreadTest == $K || System.Object <: $K); + +function Inv_Microsoft.Singularity.Applications.ThreadTest(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) } Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest } { Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest ==> Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap)); + +procedure Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod(); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +implementation Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod() +{ + var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block1513$LoopPreheader: [ref,name]any; + + entry: + assume IsHeap($Heap); + goto block1479; + + block1479: + goto block1496; + + block1496: + // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) + stack0o := $stringLiteral0; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) + stack0o := $stringLiteral1; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,18) + i := 0; + goto block1513$LoopPreheader; + + block1513: + // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + assert (forall $o: ref :: $Heap$block1513$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool != true); + assert (forall $o: ref :: cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + stack0i := 10; + // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + stack0b := i >= stack0i; + // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + goto true1513to1547, false1513to1530; + + true1513to1547: + assume stack0b == true; + goto block1547; + + false1513to1530: + assume stack0b == false; + goto block1530; + + block1547: + // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) + stack0o := $stringLiteral3; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) + stack0o := $stringLiteral4; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(31,10) + return; + + block1530: + // ----- load constant [0] ... ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) + stack0o := $stringLiteral2; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) + // Commented out, to avoid problems with the theorem prover nondeterministically choosing this error over the one 12 lines above: call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(26,17) + call System.Threading.Thread.Yield(); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,37) + local1 := i; + // ----- load constant 1 + stack0i := 1; + // ----- binary operator + stack0i := local1 + stack0i; + // ----- copy + i := stack0i; + // ----- copy + stack0i := local1; + // ----- branch + goto block1513; + + block1513$LoopPreheader: + $Heap$block1513$LoopPreheader := $Heap; + goto block1513; + +} + + + +axiom $IsClass(System.String); + +axiom System.String <: System.Object && AsDirectSubClass(System.String, System.Object) == System.String; + +axiom $IsInterface(System.IComparable); + +axiom (forall $K: name :: { System.IComparable <: $K } System.IComparable <: $K <==> System.IComparable == $K || System.Object == $K); + +axiom Implements(System.String, System.IComparable); + +axiom $IsInterface(System.ICloneable); + +axiom (forall $K: name :: { System.ICloneable <: $K } System.ICloneable <: $K <==> System.ICloneable == $K || System.Object == $K); + +axiom Implements(System.String, System.ICloneable); + +axiom $IsInterface(System.Collections.IEnumerable); + +axiom (forall $K: name :: { System.Collections.IEnumerable <: $K } System.Collections.IEnumerable <: $K <==> System.Collections.IEnumerable == $K || System.Object == $K); + +axiom Implements(System.String, System.Collections.IEnumerable); + +axiom (forall $K: name :: { System.String <: $K } System.String <: $K <==> System.String == $K || System.Object <: $K || System.IComparable <: $K || System.ICloneable <: $K || System.Collections.IEnumerable <: $K); + +axiom (forall $U: name :: { $U <: System.String } $U <: System.String ==> $U == System.String); + +function Inv_System.String(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.String(this, heap) } Inv_System.String(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.String } { Inv_System.String($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.String ==> Inv_System.String($o, heap)); + +procedure System.Console.WriteLine$System.String(value$in: ref); + requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure Microsoft.Singularity.DebugStub.Print$System.String(value$in: ref); + requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure System.Threading.Thread.Yield(); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod(); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +implementation Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod() +{ + var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block2516$LoopPreheader: [ref,name]any; + + entry: + assume IsHeap($Heap); + goto block2482; + + block2482: + goto block2499; + + block2499: + // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) + stack0o := $stringLiteral5; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) + stack0o := $stringLiteral6; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,18) + i := 0; + goto block2516$LoopPreheader; + + block2516: + // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + assert (forall $o: ref :: $Heap$block2516$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool != true); + assert (forall $o: ref :: cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + stack0i := 10; + // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + stack0b := i >= stack0i; + // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + goto true2516to2550, false2516to2533; + + true2516to2550: + assume stack0b == true; + goto block2550; + + false2516to2533: + assume stack0b == false; + goto block2533; + + block2550: + // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) + stack0o := $stringLiteral8; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) + stack0o := $stringLiteral9; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(46,10) + return; + + block2533: + // ----- load constant ... [1] ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) + stack0o := $stringLiteral7; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) + // Commented out, to avoid problems with the theorem prover nondeterministically choosing this error over the one 12 lines above: call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(41,17) + call System.Threading.Thread.Yield(); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,37) + local1 := i; + // ----- load constant 1 + stack0i := 1; + // ----- binary operator + stack0i := local1 + stack0i; + // ----- copy + i := stack0i; + // ----- copy + stack0i := local1; + // ----- branch + goto block2516; + + block2516$LoopPreheader: + $Heap$block2516$LoopPreheader := $Heap; + goto block2516; + +} + + + +procedure Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int); + requires args$in == null || (cast($Heap[args$in, $writable]):bool == true && cast($Heap[args$in, $inv]):name == $typeof(args$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures IsAllocated($Heap, $result); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +implementation Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int) +{ + var args: ref, stack0o: ref, stack1o: ref, stack50000o: ref, t1: ref, t2: ref, i: int, stack0i: int, stack0b: bool, local3: int, return.value: int, SS$Display.Return.Local: int, $Heap$block3825$LoopPreheader: [ref,name]any; + + entry: + assume IsHeap($Heap); + args := args$in; + assume $Is(args, RefArray(System.String, 1)); + assume cast($Heap[args$in, $allocated]):bool == true; + goto block3791; + + block3791: + goto block3808; + + block3808: + stack0o := null; + // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + havoc stack1o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + assert stack50000o != null; + call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + stack0o := stack50000o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + assert stack50000o != null; + call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + stack0o := stack50000o; + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + t1 := stack0o; + stack0o := null; + // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + havoc stack1o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + assert stack50000o != null; + call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + stack0o := stack50000o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + assert stack50000o != null; + call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + stack0o := stack50000o; + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + t2 := stack0o; + // ----- load constant Starting first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) + stack0o := $stringLiteral10; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(55,13) + assert t1 != null; + call System.Threading.Thread.Start(t1); + // ----- load constant Started first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) + stack0o := $stringLiteral11; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant Starting second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) + stack0o := $stringLiteral12; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(59,13) + assert t2 != null; + call System.Threading.Thread.Start(t2); + // ----- load constant Started second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) + stack0o := $stringLiteral13; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,18) + i := 0; + goto block3825$LoopPreheader; + + block3825: + // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + assert (forall $o: ref :: $Heap$block3825$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool != true); + assert (forall $o: ref :: cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + // ----- load constant 30 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + stack0i := 30; + // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + stack0b := i >= stack0i; + // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + goto true3825to3859, false3825to3842; + + true3825to3859: + assume stack0b == true; + goto block3859; + + false3825to3842: + assume stack0b == false; + goto block3842; + + block3859: + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(66,13) + return.value := 0; + // ----- branch + goto block3876; + + block3842: + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(64,17) + call System.Threading.Thread.Yield(); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,37) + local3 := i; + // ----- load constant 1 + stack0i := 1; + // ----- binary operator + stack0i := local3 + stack0i; + // ----- copy + i := stack0i; + // ----- copy + stack0i := local3; + // ----- branch + goto block3825; + + block3876: + // ----- copy + SS$Display.Return.Local := return.value; + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) + stack0i := return.value; + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) + $result := stack0i; + return; + + block3825$LoopPreheader: + $Heap$block3825$LoopPreheader := $Heap; + goto block3825; + +} + + + +axiom $IsClass(System.Threading.ThreadStart); + +axiom $IsClass(System.MulticastDelegate); + +axiom $IsClass(System.Delegate); + +axiom System.Delegate <: System.Object && AsDirectSubClass(System.Delegate, System.Object) == System.Delegate; + +axiom Implements(System.Delegate, System.ICloneable); + +axiom (forall $K: name :: { System.Delegate <: $K } System.Delegate <: $K <==> System.Delegate == $K || System.Object <: $K || System.ICloneable <: $K); + +function Inv_System.Delegate(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Delegate(this, heap) } Inv_System.Delegate(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Delegate } { Inv_System.Delegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Delegate ==> Inv_System.Delegate($o, heap)); + +axiom System.MulticastDelegate <: System.Delegate && AsDirectSubClass(System.MulticastDelegate, System.Delegate) == System.MulticastDelegate; + +axiom (forall $K: name :: { System.MulticastDelegate <: $K } System.MulticastDelegate <: $K <==> System.MulticastDelegate == $K || System.Delegate <: $K); + +function Inv_System.MulticastDelegate(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.MulticastDelegate(this, heap) } Inv_System.MulticastDelegate(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.MulticastDelegate } { Inv_System.MulticastDelegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.MulticastDelegate ==> Inv_System.MulticastDelegate($o, heap)); + +axiom System.Threading.ThreadStart <: System.MulticastDelegate && AsDirectSubClass(System.Threading.ThreadStart, System.MulticastDelegate) == System.Threading.ThreadStart; + +axiom (forall $K: name :: { System.Threading.ThreadStart <: $K } System.Threading.ThreadStart <: $K <==> System.Threading.ThreadStart == $K || System.MulticastDelegate <: $K); + +axiom (forall $U: name :: { $U <: System.Threading.ThreadStart } $U <: System.Threading.ThreadStart ==> $U == System.Threading.ThreadStart); + +function Inv_System.Threading.ThreadStart(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.ThreadStart(this, heap) } Inv_System.Threading.ThreadStart(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.ThreadStart } { Inv_System.Threading.ThreadStart($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.ThreadStart ==> Inv_System.Threading.ThreadStart($o, heap)); + +procedure System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(this: ref, object$in: ref, method$in: ref); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.ThreadStart; + + + +axiom $IsClass(System.Threading.Thread); + +axiom System.Threading.Thread <: System.Object && AsDirectSubClass(System.Threading.Thread, System.Object) == System.Threading.Thread; + +axiom (forall $K: name :: { System.Threading.Thread <: $K } System.Threading.Thread <: $K <==> System.Threading.Thread == $K || System.Object <: $K); + +axiom (forall $U: name :: { $U <: System.Threading.Thread } $U <: System.Threading.Thread ==> $U == System.Threading.Thread); + +function Inv_System.Threading.Thread(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.Thread(this, heap) } Inv_System.Threading.Thread(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.Thread } { Inv_System.Threading.Thread($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.Thread ==> Inv_System.Threading.Thread($o, heap)); + +procedure System.Threading.Thread..ctor$System.Threading.ThreadStart(this: ref, start$in: ref); + requires start$in == null || (cast($Heap[start$in, $writable]):bool == true && cast($Heap[start$in, $inv]):name == $typeof(start$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Threading.Thread <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.Thread; + ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; + + + +procedure System.Threading.Thread.Start(this: ref); + requires cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == $typeof(this); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(Microsoft.Singularity.Applications.ThreadTest <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == Microsoft.Singularity.Applications.ThreadTest; + ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; + + + +implementation Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref) +{ + + entry: + assume IsHeap($Heap); + assume $IsNotNull(this, Microsoft.Singularity.Applications.ThreadTest); + assume cast($Heap[this, $allocated]):bool == true; + assume cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; + goto block4777; + + block4777: + goto block4794; + + block4794: + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,18) + assert this != null; + call System.Object..ctor(this); + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,28) + assert this != null; + assert cast($Heap[this, $writable]):bool == true && System.Object <: cast($Heap[this, $inv]):name; + assert cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; + assert Inv_Microsoft.Singularity.Applications.ThreadTest(this, $Heap); + $Heap[this, $inv] := Microsoft.Singularity.Applications.ThreadTest; + return; + +} + + + +procedure System.Object..ctor(this: ref); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Object <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; + ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; + + + +type ref, name, any; +const null : ref; diff --git a/Test/test2/strings-where.bpl b/Test/test2/strings-where.bpl index b2ad7217..c9b6772f 100644 --- a/Test/test2/strings-where.bpl +++ b/Test/test2/strings-where.bpl @@ -1,997 +1,997 @@ -// RUN: %boogie -noinfer "%s" > "%t" -// RUN: %diff "%s.expect" "%t" - - -type elements; - -type struct; - -var $Heap: [ref,name]any where IsHeap($Heap); -function cast(S) returns (T); -function IsHeap(h: [ref,name]any) returns (bool); - -const unique $allocated: name; - -const unique $elements: name; - -const unique $inv: name; - -const unique $writable: name; - -const unique $sharingMode: name; - -const unique $SharingMode_Unshared: name; - -const unique $SharingMode_LockProtected: name; - -function ClassRepr(class: name) returns (ref); - -axiom (forall c0: name, c1: name :: c0 != c1 ==> ClassRepr(c0) != ClassRepr(c1)); - -axiom (forall T: name :: !($typeof(ClassRepr(T)) <: System.Object)); - -axiom (forall T: name :: ClassRepr(T) != null); - -axiom (forall T: name, h: [ref,name]any :: { h[ClassRepr(T), $writable] } IsHeap(h) ==> cast(h[ClassRepr(T), $writable]):bool); - -function IsDirectlyModifiableField(f: name) returns (bool); - -axiom !IsDirectlyModifiableField($allocated); - -axiom IsDirectlyModifiableField($elements); - -axiom !IsDirectlyModifiableField($inv); - -axiom !IsDirectlyModifiableField($writable); - -function IsStaticField(f: name) returns (bool); - -axiom !IsStaticField($allocated); - -axiom !IsStaticField($elements); - -axiom !IsStaticField($inv); - -axiom !IsStaticField($writable); - -function ValueArrayGet(elements, int) returns (any); - -function ValueArraySet(elements, int, any) returns (elements); - -function RefArrayGet(elements, int) returns (ref); - -function RefArraySet(elements, int, ref) returns (elements); - -axiom (forall A: elements, i: int, x: any :: ValueArrayGet(ValueArraySet(A, i, x), i) == x); - -axiom (forall A: elements, i: int, j: int, x: any :: i != j ==> ValueArrayGet(ValueArraySet(A, i, x), j) == ValueArrayGet(A, j)); - -axiom (forall A: elements, i: int, x: ref :: RefArrayGet(RefArraySet(A, i, x), i) == x); - -axiom (forall A: elements, i: int, j: int, x: ref :: i != j ==> RefArrayGet(RefArraySet(A, i, x), j) == RefArrayGet(A, j)); - -function ArrayIndex(arr: ref, dim: int, indexAtDim: int, remainingIndexContribution: int) returns (int); - -axiom (forall a: ref, d: int, x: int, y: int, x': int, y': int :: ArrayIndex(a, d, x, y) == ArrayIndex(a, d, x', y') ==> x == x' && y == y'); - -axiom (forall a: ref, T: name, i: int, r: int, heap: [ref,name]any :: $typeof(a) <: RefArray(T, r) ==> $Is(RefArrayGet(cast(heap[a, $elements]):elements, i), T)); - -function $Rank(ref) returns (int); - -axiom (forall a: ref :: 1 <= $Rank(a)); - -axiom (forall a: ref, T: name, r: int :: { $Is(a, ValueArray(T, r)) } $Is(a, ValueArray(T, r)) ==> $Rank(a) == r); - -axiom (forall a: ref, T: name, r: int :: { $Is(a, RefArray(T, r)) } $Is(a, RefArray(T, r)) ==> $Rank(a) == r); - -function $Length(ref) returns (int); - -axiom (forall a: ref :: { $Length(a) } 0 <= $Length(a)); - -function $DimLength(ref, int) returns (int); - -axiom (forall a: ref, i: int :: 0 <= $DimLength(a, i)); - -axiom (forall a: ref :: $Rank(a) == 1 ==> $DimLength(a, 0) == $Length(a)); - -function $LBound(ref, int) returns (int); - -function $UBound(ref, int) returns (int); - -axiom (forall a: ref, i: int :: { $LBound(a, i) } $LBound(a, i) == 0); - -axiom (forall a: ref, i: int :: { $UBound(a, i) } $UBound(a, i) == $DimLength(a, i) - 1); - -const unique System.Array: name; - -axiom $IsClass(System.Array); - -axiom System.Array <: System.Object; - -function $ElementType(name) returns (name); - -function ValueArray(elementType: name, rank: int) returns (name); - -axiom (forall T: name, r: int :: { ValueArray(T, r) } ValueArray(T, r) <: System.Array); - -function RefArray(elementType: name, rank: int) returns (name); - -axiom (forall T: name, r: int :: { RefArray(T, r) } RefArray(T, r) <: System.Array); - -axiom (forall T: name, U: name, r: int :: U <: T ==> RefArray(U, r) <: RefArray(T, r)); - -axiom (forall A: name, r: int :: $ElementType(ValueArray(A, r)) == A); - -axiom (forall A: name, r: int :: $ElementType(RefArray(A, r)) == A); - -axiom (forall A: name, r: int, T: name :: { T <: RefArray(A, r) } T <: RefArray(A, r) ==> T == RefArray($ElementType(T), r) && $ElementType(T) <: A); - -axiom (forall A: name, r: int, T: name :: { T <: ValueArray(A, r) } T <: ValueArray(A, r) ==> T == ValueArray(A, r)); - -axiom (forall A: name, r: int, T: name :: RefArray(A, r) <: T ==> System.Array <: T || (T == RefArray($ElementType(T), r) && A <: $ElementType(T))); - -axiom (forall A: name, r: int, T: name :: ValueArray(A, r) <: T ==> System.Array <: T || T == ValueArray(A, r)); - -function $ArrayPtr(elementType: name) returns (name); - -function $StructGet(struct, name) returns (any); - -function $StructSet(struct, name, any) returns (struct); - -axiom (forall s: struct, f: name, x: any :: $StructGet($StructSet(s, f, x), f) == x); - -axiom (forall s: struct, f: name, f': name, x: any :: f != f' ==> $StructGet($StructSet(s, f, x), f') == $StructGet(s, f')); - -function ZeroInit(s: struct, typ: name) returns (bool); - -function $typeof(ref) returns (name); - -function Implements(class: name, interface: name) returns (bool); - -axiom (forall T: name, J: name :: { Implements(T, J) } Implements(T, J) ==> T <: J); - -function InterfaceExtends(subIntf: name, superIntf: name) returns (bool); - -axiom (forall J: name, K: name :: { InterfaceExtends(J, K) } InterfaceExtends(J, K) ==> J <: K); - -function $IsClass(name) returns (bool); - -axiom (forall C: name :: { $IsClass(C) } $IsClass(C) ==> C <: C); - -function AsDirectSubClass(sub: name, base: name) returns (sub': name); - -function OneClassDown(sub: name, base: name) returns (directSub: name); - -axiom (forall A: name, B: name, C: name :: { C <: AsDirectSubClass(B, A) } C <: AsDirectSubClass(B, A) ==> OneClassDown(C, A) == B); - -function $IsInterface(name) returns (bool); - -axiom (forall J: name :: { $IsInterface(J) } $IsInterface(J) ==> J <: System.Object); - -function $IsValueType(name) returns (bool); - -axiom (forall T: name :: $IsValueType(T) ==> (forall U: name :: T <: U ==> T == U) && (forall U: name :: U <: T ==> T == U)); - -const unique System.Object: name; - -axiom $IsClass(System.Object); - -function $IsTokenForType(struct, name) returns (bool); - -function TypeObject(name) returns (ref); - -const unique System.Type: name; - -axiom System.Type <: System.Object; - -axiom (forall T: name :: { TypeObject(T) } $IsNotNull(TypeObject(T), System.Type)); - -function $Is(ref, name) returns (bool); - -axiom (forall o: ref, T: name :: { $Is(o, T) } $Is(o, T) <==> o == null || $typeof(o) <: T); - -function $IsNotNull(ref, name) returns (bool); - -axiom (forall o: ref, T: name :: { $IsNotNull(o, T) } $IsNotNull(o, T) <==> o != null && $Is(o, T)); - -function $As(ref, name) returns (ref); - -axiom (forall o: ref, T: name :: $Is(o, T) ==> $As(o, T) == o); - -axiom (forall o: ref, T: name :: !$Is(o, T) ==> $As(o, T) == null); - -axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, RefArray(A, r)) ==> heap[o, $inv] == $typeof(o)); - -axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, ValueArray(A, r)) ==> heap[o, $inv] == $typeof(o)); - -function IsAllocated(h: [ref,name]any, o: any) returns (bool); - -axiom (forall h: [ref,name]any, o: ref, f: name :: { IsAllocated(h, h[o, f]) } IsHeap(h) ==> IsAllocated(h, h[o, f])); - -axiom (forall h: [ref,name]any, s: struct, f: name :: { IsAllocated(h, $StructGet(s, f)) } IsAllocated(h, s) ==> IsAllocated(h, $StructGet(s, f))); - -axiom (forall h: [ref,name]any, e: elements, i: int :: { IsAllocated(h, RefArrayGet(e, i)) } IsAllocated(h, e) ==> IsAllocated(h, RefArrayGet(e, i))); - -axiom (forall h: [ref,name]any, o: ref :: { h[o, $allocated] } IsAllocated(h, o) ==> cast(h[o, $allocated]):bool); - -axiom (forall h: [ref,name]any, c: name :: { h[ClassRepr(c), $allocated] } IsHeap(h) ==> cast(h[ClassRepr(c), $allocated]):bool); - -function DeclType(field: name) returns (class: name); - -function AsNonNullRefField(field: name, T: name) returns (f: name); - -function AsRefField(field: name, T: name) returns (f: name); - -function AsRangeField(field: name, T: name) returns (f: name); - -axiom (forall f: name, T: name :: { AsNonNullRefField(f, T) } AsNonNullRefField(f, T) == f ==> AsRefField(f, T) == f); - -axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRefField(f, T)] } IsHeap(h) ==> $Is(cast(h[o, AsRefField(f, T)]):ref, T)); - -axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsNonNullRefField(f, T)] } IsHeap(h) ==> cast(h[o, AsNonNullRefField(f, T)]):ref != null); - -axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRangeField(f, T)] } IsHeap(h) ==> InRange(cast(h[o, AsRangeField(f, T)]):int, T)); - -const unique System.String: name; - -axiom (forall h: [ref,name]any, s: ref :: IsHeap(h) && $typeof(s) == System.String ==> h[s, $inv] == $typeof(s) && cast(h[s, $writable]):bool); - -function AsOwnedField(f: name) returns (name); - -axiom (forall h: [ref,name]any, o: ref, f: name :: { h[o, AsOwnedField(f)] } IsHeap(h) && cast(h[o, $inv]):name <: DeclType(AsOwnedField(f)) ==> cast(h[o, AsOwnedField(f)]):ref == null || $typeof(cast(h[o, AsOwnedField(f)]):ref) == System.String || !cast(h[cast(h[o, AsOwnedField(f)]):ref, $writable]):bool); - -axiom (forall h: [ref,name]any, o: ref :: { h[o, $writable] } IsHeap(h) && !cast(h[o, $writable]):bool ==> cast(h[o, $inv]):name == $typeof(o)); - -function Box(any, ref) returns (ref); - -function Unbox(ref) returns (any); - -axiom (forall x: any, p: ref :: { Unbox(Box(x, p)) } Unbox(Box(x, p)) == x); - -axiom (forall heap: [ref,name]any, x: any, p: ref :: { heap[Box(x, p), $inv] } IsHeap(heap) ==> heap[Box(x, p), $inv] == $typeof(Box(x, p))); - -function UnboxedType(ref) returns (name); - -function BoxTester(p: ref, typ: name) returns (ref); - -axiom (forall p: ref, typ: name :: { BoxTester(p, typ) } UnboxedType(p) == typ <==> BoxTester(p, typ) != null); - -const unique System.Int16: name; - -axiom $IsValueType(System.Int16); - -const unique System.Int32: name; - -axiom $IsValueType(System.Int32); - -const unique System.Int64: name; - -axiom $IsValueType(System.Int64); - -const unique System.Byte: name; - -axiom $IsValueType(System.Byte); - -const unique System.Int16.MinValue: int; - -const unique System.Int16.MaxValue: int; - -const unique System.Int32.MinValue: int; - -const unique System.Int32.MaxValue: int; - -const unique System.Int64.MinValue: int; - -const unique System.Int64.MaxValue: int; - -axiom System.Int64.MinValue < System.Int32.MinValue; - -axiom System.Int32.MinValue < System.Int16.MinValue; - -axiom System.Int16.MinValue < System.Int16.MaxValue; - -axiom System.Int16.MaxValue < System.Int32.MaxValue; - -axiom System.Int32.MaxValue < System.Int64.MaxValue; - -function InRange(i: int, T: name) returns (bool); - -axiom (forall i: int :: InRange(i, System.Int16) <==> System.Int16.MinValue <= i && i <= System.Int16.MaxValue); - -axiom (forall i: int :: InRange(i, System.Int32) <==> System.Int32.MinValue <= i && i <= System.Int32.MaxValue); - -axiom (forall i: int :: InRange(i, System.Int64) <==> System.Int64.MinValue <= i && i <= System.Int64.MaxValue); - -axiom (forall i: int :: { InRange(i, System.Byte) } InRange(i, System.Byte) <==> 0 <= i && i < 256); - -function $RealToInt(real) returns (int); - -function $IntToReal(int) returns (real); - -function $SizeIs(name, int) returns (bool); - -function $IfThenElse(bool, any, any) returns (any); - -axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } b ==> $IfThenElse(b, x, y) == x); - -axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } !b ==> $IfThenElse(b, x, y) == y); - -function #neg(int) returns (int); - -function #rneg(real) returns (real); - -function #rdiv(real, real) returns (real); - -function #and(int, int) returns (int); - -function #or(int, int) returns (int); - -function #xor(int, int) returns (int); - -function #shl(int, int) returns (int); - -function #shr(int, int) returns (int); - -axiom (forall x: int, y: int :: { x mod y } { x div y } x mod y == x - x div y * y); - -axiom (forall x: int, y: int :: { x mod y } 0 <= x && 0 < y ==> 0 <= x mod y && x mod y < y); - -axiom (forall x: int, y: int :: { x mod y } 0 <= x && y < 0 ==> 0 <= x mod y && x mod y < 0 - y); - -axiom (forall x: int, y: int :: { x mod y } x <= 0 && 0 < y ==> 0 - y < x mod y && x mod y <= 0); - -axiom (forall x: int, y: int :: { x mod y } x <= 0 && y < 0 ==> y < x mod y && x mod y <= 0); - -axiom (forall x: int, y: int :: { (x + y) mod y } 0 <= x && 0 <= y ==> (x + y) mod y == x mod y); - -axiom (forall x: int, y: int :: { (y + x) mod y } 0 <= x && 0 <= y ==> (y + x) mod y == x mod y); - -axiom (forall x: int, y: int :: { (x - y) mod y } 0 <= x - y && 0 <= y ==> (x - y) mod y == x mod y); - -axiom (forall a: int, b: int, d: int :: { a mod d,b mod d } 2 <= d && a mod d == b mod d && a < b ==> a + d <= b); - -axiom (forall i: int :: { #shl(i, 0) } #shl(i, 0) == i); - -axiom (forall i: int, j: int :: 0 <= j ==> #shl(i, j + 1) == #shl(i, j) * 2); - -axiom (forall i: int :: { #shr(i, 0) } #shr(i, 0) == i); - -axiom (forall i: int, j: int :: 0 <= j ==> #shr(i, j + 1) == #shr(i, j) div 2); - -const unique $UnknownRef: ref; - -const unique System.IComparable: name; - -const unique Microsoft.Singularity.Applications.ThreadTest: name; - -const unique System.Threading.Thread: name; - -const unique System.Collections.IEnumerable: name; - -const unique System.Threading.ThreadStart: name; - -const unique System.ICloneable: name; - -const unique System.MulticastDelegate: name; - -const unique System.Delegate: name; - -const unique $stringLiteral0: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral0, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral0, $allocated]):bool) && $IsNotNull($stringLiteral0, System.String) && $Length($stringLiteral0) == 13; - -const unique $stringLiteral1: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral1, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral1, $allocated]):bool) && $IsNotNull($stringLiteral1, System.String) && $Length($stringLiteral1) == 14; - -const unique $stringLiteral2: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral2, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral2, $allocated]):bool) && $IsNotNull($stringLiteral2, System.String) && $Length($stringLiteral2) == 11; - -const unique $stringLiteral3: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral3, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral3, $allocated]):bool) && $IsNotNull($stringLiteral3, System.String) && $Length($stringLiteral3) == 18; - -const unique $stringLiteral4: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral4, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral4, $allocated]):bool) && $IsNotNull($stringLiteral4, System.String) && $Length($stringLiteral4) == 19; - -const unique $stringLiteral5: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral5, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral5, $allocated]):bool) && $IsNotNull($stringLiteral5, System.String) && $Length($stringLiteral5) == 14; - -const unique $stringLiteral6: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral6, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral6, $allocated]):bool) && $IsNotNull($stringLiteral6, System.String) && $Length($stringLiteral6) == 15; - -const unique $stringLiteral7: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral7, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral7, $allocated]):bool) && $IsNotNull($stringLiteral7, System.String) && $Length($stringLiteral7) == 11; - -const unique $stringLiteral8: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral8, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral8, $allocated]):bool) && $IsNotNull($stringLiteral8, System.String) && $Length($stringLiteral8) == 19; - -const unique $stringLiteral9: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral9, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral9, $allocated]):bool) && $IsNotNull($stringLiteral9, System.String) && $Length($stringLiteral9) == 20; - -const unique $stringLiteral10: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral10, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral10, $allocated]):bool) && $IsNotNull($stringLiteral10, System.String) && $Length($stringLiteral10) == 22; - -const unique $stringLiteral11: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral11, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral11, $allocated]):bool) && $IsNotNull($stringLiteral11, System.String) && $Length($stringLiteral11) == 21; - -const unique $stringLiteral12: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral12, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral12, $allocated]):bool) && $IsNotNull($stringLiteral12, System.String) && $Length($stringLiteral12) == 23; - -const unique $stringLiteral13: ref; - -axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral13, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral13, $allocated]):bool) && $IsNotNull($stringLiteral13, System.String) && $Length($stringLiteral13) == 22; - -axiom $IsClass(Microsoft.Singularity.Applications.ThreadTest); - -axiom Microsoft.Singularity.Applications.ThreadTest <: System.Object && AsDirectSubClass(Microsoft.Singularity.Applications.ThreadTest, System.Object) == Microsoft.Singularity.Applications.ThreadTest; - -axiom (forall $K: name :: { Microsoft.Singularity.Applications.ThreadTest <: $K } Microsoft.Singularity.Applications.ThreadTest <: $K <==> Microsoft.Singularity.Applications.ThreadTest == $K || System.Object <: $K); - -function Inv_Microsoft.Singularity.Applications.ThreadTest(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) } Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest } { Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest ==> Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap)); - -procedure Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod(); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -implementation Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod() -{ - var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block1513$LoopPreheader: [ref,name]any; - - entry: - assume IsHeap($Heap); - goto block1479; - - block1479: - goto block1496; - - block1496: - // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) - stack0o := $stringLiteral0; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) - stack0o := $stringLiteral1; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,18) - i := 0; - goto block1513$LoopPreheader; - - block1513: - // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - assert (forall $o: ref :: $Heap$block1513$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool != true); - assert (forall $o: ref :: cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - stack0i := 10; - // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - stack0b := i >= stack0i; - // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) - goto true1513to1547, false1513to1530; - - true1513to1547: - assume stack0b == true; - goto block1547; - - false1513to1530: - assume stack0b == false; - goto block1530; - - block1547: - // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) - stack0o := $stringLiteral3; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) - stack0o := $stringLiteral4; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(31,10) - return; - - block1530: - // ----- load constant [0] ... ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) - stack0o := $stringLiteral2; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) - call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(26,17) - call System.Threading.Thread.Yield(); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,37) - local1 := i; - // ----- load constant 1 - stack0i := 1; - // ----- binary operator - stack0i := local1 + stack0i; - // ----- copy - i := stack0i; - // ----- copy - stack0i := local1; - // ----- branch - goto block1513; - - block1513$LoopPreheader: - $Heap$block1513$LoopPreheader := $Heap; - goto block1513; - -} - - - -axiom $IsClass(System.String); - -axiom System.String <: System.Object && AsDirectSubClass(System.String, System.Object) == System.String; - -axiom $IsInterface(System.IComparable); - -axiom (forall $K: name :: { System.IComparable <: $K } System.IComparable <: $K <==> System.IComparable == $K || System.Object == $K); - -axiom Implements(System.String, System.IComparable); - -axiom $IsInterface(System.ICloneable); - -axiom (forall $K: name :: { System.ICloneable <: $K } System.ICloneable <: $K <==> System.ICloneable == $K || System.Object == $K); - -axiom Implements(System.String, System.ICloneable); - -axiom $IsInterface(System.Collections.IEnumerable); - -axiom (forall $K: name :: { System.Collections.IEnumerable <: $K } System.Collections.IEnumerable <: $K <==> System.Collections.IEnumerable == $K || System.Object == $K); - -axiom Implements(System.String, System.Collections.IEnumerable); - -axiom (forall $K: name :: { System.String <: $K } System.String <: $K <==> System.String == $K || System.Object <: $K || System.IComparable <: $K || System.ICloneable <: $K || System.Collections.IEnumerable <: $K); - -axiom (forall $U: name :: { $U <: System.String } $U <: System.String ==> $U == System.String); - -function Inv_System.String(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.String(this, heap) } Inv_System.String(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.String } { Inv_System.String($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.String ==> Inv_System.String($o, heap)); - -procedure System.Console.WriteLine$System.String(value$in: ref); - requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure Microsoft.Singularity.DebugStub.Print$System.String(value$in: ref); - requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure System.Threading.Thread.Yield(); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod(); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -implementation Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod() -{ - var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block2516$LoopPreheader: [ref,name]any; - - entry: - assume IsHeap($Heap); - goto block2482; - - block2482: - goto block2499; - - block2499: - // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) - stack0o := $stringLiteral5; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) - stack0o := $stringLiteral6; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,18) - i := 0; - goto block2516$LoopPreheader; - - block2516: - // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - assert (forall $o: ref :: $Heap$block2516$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool != true); - assert (forall $o: ref :: cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - stack0i := 10; - // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - stack0b := i >= stack0i; - // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) - goto true2516to2550, false2516to2533; - - true2516to2550: - assume stack0b == true; - goto block2550; - - false2516to2533: - assume stack0b == false; - goto block2533; - - block2550: - // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) - stack0o := $stringLiteral8; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) - stack0o := $stringLiteral9; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) - call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(46,10) - return; - - block2533: - // ----- load constant ... [1] ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) - stack0o := $stringLiteral7; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) - call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(41,17) - call System.Threading.Thread.Yield(); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,37) - local1 := i; - // ----- load constant 1 - stack0i := 1; - // ----- binary operator - stack0i := local1 + stack0i; - // ----- copy - i := stack0i; - // ----- copy - stack0i := local1; - // ----- branch - goto block2516; - - block2516$LoopPreheader: - $Heap$block2516$LoopPreheader := $Heap; - goto block2516; - -} - - - -procedure Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int); - requires args$in == null || (cast($Heap[args$in, $writable]):bool == true && cast($Heap[args$in, $inv]):name == $typeof(args$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures IsAllocated($Heap, $result); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -implementation Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int) -{ - var args: ref, stack0o: ref, stack1o: ref, stack50000o: ref, t1: ref, t2: ref, i: int, stack0i: int, stack0b: bool, local3: int, return.value: int, SS$Display.Return.Local: int, $Heap$block3825$LoopPreheader: [ref,name]any; - - entry: - assume IsHeap($Heap); - args := args$in; - assume $Is(args, RefArray(System.String, 1)); - assume cast($Heap[args$in, $allocated]):bool == true; - goto block3791; - - block3791: - goto block3808; - - block3808: - stack0o := null; - // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - havoc stack1o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - assert stack50000o != null; - call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - stack0o := stack50000o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - assert stack50000o != null; - call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - stack0o := stack50000o; - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) - t1 := stack0o; - stack0o := null; - // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - havoc stack1o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - assert stack50000o != null; - call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - stack0o := stack50000o; - // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - havoc stack50000o; - assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; - $Heap[stack50000o, $allocated] := true; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - assert stack50000o != null; - call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - stack0o := stack50000o; - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) - t2 := stack0o; - // ----- load constant Starting first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) - stack0o := $stringLiteral10; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(55,13) - assert t1 != null; - call System.Threading.Thread.Start(t1); - // ----- load constant Started first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) - stack0o := $stringLiteral11; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant Starting second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) - stack0o := $stringLiteral12; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(59,13) - assert t2 != null; - call System.Threading.Thread.Start(t2); - // ----- load constant Started second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) - stack0o := $stringLiteral13; - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) - call System.Console.WriteLine$System.String(stack0o); - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,18) - i := 0; - goto block3825$LoopPreheader; - - block3825: - // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - assert (forall $o: ref :: $Heap$block3825$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool != true); - assert (forall $o: ref :: cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - // ----- load constant 30 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - stack0i := 30; - // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - stack0b := i >= stack0i; - // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) - goto true3825to3859, false3825to3842; - - true3825to3859: - assume stack0b == true; - goto block3859; - - false3825to3842: - assume stack0b == false; - goto block3842; - - block3859: - // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(66,13) - return.value := 0; - // ----- branch - goto block3876; - - block3842: - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(64,17) - call System.Threading.Thread.Yield(); - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,37) - local3 := i; - // ----- load constant 1 - stack0i := 1; - // ----- binary operator - stack0i := local3 + stack0i; - // ----- copy - i := stack0i; - // ----- copy - stack0i := local3; - // ----- branch - goto block3825; - - block3876: - // ----- copy - SS$Display.Return.Local := return.value; - // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) - stack0i := return.value; - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) - $result := stack0i; - return; - - block3825$LoopPreheader: - $Heap$block3825$LoopPreheader := $Heap; - goto block3825; - -} - - - -axiom $IsClass(System.Threading.ThreadStart); - -axiom $IsClass(System.MulticastDelegate); - -axiom $IsClass(System.Delegate); - -axiom System.Delegate <: System.Object && AsDirectSubClass(System.Delegate, System.Object) == System.Delegate; - -axiom Implements(System.Delegate, System.ICloneable); - -axiom (forall $K: name :: { System.Delegate <: $K } System.Delegate <: $K <==> System.Delegate == $K || System.Object <: $K || System.ICloneable <: $K); - -function Inv_System.Delegate(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Delegate(this, heap) } Inv_System.Delegate(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Delegate } { Inv_System.Delegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Delegate ==> Inv_System.Delegate($o, heap)); - -axiom System.MulticastDelegate <: System.Delegate && AsDirectSubClass(System.MulticastDelegate, System.Delegate) == System.MulticastDelegate; - -axiom (forall $K: name :: { System.MulticastDelegate <: $K } System.MulticastDelegate <: $K <==> System.MulticastDelegate == $K || System.Delegate <: $K); - -function Inv_System.MulticastDelegate(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.MulticastDelegate(this, heap) } Inv_System.MulticastDelegate(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.MulticastDelegate } { Inv_System.MulticastDelegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.MulticastDelegate ==> Inv_System.MulticastDelegate($o, heap)); - -axiom System.Threading.ThreadStart <: System.MulticastDelegate && AsDirectSubClass(System.Threading.ThreadStart, System.MulticastDelegate) == System.Threading.ThreadStart; - -axiom (forall $K: name :: { System.Threading.ThreadStart <: $K } System.Threading.ThreadStart <: $K <==> System.Threading.ThreadStart == $K || System.MulticastDelegate <: $K); - -axiom (forall $U: name :: { $U <: System.Threading.ThreadStart } $U <: System.Threading.ThreadStart ==> $U == System.Threading.ThreadStart); - -function Inv_System.Threading.ThreadStart(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.ThreadStart(this, heap) } Inv_System.Threading.ThreadStart(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.ThreadStart } { Inv_System.Threading.ThreadStart($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.ThreadStart ==> Inv_System.Threading.ThreadStart($o, heap)); - -procedure System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(this: ref, object$in: ref, method$in: ref); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.ThreadStart; - - - -axiom $IsClass(System.Threading.Thread); - -axiom System.Threading.Thread <: System.Object && AsDirectSubClass(System.Threading.Thread, System.Object) == System.Threading.Thread; - -axiom (forall $K: name :: { System.Threading.Thread <: $K } System.Threading.Thread <: $K <==> System.Threading.Thread == $K || System.Object <: $K); - -axiom (forall $U: name :: { $U <: System.Threading.Thread } $U <: System.Threading.Thread ==> $U == System.Threading.Thread); - -function Inv_System.Threading.Thread(object: ref, heap: [ref,name]any) returns (result: bool); - -axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.Thread(this, heap) } Inv_System.Threading.Thread(this, heap) <==> true); - -axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.Thread } { Inv_System.Threading.Thread($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.Thread ==> Inv_System.Threading.Thread($o, heap)); - -procedure System.Threading.Thread..ctor$System.Threading.ThreadStart(this: ref, start$in: ref); - requires start$in == null || (cast($Heap[start$in, $writable]):bool == true && cast($Heap[start$in, $inv]):name == $typeof(start$in)); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Threading.Thread <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.Thread; - ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; - - - -procedure System.Threading.Thread.Start(this: ref); - requires cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == $typeof(this); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - - - -procedure Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(Microsoft.Singularity.Applications.ThreadTest <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == Microsoft.Singularity.Applications.ThreadTest; - ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; - - - -implementation Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref) -{ - - entry: - assume IsHeap($Heap); - assume $IsNotNull(this, Microsoft.Singularity.Applications.ThreadTest); - assume cast($Heap[this, $allocated]):bool == true; - assume cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; - goto block4777; - - block4777: - goto block4794; - - block4794: - // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,18) - assert this != null; - call System.Object..ctor(this); - // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,28) - assert this != null; - assert cast($Heap[this, $writable]):bool == true && System.Object <: cast($Heap[this, $inv]):name; - assert cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; - assert Inv_Microsoft.Singularity.Applications.ThreadTest(this, $Heap); - $Heap[this, $inv] := Microsoft.Singularity.Applications.ThreadTest; - return; - -} - - - -procedure System.Object..ctor(this: ref); - modifies $Heap; - free ensures IsHeap($Heap); - free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Object <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); - free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); - free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); - free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); - ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; - ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; - - - -type ref, name, any; -const null : ref; +// RUN: %boogie -noinfer "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + + +type elements; + +type struct; + +var $Heap: [ref,name]any where IsHeap($Heap); +function cast(S) returns (T); +function IsHeap(h: [ref,name]any) returns (bool); + +const unique $allocated: name; + +const unique $elements: name; + +const unique $inv: name; + +const unique $writable: name; + +const unique $sharingMode: name; + +const unique $SharingMode_Unshared: name; + +const unique $SharingMode_LockProtected: name; + +function ClassRepr(class: name) returns (ref); + +axiom (forall c0: name, c1: name :: c0 != c1 ==> ClassRepr(c0) != ClassRepr(c1)); + +axiom (forall T: name :: !($typeof(ClassRepr(T)) <: System.Object)); + +axiom (forall T: name :: ClassRepr(T) != null); + +axiom (forall T: name, h: [ref,name]any :: { h[ClassRepr(T), $writable] } IsHeap(h) ==> cast(h[ClassRepr(T), $writable]):bool); + +function IsDirectlyModifiableField(f: name) returns (bool); + +axiom !IsDirectlyModifiableField($allocated); + +axiom IsDirectlyModifiableField($elements); + +axiom !IsDirectlyModifiableField($inv); + +axiom !IsDirectlyModifiableField($writable); + +function IsStaticField(f: name) returns (bool); + +axiom !IsStaticField($allocated); + +axiom !IsStaticField($elements); + +axiom !IsStaticField($inv); + +axiom !IsStaticField($writable); + +function ValueArrayGet(elements, int) returns (any); + +function ValueArraySet(elements, int, any) returns (elements); + +function RefArrayGet(elements, int) returns (ref); + +function RefArraySet(elements, int, ref) returns (elements); + +axiom (forall A: elements, i: int, x: any :: ValueArrayGet(ValueArraySet(A, i, x), i) == x); + +axiom (forall A: elements, i: int, j: int, x: any :: i != j ==> ValueArrayGet(ValueArraySet(A, i, x), j) == ValueArrayGet(A, j)); + +axiom (forall A: elements, i: int, x: ref :: RefArrayGet(RefArraySet(A, i, x), i) == x); + +axiom (forall A: elements, i: int, j: int, x: ref :: i != j ==> RefArrayGet(RefArraySet(A, i, x), j) == RefArrayGet(A, j)); + +function ArrayIndex(arr: ref, dim: int, indexAtDim: int, remainingIndexContribution: int) returns (int); + +axiom (forall a: ref, d: int, x: int, y: int, x': int, y': int :: ArrayIndex(a, d, x, y) == ArrayIndex(a, d, x', y') ==> x == x' && y == y'); + +axiom (forall a: ref, T: name, i: int, r: int, heap: [ref,name]any :: $typeof(a) <: RefArray(T, r) ==> $Is(RefArrayGet(cast(heap[a, $elements]):elements, i), T)); + +function $Rank(ref) returns (int); + +axiom (forall a: ref :: 1 <= $Rank(a)); + +axiom (forall a: ref, T: name, r: int :: { $Is(a, ValueArray(T, r)) } $Is(a, ValueArray(T, r)) ==> $Rank(a) == r); + +axiom (forall a: ref, T: name, r: int :: { $Is(a, RefArray(T, r)) } $Is(a, RefArray(T, r)) ==> $Rank(a) == r); + +function $Length(ref) returns (int); + +axiom (forall a: ref :: { $Length(a) } 0 <= $Length(a)); + +function $DimLength(ref, int) returns (int); + +axiom (forall a: ref, i: int :: 0 <= $DimLength(a, i)); + +axiom (forall a: ref :: $Rank(a) == 1 ==> $DimLength(a, 0) == $Length(a)); + +function $LBound(ref, int) returns (int); + +function $UBound(ref, int) returns (int); + +axiom (forall a: ref, i: int :: { $LBound(a, i) } $LBound(a, i) == 0); + +axiom (forall a: ref, i: int :: { $UBound(a, i) } $UBound(a, i) == $DimLength(a, i) - 1); + +const unique System.Array: name; + +axiom $IsClass(System.Array); + +axiom System.Array <: System.Object; + +function $ElementType(name) returns (name); + +function ValueArray(elementType: name, rank: int) returns (name); + +axiom (forall T: name, r: int :: { ValueArray(T, r) } ValueArray(T, r) <: System.Array); + +function RefArray(elementType: name, rank: int) returns (name); + +axiom (forall T: name, r: int :: { RefArray(T, r) } RefArray(T, r) <: System.Array); + +axiom (forall T: name, U: name, r: int :: U <: T ==> RefArray(U, r) <: RefArray(T, r)); + +axiom (forall A: name, r: int :: $ElementType(ValueArray(A, r)) == A); + +axiom (forall A: name, r: int :: $ElementType(RefArray(A, r)) == A); + +axiom (forall A: name, r: int, T: name :: { T <: RefArray(A, r) } T <: RefArray(A, r) ==> T == RefArray($ElementType(T), r) && $ElementType(T) <: A); + +axiom (forall A: name, r: int, T: name :: { T <: ValueArray(A, r) } T <: ValueArray(A, r) ==> T == ValueArray(A, r)); + +axiom (forall A: name, r: int, T: name :: RefArray(A, r) <: T ==> System.Array <: T || (T == RefArray($ElementType(T), r) && A <: $ElementType(T))); + +axiom (forall A: name, r: int, T: name :: ValueArray(A, r) <: T ==> System.Array <: T || T == ValueArray(A, r)); + +function $ArrayPtr(elementType: name) returns (name); + +function $StructGet(struct, name) returns (any); + +function $StructSet(struct, name, any) returns (struct); + +axiom (forall s: struct, f: name, x: any :: $StructGet($StructSet(s, f, x), f) == x); + +axiom (forall s: struct, f: name, f': name, x: any :: f != f' ==> $StructGet($StructSet(s, f, x), f') == $StructGet(s, f')); + +function ZeroInit(s: struct, typ: name) returns (bool); + +function $typeof(ref) returns (name); + +function Implements(class: name, interface: name) returns (bool); + +axiom (forall T: name, J: name :: { Implements(T, J) } Implements(T, J) ==> T <: J); + +function InterfaceExtends(subIntf: name, superIntf: name) returns (bool); + +axiom (forall J: name, K: name :: { InterfaceExtends(J, K) } InterfaceExtends(J, K) ==> J <: K); + +function $IsClass(name) returns (bool); + +axiom (forall C: name :: { $IsClass(C) } $IsClass(C) ==> C <: C); + +function AsDirectSubClass(sub: name, base: name) returns (sub': name); + +function OneClassDown(sub: name, base: name) returns (directSub: name); + +axiom (forall A: name, B: name, C: name :: { C <: AsDirectSubClass(B, A) } C <: AsDirectSubClass(B, A) ==> OneClassDown(C, A) == B); + +function $IsInterface(name) returns (bool); + +axiom (forall J: name :: { $IsInterface(J) } $IsInterface(J) ==> J <: System.Object); + +function $IsValueType(name) returns (bool); + +axiom (forall T: name :: $IsValueType(T) ==> (forall U: name :: T <: U ==> T == U) && (forall U: name :: U <: T ==> T == U)); + +const unique System.Object: name; + +axiom $IsClass(System.Object); + +function $IsTokenForType(struct, name) returns (bool); + +function TypeObject(name) returns (ref); + +const unique System.Type: name; + +axiom System.Type <: System.Object; + +axiom (forall T: name :: { TypeObject(T) } $IsNotNull(TypeObject(T), System.Type)); + +function $Is(ref, name) returns (bool); + +axiom (forall o: ref, T: name :: { $Is(o, T) } $Is(o, T) <==> o == null || $typeof(o) <: T); + +function $IsNotNull(ref, name) returns (bool); + +axiom (forall o: ref, T: name :: { $IsNotNull(o, T) } $IsNotNull(o, T) <==> o != null && $Is(o, T)); + +function $As(ref, name) returns (ref); + +axiom (forall o: ref, T: name :: $Is(o, T) ==> $As(o, T) == o); + +axiom (forall o: ref, T: name :: !$Is(o, T) ==> $As(o, T) == null); + +axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, RefArray(A, r)) ==> heap[o, $inv] == $typeof(o)); + +axiom (forall heap: [ref,name]any, o: ref, A: name, r: int :: $Is(o, ValueArray(A, r)) ==> heap[o, $inv] == $typeof(o)); + +function IsAllocated(h: [ref,name]any, o: any) returns (bool); + +axiom (forall h: [ref,name]any, o: ref, f: name :: { IsAllocated(h, h[o, f]) } IsHeap(h) ==> IsAllocated(h, h[o, f])); + +axiom (forall h: [ref,name]any, s: struct, f: name :: { IsAllocated(h, $StructGet(s, f)) } IsAllocated(h, s) ==> IsAllocated(h, $StructGet(s, f))); + +axiom (forall h: [ref,name]any, e: elements, i: int :: { IsAllocated(h, RefArrayGet(e, i)) } IsAllocated(h, e) ==> IsAllocated(h, RefArrayGet(e, i))); + +axiom (forall h: [ref,name]any, o: ref :: { h[o, $allocated] } IsAllocated(h, o) ==> cast(h[o, $allocated]):bool); + +axiom (forall h: [ref,name]any, c: name :: { h[ClassRepr(c), $allocated] } IsHeap(h) ==> cast(h[ClassRepr(c), $allocated]):bool); + +function DeclType(field: name) returns (class: name); + +function AsNonNullRefField(field: name, T: name) returns (f: name); + +function AsRefField(field: name, T: name) returns (f: name); + +function AsRangeField(field: name, T: name) returns (f: name); + +axiom (forall f: name, T: name :: { AsNonNullRefField(f, T) } AsNonNullRefField(f, T) == f ==> AsRefField(f, T) == f); + +axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRefField(f, T)] } IsHeap(h) ==> $Is(cast(h[o, AsRefField(f, T)]):ref, T)); + +axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsNonNullRefField(f, T)] } IsHeap(h) ==> cast(h[o, AsNonNullRefField(f, T)]):ref != null); + +axiom (forall h: [ref,name]any, o: ref, f: name, T: name :: { h[o, AsRangeField(f, T)] } IsHeap(h) ==> InRange(cast(h[o, AsRangeField(f, T)]):int, T)); + +const unique System.String: name; + +axiom (forall h: [ref,name]any, s: ref :: IsHeap(h) && $typeof(s) == System.String ==> h[s, $inv] == $typeof(s) && cast(h[s, $writable]):bool); + +function AsOwnedField(f: name) returns (name); + +axiom (forall h: [ref,name]any, o: ref, f: name :: { h[o, AsOwnedField(f)] } IsHeap(h) && cast(h[o, $inv]):name <: DeclType(AsOwnedField(f)) ==> cast(h[o, AsOwnedField(f)]):ref == null || $typeof(cast(h[o, AsOwnedField(f)]):ref) == System.String || !cast(h[cast(h[o, AsOwnedField(f)]):ref, $writable]):bool); + +axiom (forall h: [ref,name]any, o: ref :: { h[o, $writable] } IsHeap(h) && !cast(h[o, $writable]):bool ==> cast(h[o, $inv]):name == $typeof(o)); + +function Box(any, ref) returns (ref); + +function Unbox(ref) returns (any); + +axiom (forall x: any, p: ref :: { Unbox(Box(x, p)) } Unbox(Box(x, p)) == x); + +axiom (forall heap: [ref,name]any, x: any, p: ref :: { heap[Box(x, p), $inv] } IsHeap(heap) ==> heap[Box(x, p), $inv] == $typeof(Box(x, p))); + +function UnboxedType(ref) returns (name); + +function BoxTester(p: ref, typ: name) returns (ref); + +axiom (forall p: ref, typ: name :: { BoxTester(p, typ) } UnboxedType(p) == typ <==> BoxTester(p, typ) != null); + +const unique System.Int16: name; + +axiom $IsValueType(System.Int16); + +const unique System.Int32: name; + +axiom $IsValueType(System.Int32); + +const unique System.Int64: name; + +axiom $IsValueType(System.Int64); + +const unique System.Byte: name; + +axiom $IsValueType(System.Byte); + +const unique System.Int16.MinValue: int; + +const unique System.Int16.MaxValue: int; + +const unique System.Int32.MinValue: int; + +const unique System.Int32.MaxValue: int; + +const unique System.Int64.MinValue: int; + +const unique System.Int64.MaxValue: int; + +axiom System.Int64.MinValue < System.Int32.MinValue; + +axiom System.Int32.MinValue < System.Int16.MinValue; + +axiom System.Int16.MinValue < System.Int16.MaxValue; + +axiom System.Int16.MaxValue < System.Int32.MaxValue; + +axiom System.Int32.MaxValue < System.Int64.MaxValue; + +function InRange(i: int, T: name) returns (bool); + +axiom (forall i: int :: InRange(i, System.Int16) <==> System.Int16.MinValue <= i && i <= System.Int16.MaxValue); + +axiom (forall i: int :: InRange(i, System.Int32) <==> System.Int32.MinValue <= i && i <= System.Int32.MaxValue); + +axiom (forall i: int :: InRange(i, System.Int64) <==> System.Int64.MinValue <= i && i <= System.Int64.MaxValue); + +axiom (forall i: int :: { InRange(i, System.Byte) } InRange(i, System.Byte) <==> 0 <= i && i < 256); + +function $RealToInt(real) returns (int); + +function $IntToReal(int) returns (real); + +function $SizeIs(name, int) returns (bool); + +function $IfThenElse(bool, any, any) returns (any); + +axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } b ==> $IfThenElse(b, x, y) == x); + +axiom (forall b: bool, x: any, y: any :: { $IfThenElse(b, x, y) } !b ==> $IfThenElse(b, x, y) == y); + +function #neg(int) returns (int); + +function #rneg(real) returns (real); + +function #rdiv(real, real) returns (real); + +function #and(int, int) returns (int); + +function #or(int, int) returns (int); + +function #xor(int, int) returns (int); + +function #shl(int, int) returns (int); + +function #shr(int, int) returns (int); + +axiom (forall x: int, y: int :: { x mod y } { x div y } x mod y == x - x div y * y); + +axiom (forall x: int, y: int :: { x mod y } 0 <= x && 0 < y ==> 0 <= x mod y && x mod y < y); + +axiom (forall x: int, y: int :: { x mod y } 0 <= x && y < 0 ==> 0 <= x mod y && x mod y < 0 - y); + +axiom (forall x: int, y: int :: { x mod y } x <= 0 && 0 < y ==> 0 - y < x mod y && x mod y <= 0); + +axiom (forall x: int, y: int :: { x mod y } x <= 0 && y < 0 ==> y < x mod y && x mod y <= 0); + +axiom (forall x: int, y: int :: { (x + y) mod y } 0 <= x && 0 <= y ==> (x + y) mod y == x mod y); + +axiom (forall x: int, y: int :: { (y + x) mod y } 0 <= x && 0 <= y ==> (y + x) mod y == x mod y); + +axiom (forall x: int, y: int :: { (x - y) mod y } 0 <= x - y && 0 <= y ==> (x - y) mod y == x mod y); + +axiom (forall a: int, b: int, d: int :: { a mod d,b mod d } 2 <= d && a mod d == b mod d && a < b ==> a + d <= b); + +axiom (forall i: int :: { #shl(i, 0) } #shl(i, 0) == i); + +axiom (forall i: int, j: int :: 0 <= j ==> #shl(i, j + 1) == #shl(i, j) * 2); + +axiom (forall i: int :: { #shr(i, 0) } #shr(i, 0) == i); + +axiom (forall i: int, j: int :: 0 <= j ==> #shr(i, j + 1) == #shr(i, j) div 2); + +const unique $UnknownRef: ref; + +const unique System.IComparable: name; + +const unique Microsoft.Singularity.Applications.ThreadTest: name; + +const unique System.Threading.Thread: name; + +const unique System.Collections.IEnumerable: name; + +const unique System.Threading.ThreadStart: name; + +const unique System.ICloneable: name; + +const unique System.MulticastDelegate: name; + +const unique System.Delegate: name; + +const unique $stringLiteral0: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral0, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral0, $allocated]):bool) && $IsNotNull($stringLiteral0, System.String) && $Length($stringLiteral0) == 13; + +const unique $stringLiteral1: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral1, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral1, $allocated]):bool) && $IsNotNull($stringLiteral1, System.String) && $Length($stringLiteral1) == 14; + +const unique $stringLiteral2: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral2, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral2, $allocated]):bool) && $IsNotNull($stringLiteral2, System.String) && $Length($stringLiteral2) == 11; + +const unique $stringLiteral3: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral3, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral3, $allocated]):bool) && $IsNotNull($stringLiteral3, System.String) && $Length($stringLiteral3) == 18; + +const unique $stringLiteral4: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral4, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral4, $allocated]):bool) && $IsNotNull($stringLiteral4, System.String) && $Length($stringLiteral4) == 19; + +const unique $stringLiteral5: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral5, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral5, $allocated]):bool) && $IsNotNull($stringLiteral5, System.String) && $Length($stringLiteral5) == 14; + +const unique $stringLiteral6: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral6, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral6, $allocated]):bool) && $IsNotNull($stringLiteral6, System.String) && $Length($stringLiteral6) == 15; + +const unique $stringLiteral7: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral7, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral7, $allocated]):bool) && $IsNotNull($stringLiteral7, System.String) && $Length($stringLiteral7) == 11; + +const unique $stringLiteral8: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral8, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral8, $allocated]):bool) && $IsNotNull($stringLiteral8, System.String) && $Length($stringLiteral8) == 19; + +const unique $stringLiteral9: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral9, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral9, $allocated]):bool) && $IsNotNull($stringLiteral9, System.String) && $Length($stringLiteral9) == 20; + +const unique $stringLiteral10: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral10, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral10, $allocated]):bool) && $IsNotNull($stringLiteral10, System.String) && $Length($stringLiteral10) == 22; + +const unique $stringLiteral11: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral11, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral11, $allocated]):bool) && $IsNotNull($stringLiteral11, System.String) && $Length($stringLiteral11) == 21; + +const unique $stringLiteral12: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral12, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral12, $allocated]):bool) && $IsNotNull($stringLiteral12, System.String) && $Length($stringLiteral12) == 23; + +const unique $stringLiteral13: ref; + +axiom (forall heap: [ref,name]any :: { cast(heap[$stringLiteral13, $allocated]):bool } IsHeap(heap) ==> cast(heap[$stringLiteral13, $allocated]):bool) && $IsNotNull($stringLiteral13, System.String) && $Length($stringLiteral13) == 22; + +axiom $IsClass(Microsoft.Singularity.Applications.ThreadTest); + +axiom Microsoft.Singularity.Applications.ThreadTest <: System.Object && AsDirectSubClass(Microsoft.Singularity.Applications.ThreadTest, System.Object) == Microsoft.Singularity.Applications.ThreadTest; + +axiom (forall $K: name :: { Microsoft.Singularity.Applications.ThreadTest <: $K } Microsoft.Singularity.Applications.ThreadTest <: $K <==> Microsoft.Singularity.Applications.ThreadTest == $K || System.Object <: $K); + +function Inv_Microsoft.Singularity.Applications.ThreadTest(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) } Inv_Microsoft.Singularity.Applications.ThreadTest(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest } { Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: Microsoft.Singularity.Applications.ThreadTest ==> Inv_Microsoft.Singularity.Applications.ThreadTest($o, heap)); + +procedure Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod(); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +implementation Microsoft.Singularity.Applications.ThreadTest.FirstThreadMethod() +{ + var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block1513$LoopPreheader: [ref,name]any; + + entry: + assume IsHeap($Heap); + goto block1479; + + block1479: + goto block1496; + + block1496: + // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) + stack0o := $stringLiteral0; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(21,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant First thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) + stack0o := $stringLiteral1; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(22,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,18) + i := 0; + goto block1513$LoopPreheader; + + block1513: + // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + assert (forall $o: ref :: $Heap$block1513$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool != true); + assert (forall $o: ref :: cast($Heap$block1513$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + stack0i := 10; + // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + stack0b := i >= stack0i; + // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,29) + goto true1513to1547, false1513to1530; + + true1513to1547: + assume stack0b == true; + goto block1547; + + false1513to1530: + assume stack0b == false; + goto block1530; + + block1547: + // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) + stack0o := $stringLiteral3; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(29,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant First thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) + stack0o := $stringLiteral4; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(30,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(31,10) + return; + + block1530: + // ----- load constant [0] ... ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) + stack0o := $stringLiteral2; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(25,17) + call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(26,17) + call System.Threading.Thread.Yield(); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(24,37) + local1 := i; + // ----- load constant 1 + stack0i := 1; + // ----- binary operator + stack0i := local1 + stack0i; + // ----- copy + i := stack0i; + // ----- copy + stack0i := local1; + // ----- branch + goto block1513; + + block1513$LoopPreheader: + $Heap$block1513$LoopPreheader := $Heap; + goto block1513; + +} + + + +axiom $IsClass(System.String); + +axiom System.String <: System.Object && AsDirectSubClass(System.String, System.Object) == System.String; + +axiom $IsInterface(System.IComparable); + +axiom (forall $K: name :: { System.IComparable <: $K } System.IComparable <: $K <==> System.IComparable == $K || System.Object == $K); + +axiom Implements(System.String, System.IComparable); + +axiom $IsInterface(System.ICloneable); + +axiom (forall $K: name :: { System.ICloneable <: $K } System.ICloneable <: $K <==> System.ICloneable == $K || System.Object == $K); + +axiom Implements(System.String, System.ICloneable); + +axiom $IsInterface(System.Collections.IEnumerable); + +axiom (forall $K: name :: { System.Collections.IEnumerable <: $K } System.Collections.IEnumerable <: $K <==> System.Collections.IEnumerable == $K || System.Object == $K); + +axiom Implements(System.String, System.Collections.IEnumerable); + +axiom (forall $K: name :: { System.String <: $K } System.String <: $K <==> System.String == $K || System.Object <: $K || System.IComparable <: $K || System.ICloneable <: $K || System.Collections.IEnumerable <: $K); + +axiom (forall $U: name :: { $U <: System.String } $U <: System.String ==> $U == System.String); + +function Inv_System.String(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.String(this, heap) } Inv_System.String(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.String } { Inv_System.String($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.String ==> Inv_System.String($o, heap)); + +procedure System.Console.WriteLine$System.String(value$in: ref); + requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure Microsoft.Singularity.DebugStub.Print$System.String(value$in: ref); + requires value$in == null || (cast($Heap[value$in, $writable]):bool == true && cast($Heap[value$in, $inv]):name == $typeof(value$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure System.Threading.Thread.Yield(); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod(); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +implementation Microsoft.Singularity.Applications.ThreadTest.SecondThreadMethod() +{ + var stack0o: ref, i: int, stack0i: int, stack0b: bool, local1: int, $Heap$block2516$LoopPreheader: [ref,name]any; + + entry: + assume IsHeap($Heap); + goto block2482; + + block2482: + goto block2499; + + block2499: + // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) + stack0o := $stringLiteral5; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(35,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant Second thread! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) + stack0o := $stringLiteral6; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(36,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,18) + i := 0; + goto block2516$LoopPreheader; + + block2516: + // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + assert (forall $o: ref :: $Heap$block2516$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool != true); + assert (forall $o: ref :: cast($Heap$block2516$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + // ----- load constant 10 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + stack0i := 10; + // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + stack0b := i >= stack0i; + // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,29) + goto true2516to2550, false2516to2533; + + true2516to2550: + assume stack0b == true; + goto block2550; + + false2516to2533: + assume stack0b == false; + goto block2533; + + block2550: + // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) + stack0o := $stringLiteral8; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(44,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant Second thread done! ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) + stack0o := $stringLiteral9; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(45,13) + call Microsoft.Singularity.DebugStub.Print$System.String(stack0o); + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(46,10) + return; + + block2533: + // ----- load constant ... [1] ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) + stack0o := $stringLiteral7; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(40,17) + call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(41,17) + call System.Threading.Thread.Yield(); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(38,37) + local1 := i; + // ----- load constant 1 + stack0i := 1; + // ----- binary operator + stack0i := local1 + stack0i; + // ----- copy + i := stack0i; + // ----- copy + stack0i := local1; + // ----- branch + goto block2516; + + block2516$LoopPreheader: + $Heap$block2516$LoopPreheader := $Heap; + goto block2516; + +} + + + +procedure Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int); + requires args$in == null || (cast($Heap[args$in, $writable]):bool == true && cast($Heap[args$in, $inv]):name == $typeof(args$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures IsAllocated($Heap, $result); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +implementation Microsoft.Singularity.Applications.ThreadTest.Main$System.String.array(args$in: ref) returns ($result: int) +{ + var args: ref, stack0o: ref, stack1o: ref, stack50000o: ref, t1: ref, t2: ref, i: int, stack0i: int, stack0b: bool, local3: int, return.value: int, SS$Display.Return.Local: int, $Heap$block3825$LoopPreheader: [ref,name]any; + + entry: + assume IsHeap($Heap); + args := args$in; + assume $Is(args, RefArray(System.String, 1)); + assume cast($Heap[args$in, $allocated]):bool == true; + goto block3791; + + block3791: + goto block3808; + + block3808: + stack0o := null; + // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + havoc stack1o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + assert stack50000o != null; + call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + stack0o := stack50000o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + assert stack50000o != null; + call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + stack0o := stack50000o; + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(51,13) + t1 := stack0o; + stack0o := null; + // ----- load function ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + havoc stack1o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.ThreadStart; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + assert stack50000o != null; + call System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(stack50000o, stack0o, stack1o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + stack0o := stack50000o; + // ----- new object ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + havoc stack50000o; + assume cast($Heap[stack50000o, $allocated]):bool == false && stack50000o != null && $typeof(stack50000o) == System.Threading.Thread; + $Heap[stack50000o, $allocated] := true; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + assert stack50000o != null; + call System.Threading.Thread..ctor$System.Threading.ThreadStart(stack50000o, stack0o); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + stack0o := stack50000o; + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(52,13) + t2 := stack0o; + // ----- load constant Starting first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) + stack0o := $stringLiteral10; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(54,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(55,13) + assert t1 != null; + call System.Threading.Thread.Start(t1); + // ----- load constant Started first thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) + stack0o := $stringLiteral11; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(56,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant Starting second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) + stack0o := $stringLiteral12; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(58,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(59,13) + assert t2 != null; + call System.Threading.Thread.Start(t2); + // ----- load constant Started second thread. ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) + stack0o := $stringLiteral13; + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(60,13) + call System.Console.WriteLine$System.String(stack0o); + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,18) + i := 0; + goto block3825$LoopPreheader; + + block3825: + // ----- default loop invariant: $inv field ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + assert (forall $o: ref :: $Heap$block3825$LoopPreheader[$o, $inv] == $Heap[$o, $inv] || cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool != true); + assert (forall $o: ref :: cast($Heap$block3825$LoopPreheader[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + // ----- load constant 30 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + stack0i := 30; + // ----- binary operator ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + stack0b := i >= stack0i; + // ----- branch ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,29) + goto true3825to3859, false3825to3842; + + true3825to3859: + assume stack0b == true; + goto block3859; + + false3825to3842: + assume stack0b == false; + goto block3842; + + block3859: + // ----- load constant 0 ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(66,13) + return.value := 0; + // ----- branch + goto block3876; + + block3842: + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(64,17) + call System.Threading.Thread.Yield(); + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(62,37) + local3 := i; + // ----- load constant 1 + stack0i := 1; + // ----- binary operator + stack0i := local3 + stack0i; + // ----- copy + i := stack0i; + // ----- copy + stack0i := local3; + // ----- branch + goto block3825; + + block3876: + // ----- copy + SS$Display.Return.Local := return.value; + // ----- copy ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) + stack0i := return.value; + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(67,10) + $result := stack0i; + return; + + block3825$LoopPreheader: + $Heap$block3825$LoopPreheader := $Heap; + goto block3825; + +} + + + +axiom $IsClass(System.Threading.ThreadStart); + +axiom $IsClass(System.MulticastDelegate); + +axiom $IsClass(System.Delegate); + +axiom System.Delegate <: System.Object && AsDirectSubClass(System.Delegate, System.Object) == System.Delegate; + +axiom Implements(System.Delegate, System.ICloneable); + +axiom (forall $K: name :: { System.Delegate <: $K } System.Delegate <: $K <==> System.Delegate == $K || System.Object <: $K || System.ICloneable <: $K); + +function Inv_System.Delegate(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Delegate(this, heap) } Inv_System.Delegate(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Delegate } { Inv_System.Delegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Delegate ==> Inv_System.Delegate($o, heap)); + +axiom System.MulticastDelegate <: System.Delegate && AsDirectSubClass(System.MulticastDelegate, System.Delegate) == System.MulticastDelegate; + +axiom (forall $K: name :: { System.MulticastDelegate <: $K } System.MulticastDelegate <: $K <==> System.MulticastDelegate == $K || System.Delegate <: $K); + +function Inv_System.MulticastDelegate(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.MulticastDelegate(this, heap) } Inv_System.MulticastDelegate(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.MulticastDelegate } { Inv_System.MulticastDelegate($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.MulticastDelegate ==> Inv_System.MulticastDelegate($o, heap)); + +axiom System.Threading.ThreadStart <: System.MulticastDelegate && AsDirectSubClass(System.Threading.ThreadStart, System.MulticastDelegate) == System.Threading.ThreadStart; + +axiom (forall $K: name :: { System.Threading.ThreadStart <: $K } System.Threading.ThreadStart <: $K <==> System.Threading.ThreadStart == $K || System.MulticastDelegate <: $K); + +axiom (forall $U: name :: { $U <: System.Threading.ThreadStart } $U <: System.Threading.ThreadStart ==> $U == System.Threading.ThreadStart); + +function Inv_System.Threading.ThreadStart(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.ThreadStart(this, heap) } Inv_System.Threading.ThreadStart(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.ThreadStart } { Inv_System.Threading.ThreadStart($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.ThreadStart ==> Inv_System.Threading.ThreadStart($o, heap)); + +procedure System.Threading.ThreadStart..ctor$System.Object$System.IntPtr(this: ref, object$in: ref, method$in: ref); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.ThreadStart; + + + +axiom $IsClass(System.Threading.Thread); + +axiom System.Threading.Thread <: System.Object && AsDirectSubClass(System.Threading.Thread, System.Object) == System.Threading.Thread; + +axiom (forall $K: name :: { System.Threading.Thread <: $K } System.Threading.Thread <: $K <==> System.Threading.Thread == $K || System.Object <: $K); + +axiom (forall $U: name :: { $U <: System.Threading.Thread } $U <: System.Threading.Thread ==> $U == System.Threading.Thread); + +function Inv_System.Threading.Thread(object: ref, heap: [ref,name]any) returns (result: bool); + +axiom (forall this: ref, heap: [ref,name]any :: { Inv_System.Threading.Thread(this, heap) } Inv_System.Threading.Thread(this, heap) <==> true); + +axiom (forall $o: ref, heap: [ref,name]any :: { cast(heap[$o, $inv]):name <: System.Threading.Thread } { Inv_System.Threading.Thread($o, heap) } IsHeap(heap) && cast(heap[$o, $inv]):name <: System.Threading.Thread ==> Inv_System.Threading.Thread($o, heap)); + +procedure System.Threading.Thread..ctor$System.Threading.ThreadStart(this: ref, start$in: ref); + requires start$in == null || (cast($Heap[start$in, $writable]):bool == true && cast($Heap[start$in, $inv]):name == $typeof(start$in)); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Threading.Thread <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Threading.Thread; + ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; + + + +procedure System.Threading.Thread.Start(this: ref); + requires cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == $typeof(this); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + + + +procedure Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(Microsoft.Singularity.Applications.ThreadTest <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == Microsoft.Singularity.Applications.ThreadTest; + ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; + + + +implementation Microsoft.Singularity.Applications.ThreadTest..ctor(this: ref) +{ + + entry: + assume IsHeap($Heap); + assume $IsNotNull(this, Microsoft.Singularity.Applications.ThreadTest); + assume cast($Heap[this, $allocated]):bool == true; + assume cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; + goto block4777; + + block4777: + goto block4794; + + block4794: + // ----- call ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,18) + assert this != null; + call System.Object..ctor(this); + // ----- return ----- C:\Maf\Singularity\base\Applications\Tests\ThreadTest\ThreadTest.cs(17,28) + assert this != null; + assert cast($Heap[this, $writable]):bool == true && System.Object <: cast($Heap[this, $inv]):name; + assert cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; + assert Inv_Microsoft.Singularity.Applications.ThreadTest(this, $Heap); + $Heap[this, $inv] := Microsoft.Singularity.Applications.ThreadTest; + return; + +} + + + +procedure System.Object..ctor(this: ref); + modifies $Heap; + free ensures IsHeap($Heap); + free ensures (forall $o: ref, $f: name :: $f != $inv && $o != null && cast(old($Heap)[$o, $allocated]):bool == true && cast(old($Heap)[$o, $writable]):bool == true && (!IsStaticField($f) || !IsDirectlyModifiableField($f)) && ($o != this || !(System.Object <: DeclType($f))) ==> old($Heap[$o, $f]) == $Heap[$o, $f]); + free ensures (forall $o: ref :: $o == this || old($Heap)[$o, $inv] == $Heap[$o, $inv] || cast(old($Heap)[$o, $allocated]):bool != true); + free ensures (forall $o: ref :: cast(old($Heap)[$o, $allocated]):bool ==> cast($Heap[$o, $allocated]):bool); + free ensures (forall $o: ref :: $o == this || old($Heap[$o, $sharingMode]) == $Heap[$o, $sharingMode]); + ensures cast($Heap[this, $writable]):bool == true && cast($Heap[this, $inv]):name == System.Object; + ensures $Heap[this, $sharingMode] == $SharingMode_Unshared; + + + +type ref, name, any; +const null : ref; -- cgit v1.2.3