Skip to content

Commit 382ab50

Browse files
committed
QED
1 parent 8cc9b00 commit 382ab50

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

proofs/sudoers.mlw

Lines changed: 13 additions & 5 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
@@ -397,7 +403,7 @@ let expand_all_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost
397403
(H.mem id aliases -> H.find id aliases <-> condition (final_match matched specs) = Some ()) }
398404

399405
(* ther result does not have macro's left that *)
400-
ensures { not exists i, key. 0 <= i < length result /\ who result[i] = Alias key}
406+
ensures { not exists i, key. 0 <= i < length result /\ who result[i] = Alias key }
401407

402408
(* the primary result *)
403409
ensures {
@@ -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)