Skip to content

Commit f605f1d

Browse files
authored
Merge branch 'master' into irreducible-cfg
2 parents ffe60b4 + 4eaf87e commit f605f1d

File tree

10 files changed

+232
-221
lines changed

10 files changed

+232
-221
lines changed

Source/Core/base.bpl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,19 +329,19 @@ pure procedure Map_Put<K,V>({:linear} path: Map K V, {:linear_in} l: One K, {:li
329329
pure procedure Map_GetValue<K,V>({:linear} path: Map K V, k: K) returns ({:linear} v: V);
330330
pure procedure Map_PutValue<K,V>({:linear} path: Map K V, k: K, {:linear_in} v: V);
331331

332-
type Loc;
332+
type Loc _;
333333

334-
pure procedure {:inline 1} Loc_New() returns ({:linear} {:pool "Loc_New"} l: One Loc)
334+
pure procedure {:inline 1} Loc_New<V>() returns ({:linear} {:pool "Loc_New"} l: One (Loc V))
335335
{
336336
assume {:add_to_pool "Loc_New", l} true;
337337
}
338338

339-
datatype TaggedLoc<K> { TaggedLoc(loc: Loc, tag: K) }
339+
datatype TaggedLoc<V,T> { TaggedLoc(loc: Loc V, tag: T) }
340340

341-
pure procedure {:inline 1} TaggedLocSet_New<K>(ks: Set K) returns ({:linear} {:pool "Loc_New"} l: One Loc, {:linear} tagged_locs: Set (TaggedLoc K))
341+
pure procedure {:inline 1} TaggedLocSet_New<V,T>(tags: Set T) returns ({:linear} {:pool "Loc_New"} l: One (Loc V), {:linear} tagged_locs: Set (TaggedLoc V T))
342342
{
343343
assume {:add_to_pool "Loc_New", l} true;
344-
tagged_locs := Set((lambda x: TaggedLoc K :: x->loc == l->val && Set_Contains(ks, x->tag)));
344+
tagged_locs := Set((lambda x: TaggedLoc V T :: x->loc == l->val && Set_Contains(tags, x->tag)));
345345
}
346346

347347
procedure create_async<T>(PA: T);

Source/Core/node.bpl

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,77 @@
1-
datatype Node<K,T> { Node(next: Option K, val: T) }
1+
datatype Node<T> { Node(next: Option (Loc (Node T)), val: T) }
2+
type LocNode T = Loc (Node T);
23

3-
function Between<K,T>(f: [K]Node K T, x: Option K, y: Option K, z: Option K): bool;
4-
function Avoiding<K,T>(f: [K]Node K T, x: Option K, y: Option K, z: Option K): bool;
5-
function {:inline} BetweenSet<K,T>(f:[K]Node K T, x: Option K, z: Option K): [K]bool
4+
function Between<T>(f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T))): bool;
5+
function Avoiding<T>(f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T))): bool;
6+
function {:inline} BetweenSet<T>(f:[Loc (Node T)]Node T, x: Option (Loc (Node T)), z: Option (Loc (Node T))): [Loc (Node T)]bool
67
{
7-
(lambda y: K :: Between(f, x, Some(y), z))
8+
(lambda y: Loc (Node T) :: Between(f, x, Some(y), z))
89
}
910

1011
// reflexive
11-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K :: Between(f, x, x, x));
12+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)) :: Between(f, x, x, x));
1213

1314
// step
14-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: K ::
15+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Loc (Node T) ::
1516
{f[x]}
1617
Between(f, Some(x), f[x]->next, f[x]->next));
1718

1819
// reach
19-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: K, y: Option K ::
20+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Loc (Node T), y: Option (Loc (Node T)) ::
2021
{f[x], Between(f, Some(x), y, y)}
2122
Between(f, Some(x), y, y) ==> Some(x) == y || Between(f, Some(x), f[x]->next, y));
2223

2324
// cycle
24-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: K, y: Option K ::
25+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Loc (Node T), y: Option (Loc (Node T)) ::
2526
{f[x], Between(f, Some(x), y, y)}
2627
f[x]->next == Some(x) && Between(f, Some(x), y, y) ==> Some(x) == y);
2728

2829
// sandwich
29-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K ::
30+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)) ::
3031
{Between(f, x, y, x)}
3132
Between(f, x, y, x) ==> x == y);
3233

