@@ -223,6 +223,34 @@ 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 tab2 tab1 }
238+ requires { forall i j. 0 <= i < j < length tab2 -> tab2[i] <> tab2[j] }
239+ ensures { weak_permut_all tab1 tab2 }
240+ ensures { forall i j. 0 <= i < j < length tab1 -> tab1[i] <> tab1[j] }
241+ = let tab = ref tab1 in
242+ for i = 0 to length tab1 - 1 do
243+ invariant { length !tab >= length tab1 }
244+ invariant { weak_permut_all tab2 !tab}
245+ invariant { forall i. 0 <= i < length tab1 -> exists j. 0 <= j < length !tab /\ tab1[i] = (!tab)[j] }
246+ invariant { (exists i j. 0 <= i < j < length tab1 /\ tab1[i] = tab1[j]) -> exists i j. 0 <= i < j < length !tab /\ (!tab)[i] = (!tab)[j] }
247+ invariant { forall j. 0 <= j < i -> (!tab)[j] = tab2[j] }
248+ let j = any int ensures { i <= result < length tab2 /\ tab2[i] = (!tab)[result] } in
249+ tab := (!tab)[i <- !(tab)[j]][j <- (!tab)[i]];
250+ done
251+
252+ end
253+
226254module Expansion
227255
228256use int.Int
@@ -361,10 +389,7 @@ let expand_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost pred
361389 assert { items[0.. length items] = items };
362390 !expanded
363391
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])
392+ use WeakPermut
368393
369394let 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)
370395 (* make sure the keys are uniquely defined *)
@@ -438,27 +463,12 @@ module Correctness
438463
439464use int.Int
440465use option.Option
441- use ref.Ref
442466use seq.Seq
443467
444468use FindItem
445469use AliasTable
446470use 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
471+ use WeakPermut
462472
463473let demonstration (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (pred: 'a -> bool) (sorted_table: seq (def 'a))
464474 (* make sure the keys are uniquely defined *)
@@ -476,7 +486,7 @@ let demonstration (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (pred: 'a ->
476486 exists j. 0 <= j < length table /\ let (id, _) = table[j] in id = key }
477487
478488 (* make sure the table can be topologically sorted *)
479- requires { weak_permut_all sorted_table table }
489+ requires { weak_permut_all table sorted_table }
480490
481491 requires { forall i j. 0 <= i <= j < length sorted_table ->
482492 let (_, items) = sorted_table[i] in
0 commit comments