@@ -223,6 +223,33 @@ let get_aliases (table: seq (def 'a)) (pred: 'a -> bool): found_aliases
223223
224224end
225225
226+ module WeakPermut
227+
228+ use seq.Seq
229+ use int.Int
230+ use ref.Ref
231+
232+ predicate weak_permut_all (x y: seq 'a)
233+ = length x = length y /\
234+ (forall i. 0 <= i < length x -> exists j. 0 <= j < length y /\ x[i] = y[j])
235+
236+ let lemma permut_commutes (tab1 tab2: seq 'a)
237+ requires { weak_permut_all tab1 tab2 }
238+ requires { forall i j. 0 <= i < j < length tab1 -> tab1[i] <> tab1[j] }
239+ ensures { weak_permut_all tab2 tab1 }
240+ ensures { forall i j. 0 <= i < j < length tab2 -> tab2[i] <> tab2[j] }
241+ = let tab = ref tab2 in
242+ for i = 0 to length tab2 - 1 do
243+ invariant { weak_permut_all tab1 !tab}
244+ invariant { forall i. 0 <= i < length tab2 -> exists j. 0 <= j < length !tab /\ tab2[i] = (!tab)[j] }
245+ invariant { (exists i j. 0 <= i < j < length tab2 /\ tab2[i] = tab2[j]) -> exists i j. 0 <= i < j < length !tab /\ (!tab)[i] = (!tab)[j] }
246+ invariant { forall j. 0 <= j < i -> (!tab)[j] = tab1[j] }
247+ let j = any int ensures { i <= result < length tab1 /\ tab1[i] = (!tab)[result] } in
248+ tab := (!tab)[i <- !(tab)[j]][j <- (!tab)[i]];
249+ done
250+
251+ end
252+
226253module Expansion
227254
228255use int.Int
@@ -361,10 +388,7 @@ let expand_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost pred
361388 assert { items[0.. length items] = items };
362389 !expanded
363390
364- predicate weak_permut_all (x y: seq 'a)
365- = length x = length y /\
366- (forall i. 0 <= i < length x -> exists j. 0 <= j < length y /\ x[i] = y[j]) /\
367- (forall i. 0 <= i < length y -> exists j. 0 <= j < length x /\ x[j] = y[i])
391+ use WeakPermut
368392
369393let expand_all_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost pred: 'a -> bool) (ghost aliases: found_aliases) (ghost sorted_table: seq (def 'a)): seq (spec 'tag 'a)
370394 (* make sure the keys are uniquely defined *)
@@ -438,27 +462,12 @@ module Correctness
438462
439463use int.Int
440464use option.Option
441- use ref.Ref
442465use seq.Seq
443466
444467use FindItem
445468use AliasTable
446469use Expansion
447-
448- let lemma permut_preserves_uniqueness (tab1 tab2: seq 'a) (i j: int)
449- requires { weak_permut_all tab1 tab2 }
450- requires { 0 <= i < j < length tab1 }
451- requires { tab1[i] = tab1[j] }
452- requires { forall i j. 0 <= i < j < length tab2 -> tab2[i] <> tab2[j] }
453- ensures { false }
454- = let tab = ref tab1 in
455- for i = 0 to length tab1 - 1 do
456- invariant { weak_permut_all !tab tab2 }
457- invariant { exists i j. 0 <= i < j < length !tab /\ (!tab)[i] = (!tab)[j] }
458- invariant { forall j. 0 <= j < i -> (!tab)[j] = tab2[j] }
459- let j = any int ensures { i <= result < length tab2 /\ tab2[i] = (!tab)[result] } in
460- tab := (!tab)[i <- !(tab)[j]][j <- (!tab)[i]];
461- done
470+ use WeakPermut
462471
463472let demonstration (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (pred: 'a -> bool) (sorted_table: seq (def 'a))
464473 (* make sure the keys are uniquely defined *)
@@ -476,7 +485,7 @@ let demonstration (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (pred: 'a ->
476485 exists j. 0 <= j < length table /\ let (id, _) = table[j] in id = key }
477486
478487 (* make sure the table can be topologically sorted *)
479- requires { weak_permut_all sorted_table table }
488+ requires { weak_permut_all table sorted_table }
480489
481490 requires { forall i j. 0 <= i <= j < length sorted_table ->
482491 let (_, items) = sorted_table[i] in
0 commit comments