@@ -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