3334
// order1
34-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K ::
35+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)) ::
3536
{Between(f, x, y, y), Between(f, x, z, z)}
3637
Between(f, x, y, y) && Between(f, x, z, z) ==> Between(f, x, y, z) || Between(f, x, z, y));
3738

3839
// order2
39-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K ::
40+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)) ::
4041
{Between(f, x, y, z)}
4142
Between(f, x, y, z) ==> Between(f, x, y, y) && Between(f, y, z, z));
4243

4344
// transitive1
44-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K ::
45+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)) ::
4546
{Between(f, x, y, y), Between(f, y, z, z)}
4647
Between(f, x, y, y) && Between(f, y, z, z) ==> Between(f, x, z, z));
4748

4849
// transitive2
49-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K, w: Option K ::
50+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)), w: Option (Loc (Node T)) ::
5051
{Between(f, x, y, z), Between(f, y, w, z)}
5152
Between(f, x, y, z) && Between(f, y, w, z) ==> Between(f, x, y, w) && Between(f, x, w, z));
5253

5354
// transitive3
54-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K, w: Option K ::
55+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)), w: Option (Loc (Node T)) ::
5556
{Between(f, x, y, z), Between(f, x, w, y)}
5657
Between(f, x, y, z) && Between(f, x, w, y) ==> Between(f, x, w, z) && Between(f, w, y, z));
5758

5859
// This axiom is required to deal with the incompleteness of the trigger for the reflexive axiom.
5960
// It cannot be proved using the rest of the axioms.
60-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, u: Option K, x: Option K ::
61+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, u: Option (Loc (Node T)), x: Option (Loc (Node T)) ::
6162
{Between(f, u, x, x)}
6263
Between(f, u, x, x) ==> Between(f, u, u, x));
6364

6465
// relation between Avoiding and Between
65-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K ::
66+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)) ::
6667
{Avoiding(f, x, y, z)}
6768
Avoiding(f, x, y, z) <==> Between(f, x, y, z) || (Between(f, x, y, y) && !Between(f, x, z, z)));
68-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, x: Option K, y: Option K, z: Option K ::
69+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, x: Option (Loc (Node T)), y: Option (Loc (Node T)), z: Option (Loc (Node T)) ::
6970
{Between(f, x, y, z)}
7071
Between(f, x, y, z) <==> Avoiding(f, x, y, z) && Avoiding(f, x, z, z));
7172

