Skip to content

Commit e26f827

Browse files
committed
QED
1 parent 8cc9b00 commit e26f827

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

proofs/sudoers.mlw

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ let expand_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost pred
269269
(exists k j. 0 <= k < length table /\ let (_, def) = table[k] in 0 <= j < length def /\ who result[i] = who def[j]) \/
270270
(exists j. 0 <= j < length items /\ who result[i] = who items[j]) }
271271

272+
(* no aliases will remain that refer to the last row in the table *)
273+
ensures { forall i. 0 <= i < length result ->
274+
forall key. who result[i] = Alias key -> length table > 0 -> let (id, _) = table[length table-1] in id <> key }
275+
272276
(* the alias table encodes the membership of an identifier in an alias and its status;
273277
i.e. it has been produced by get_aliases above *)
274278
requires { let matched = matched_by aliases pred in
@@ -309,11 +313,13 @@ let expand_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost pred
309313

310314
let expanded = ref empty in
311315
for i = 0 to length items - 1 do
312-
(* this invariant expresses a limited 'provenance' of the resulting list; we only care about Alias-provenance, but this is easier to reason about *)
313316
invariant { forall i. 0 <= i < length !expanded ->
314317
(exists k j. 0 <= k < length table /\ let (_, def) = table[k] in 0 <= j < length def /\ who (!expanded)[i] = who def[j]) \/
315318
(exists j. 0 <= j < length items /\ who (!expanded)[i] = who items[j]) }
316319

320+
invariant { forall i. 0 <= i < length !expanded ->
321+
forall key. who (!expanded)[i] = Alias key -> length table > 0 -> let (id, _) = table[length table-1] in id <> key }
322+
317323
invariant {
318324
let matched = matched_by aliases pred in
319325
let condition = condition aliases in
@@ -410,7 +416,7 @@ let expand_all_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost
410416
}
411417

412418
= let cur = ref items in
413-
while any bool ensures { result <-> exists i, key. 0 <= i < length !cur /\ who (!cur)[i] = Alias key } do
419+
for maxrow = table.length downto 1 do
414420
invariant {
415421
let matched = matched_by aliases pred in
416422
let condition = condition aliases in
@@ -422,9 +428,11 @@ let expand_all_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost
422428

423429
invariant { forall i. 0 <= i < length !cur ->
424430
forall key. who (!cur)[i] = Alias key ->
425-
exists j. 0 <= j < length table /\ let (id, _) = table[j] in id = key }
431+
exists j. 0 <= j < maxrow /\ let (id, _) = table[j] in id = key }
432+
433+
assert { forall j. 0 <= j < maxrow -> table[..maxrow][j] = table[j] };
426434

427-
cur := expand_aliases !cur table pred aliases
435+
cur := expand_aliases !cur table[..maxrow] pred aliases;
428436
done;
429437
!cur
430438

0 commit comments

Comments
 (0)