@@ -436,4 +436,37 @@ let expand_all_aliases (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (ghost
436436 done;
437437 !cur
438438
439+ let demonstration (items: seq (spec 'tag 'a)) (table: seq (def 'a)) (pred: 'a -> bool)
440+ (* make sure the keys are uniquely defined *)
441+ requires { forall i j. 0 <= i < j < length table ->
442+ let (k1, _) = table[i] in
443+ let (k2, _) = table[j] in
444+ k1 <> k2 }
445+
446+ (* require all aliases to be defined in the table *)
447+ requires { forall i. 0 <= i < length items ->
448+ forall key. who items[i] = Alias key ->
449+ exists j. 0 <= j < length table /\ let (id, _) = table[j] in id = key }
450+
451+ (* make sure the table is topologically sorted *)
452+ requires { forall i j. 0 <= i <= j < length table ->
453+ let (_, items) = table[i] in
454+ let (key, _) = table[j] in
455+ forall k. 0 <= k < length items -> who items[k] <> Alias key }
456+
457+ (* this function also requires that it is grounded *)
458+ requires { forall i. 0 <= i < length table ->
459+ let (_, items) = table[i] in
460+ forall k, key. 0 <= k < length items -> who items[k] = Alias key ->
461+ exists j. 0 <= j < length table /\ let (id, _) = table[j] in id = key }
462+
463+ = let aliases = get_aliases table pred in
464+
465+ let expanded = expand_all_aliases items table (ghost pred) (ghost aliases) in
466+
467+ let a = find_item expanded pred (any found_aliases) in
468+ let b = find_item items pred aliases in
469+
470+ assert { a = b }
471+
439472end
0 commit comments