7273
// update
73-
axiom {:ctor "Node"} (forall<K,T> f: [K]Node K T, u: Option K, v: Option K, x: Option K, p: K, q: Node K T ::
74+
axiom {:ctor "Node"} (forall<T> f: [Loc (Node T)]Node T, u: Option (Loc (Node T)), v: Option (Loc (Node T)), x: Option (Loc (Node T)), p: Loc (Node T), q: Node T ::
7475
{Avoiding(f[p := q], u, v, x)}
7576
Avoiding(f[p := q], u, v, x) <==>
7677
(Avoiding(f, u, v, Some(p)) && Avoiding(f, u, v, x)) ||

Test/civl/large-samples/GC.bpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (c) Microsoft Corporation. All rights reserved.
33
//
44

5-
// RUN: %parallel-boogie -lib:set_size "%s" > "%t"
5+
// RUN: %parallel-boogie -lib:set_size -timeLimit:0 -vcsSplitOnEveryAssert "%s" > "%t"
66
// RUN: %diff "%s.expect" "%t"
77

88
// Tid(i, ps) represents a linear thread id for thread number i, where i > 0 and ps = {Left(i), Right(i)}.

Test/civl/large-samples/cache-coherence.bpl

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -623,43 +623,50 @@ preserves call YieldInv#2();
623623
requires call YieldRead(i, ma, drp);
624624
{
625625
var dirState: DirState;
626-
var value: Value;
627626
var {:linear} {:layer 1,2} dp: Set DirPermission;
628-
var {:linear} {:layer 1,2} dpOne: Set DirPermission;
629-
var victims: Set CacheId;
630-
var victim: CacheId;
631-
var {:layer 2} cache_s: [CacheId][CacheAddr]CacheLine;
627+
var value: Value;
632628

633629
par dirState, dp := dir_req_begin(ma) | YieldInv#1();
634630
if (dirState is Owner) {
635631
par value := cache_invalidate_exc#1(dirState->i, ma, Invalid(), dp) | YieldInv#1();
636632
par write_mem(ma, value, dp) | YieldInv#1();
637633
} else {
638-
call {:layer 2} cache_s := Copy(cache);
639-
victims := dirState->iset;
640-
while (victims != Set_Empty())
641-
invariant {:yields} {:layer 1} true;
642-
invariant {:layer 1} call YieldInv#1();
643-
invariant {:layer 2} dp == WholeDirPermission(ma);
644-
invariant {:layer 2} Set_IsSubset(victims, dirState->iset);
645-
invariant {:layer 2} (forall i: CacheId:: Set_Contains(dirState->iset, i) || cache[i] == cache_s[i]);
646-
invariant {:layer 2} (forall i: CacheId:: Set_Contains(dirState->iset, i) ==>
647-
if Set_Contains(victims, i)
648-
then cache[i] == cache_s[i]
649-
else cache[i] == cache_s[i][Hash(ma) := CacheLine(ma, cache_s[i][Hash(ma)]->value, Invalid())]);
650-
{
651-
victim := Choice(victims->val);
652-
victims := Set_Remove(victims, victim);
653-
par dpOne, dp := get_victim(victim, ma, dp) | YieldInv#1();
654-
par cache_invalidate_shd#1(victim, ma, Invalid(), dpOne) | YieldInv#1();
655-
par dp := put_victim(dpOne, dp) | YieldInv#1();
656-
}
634+
par dp := invalidate_sharers(ma, dirState->iset, dp) | YieldInv#1();
657635
par value := read_mem(ma, dp) | YieldInv#1();
658636
}
659637
call cache_read_resp#1(i, ma, value, Exclusive(), drp, dp);
660638
par dir_req_end(ma, Owner(i), dp) | YieldInv#1();
661639
}
662640

641+
yield left procedure {:layer 2} invalidate_sharers(ma: MemAddr, victims: Set CacheId, {:linear_in} {:layer 1,2} dp: Set DirPermission)
642+
returns ({:linear} {:layer 1,2} dp': Set DirPermission)
643+
modifies cache;
644+
requires {:layer 2} Set_IsSubset(Set((lambda x: DirPermission :: Set_Contains(victims, x->i) && x->ma == ma)), dp);
645+
requires {:layer 2} (forall i: CacheId, ca: CacheAddr:: (var line := cache[i][ca];
646+
line->state == Invalid() ||
647+
(line->value == absMem[line->ma] && if line->state == Shared() then dir[line->ma] is Sharers else dir[line->ma] is Owner)));
648+
requires {:layer 2} (forall i: CacheId:: Set_Contains(victims, i) ==> cache[i][Hash(ma)]->state == Shared() && cache[i][Hash(ma)]->ma == ma);
649+
ensures {:layer 2} (forall i: CacheId:: Set_Contains(victims, i) ==>
650+
cache[i] == old(cache)[i][Hash(ma) := CacheLine(ma, old(cache)[i][Hash(ma)]->value, Invalid())]);
651+
ensures {:layer 2} (forall i: CacheId:: Set_Contains(victims, i) || cache[i] == old(cache)[i]);
652+
ensures {:layer 2} dp == dp';
653+
{
654+
var victim: CacheId;
655+
var victims': Set CacheId;
656+
var {:linear} {:layer 1,2} dpOne: Set DirPermission;
657+
658+
dp' := dp;
659+
if (victims == Set_Empty())
660+
{
661+
return;
662+
}
663+
victim := Choice(victims->val);
664+
victims' := Set_Remove(victims, victim);
665+
par dpOne, dp' := get_victim(victim, ma, dp');
666+
par cache_invalidate_shd#1(victim, ma, Invalid(), dpOne) | dp' := invalidate_sharers(ma, victims', dp');
667+
par dp' := put_victim(dpOne, dp');
668+
}
669+
663670
yield procedure {:layer 1} get_victim(victim: CacheId, ma: MemAddr, {:layer 1} {:linear_in} dp: Set DirPermission)
664671
returns ({:linear} {:layer 1} dpOne: Set DirPermission, {:linear} {:layer 1} dp': Set DirPermission)
665672
refines both action {:layer 2} _ {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11

2-
Boogie program verifier finished with 91 verified, 0 errors
2+
Boogie program verifier finished with 93 verified, 0 errors

0 commit comments

Comments
 (0)