From 4dae91b44b8d6078aab7cb9f998d672d512989b5 Mon Sep 17 00:00:00 2001 From: arnaudgolfouse Date: Thu, 16 Jan 2025 15:29:03 +0100 Subject: [PATCH] Union-Find example --- creusot/tests/should_succeed/union_find.coma | 7361 +++++++++++++++++ creusot/tests/should_succeed/union_find.rs | 425 + .../should_succeed/union_find/why3session.xml | 1372 +++ .../should_succeed/union_find/why3shapes.gz | Bin 0 -> 22652 bytes 4 files changed, 9158 insertions(+) create mode 100644 creusot/tests/should_succeed/union_find.coma create mode 100644 creusot/tests/should_succeed/union_find.rs create mode 100644 creusot/tests/should_succeed/union_find/why3session.xml create mode 100644 creusot/tests/should_succeed/union_find/why3shapes.gz diff --git a/creusot/tests/should_succeed/union_find.coma b/creusot/tests/should_succeed/union_find.coma new file mode 100644 index 000000000..ca4200d7b --- /dev/null +++ b/creusot/tests/should_succeed/union_find.coma @@ -0,0 +1,7361 @@ +module M_union_find__implementation__qyi5509895616124734008__eq [#"union_find.rs" 15 8 15 42] (* as creusot_contracts::PartialEq> *) + let%span sunion_find0 = "union_find.rs" 14 18 14 69 + let%span sptr1 = "../../../creusot-contracts/src/std/ptr.rs" 131 22 131 66 + let%span smodel2 = "../../../creusot-contracts/src/model.rs" 83 8 83 28 + let%span sunion_find3 = "union_find.rs" 21 8 21 16 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use prelude.prelude.Int + + function addr_logic'0 (self : opaque_ptr) : int + + let rec addr_eq'0 (p:opaque_ptr) (q:opaque_ptr) (return' (ret:bool))= any + [ return' (result:bool)-> {[%#sptr1] result = (addr_logic'0 p = addr_logic'0 q)} (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + use prelude.prelude.Borrow + + function deep_model'1 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find3] addr_logic'0 self.t_Element__0'0 + + function deep_model'0 (self : t_Element'0) : int = + [%#smodel2] deep_model'1 self + + meta "compute_max_steps" 1000000 + + let rec eq'0 (self:t_Element'0) (other:t_Element'0) (return' (ret:bool))= (! bb0 + [ bb0 = s0 + [ s0 = addr_eq'0 {self.t_Element__0'0} {other.t_Element__0'0} (fun (_ret':bool) -> [ &_0 <- _ret' ] s1) + | s1 = bb1 ] + + | bb1 = return' {_0} ] + ) [ & _0 : bool = any_l () | & self : t_Element'0 = self | & other : t_Element'0 = other ] + [ return' (result:bool)-> {[@expl:eq ensures] [%#sunion_find0] result = (deep_model'0 self = deep_model'0 other)} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi12240134006530516816__addr [#"union_find.rs" 31 8 31 38] (* implementation::Element *) + let%span sunion_find0 = "union_find.rs" 32 12 32 40 + let%span sunion_find1 = "union_find.rs" 30 18 30 46 + let%span sunion_find2 = "union_find.rs" 21 8 21 16 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use prelude.prelude.Int + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find2] addr_logic'0 self.t_Element__0'0 + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use prelude.prelude.Intrinsic + + use prelude.prelude.Snapshot + + meta "compute_max_steps" 1000000 + + let rec addr'0 (self:t_Element'0) (return' (ret:Snapshot.snap_ty int))= (! bb0 + [ bb0 = s0 [ s0 = [ &_0 <- [%#sunion_find0] Snapshot.new (deep_model'0 self) ] s1 | s1 = bb1 ] + | bb1 = return' {_0} ] + ) [ & _0 : Snapshot.snap_ty int = any_l () | & self : t_Element'0 = self ] + [ return' (result:Snapshot.snap_ty int)-> {[@expl:addr ensures] [%#sunion_find1] Snapshot.inner result + = deep_model'0 self} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi6778176538984101299__clone [#"union_find.rs" 44 8 44 31] (* as creusot_contracts::Clone> *) + let%span sunion_find0 = "union_find.rs" 42 18 42 33 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use prelude.prelude.Intrinsic + + use prelude.prelude.Borrow + + meta "compute_max_steps" 1000000 + + let rec clone'0 (self:t_Element'0) (return' (ret:t_Element'0))= (! bb0 + [ bb0 = s0 [ s0 = [ &_0 <- { t_Element__0'0 = self.t_Element__0'0 } ] s1 | s1 = return' {_0} ] ] + ) [ & _0 : t_Element'0 = any_l () | & self : t_Element'0 = self ] + [ return' (result:t_Element'0)-> {[@expl:clone ensures] [%#sunion_find0] self = result} (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__new [#"union_find.rs" 114 8 114 28] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 116 24 116 46 + let%span sunion_find1 = "union_find.rs" 117 21 117 32 + let%span sunion_find2 = "union_find.rs" 118 24 118 54 + let%span sunion_find3 = "union_find.rs" 119 26 119 56 + let%span sunion_find4 = "union_find.rs" 120 25 120 55 + let%span sunion_find5 = "union_find.rs" 121 27 121 39 + let%span sunion_find6 = "union_find.rs" 114 24 114 28 + let%span sunion_find7 = "union_find.rs" 113 8 113 44 + let%span sfmap8 = "../../../creusot-contracts/src/logic/fmap.rs" 239 4 239 34 + let%span sfmap9 = "../../../creusot-contracts/src/logic/fmap.rs" 237 14 237 31 + let%span sutil10 = "../../../creusot-contracts/src/util.rs" 33 11 33 28 + let%span sutil11 = "../../../creusot-contracts/src/util.rs" 34 0 34 21 + let%span sghost12 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap13 = "../../../creusot-contracts/src/logic/fmap.rs" 139 8 139 34 + let%span smapping14 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sfmap15 = "../../../creusot-contracts/src/logic/fmap.rs" 39 14 39 31 + let%span sfmap16 = "../../../creusot-contracts/src/logic/fmap.rs" 40 14 40 49 + let%span sfmap17 = "../../../creusot-contracts/src/logic/fmap.rs" 214 14 214 38 + let%span sfmap18 = "../../../creusot-contracts/src/logic/fmap.rs" 215 14 215 83 + let%span sfmap19 = "../../../creusot-contracts/src/logic/fmap.rs" 217 8 217 35 + let%span sunion_find20 = "union_find.rs" 80 8 80 20 + let%span sfmap21 = "../../../creusot-contracts/src/logic/fmap.rs" 48 14 48 25 + let%span sfmap22 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap23 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfset24 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find25 = "union_find.rs" 21 8 21 16 + let%span sfmap26 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find27 = "union_find.rs" 125 8 125 16 + let%span sfmap28 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sboxed29 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sfmap30 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap31 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sutil32 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil33 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap34 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own35 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr36 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr37 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use set.Fset + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + use prelude.prelude.Int + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap22] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap23] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap26] get_unsized'0 self k <> C_None'0 + + predicate inv'4 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'4 [@rewrite] : forall x : Snapshot.snap_ty int [inv'4 x] . inv'4 x = true + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil32] op <> C_None'0) + -> ([%#sutil33] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap31] unwrap'0 (get_unsized'0 self k) + + use prelude.prelude.Borrow + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + function addr_logic'0 (self : opaque_ptr) : int + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr37] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr36] is_null_logic'0 self = (addr_logic'0 self = 0) + + use prelude.prelude.UIntSize + + type t_T'0 + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + predicate inv'9 (_1 : t_T'0) + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x + = match x with + | C_Root'0 rank value -> inv'9 value + | C_Link'0 a_0 -> true + end + + predicate invariant'5 (self : t_Content'0) = + [%#sboxed29] inv'8 self + + predicate inv'7 (_1 : t_Content'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_Content'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sptr_own35] not is_null_logic'0 (ptr'0 self) /\ inv'7 (val'0 self) + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_PtrOwn'0) = + [%#sboxed29] inv'6 self + + predicate inv'5 (_1 : t_PtrOwn'0) + + axiom inv_axiom'5 [@rewrite] : forall x : t_PtrOwn'0 [inv'5 x] . inv'5 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sfmap34] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'4 k /\ inv'5 (lookup_unsized'0 self k) + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate invariant'1 (self : t_FMap'0) = + [%#sboxed29] inv'3 self + + predicate inv'2 (_1 : t_FMap'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_FMap'0 [inv'2 x] . inv'2 x = invariant'1 x + + predicate inv'1 (_1 : t_GhostBox'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_GhostBox'0 [inv'1 x] . inv'1 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'2 a_0 + end + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost12] self.t_GhostBox__0'0 + + function len'0 (self : t_FMap'0) : int + + axiom len'0_spec : forall self : t_FMap'0 . [%#sfmap21] len'0 self >= 0 + + use map.Const + + function empty'0 (_1 : ()) : t_FMap'0 + + axiom empty'0_spec : forall _1 : () . ([%#sfmap15] len'0 (empty'0 _1) = 0) + && ([%#sfmap16] view'0 (empty'0 _1) = Const.const (C_None'0)) + + function ext_eq'0 (self : t_FMap'0) (other : t_FMap'0) : bool = + [%#sfmap19] view'0 self = view'0 other + + axiom ext_eq'0_spec : forall self : t_FMap'0, other : t_FMap'0 . ([%#sfmap17] ext_eq'0 self other -> self = other) + && ([%#sfmap18] (forall k : Snapshot.snap_ty int . get_unsized'0 self k = get_unsized'0 other k) + -> ext_eq'0 self other) + + function is_empty'0 (self : t_FMap'0) : bool = + [%#sfmap13] ext_eq'0 self (empty'0 ()) + + let rec new'1 (_1:()) (return' (ret:t_GhostBox'0))= any + [ return' (result:t_GhostBox'0)-> {[%#sfmap8] inv'1 result} + {[%#sfmap9] is_empty'0 (inner_logic'0 result)} + (! return' {result}) ] + + + use map.Map + + use prelude.prelude.Mapping + + use map.Map + + use map.Map + + function index_logic'0 (self : Map.map (Map.map (t_Element'0) t_T'0) bool) (a : Map.map (t_Element'0) t_T'0) : bool = + [%#smapping14] Map.get self a + + function such_that'0 (p : Map.map (Map.map (t_Element'0) t_T'0) bool) : Map.map (t_Element'0) t_T'0 + + axiom such_that'0_spec : forall p : Map.map (Map.map (t_Element'0) t_T'0) bool . ([%#sutil10] exists x : Map.map (t_Element'0) t_T'0 . index_logic'0 p x) + -> ([%#sutil11] index_logic'0 p (such_that'0 p)) + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Mapping + + use map.Map + + use map.Map + + function index_logic'1 (self : Map.map (Map.map (t_Element'0) int) bool) (a : Map.map (t_Element'0) int) : bool = + [%#smapping14] Map.get self a + + function such_that'1 (p : Map.map (Map.map (t_Element'0) int) bool) : Map.map (t_Element'0) int + + axiom such_that'1_spec : forall p : Map.map (Map.map (t_Element'0) int) bool . ([%#sutil10] exists x : Map.map (t_Element'0) int . index_logic'1 p x) + -> ([%#sutil11] index_logic'1 p (such_that'1 p)) + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Mapping + + use map.Map + + use map.Map + + function index_logic'2 (self : Map.map (Map.map (t_Element'0) (t_Element'0)) bool) (a : Map.map (t_Element'0) (t_Element'0)) : bool + + = + [%#smapping14] Map.get self a + + function such_that'2 (p : Map.map (Map.map (t_Element'0) (t_Element'0)) bool) : Map.map (t_Element'0) (t_Element'0) + + axiom such_that'2_spec : forall p : Map.map (Map.map (t_Element'0) (t_Element'0)) bool . ([%#sutil10] exists x : Map.map (t_Element'0) (t_Element'0) . index_logic'2 p x) + -> ([%#sutil11] index_logic'2 p (such_that'2 p)) + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Intrinsic + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset24] Fset.mem e self + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find25] addr_logic'0 self.t_Element__0'0 + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap30] lookup_unsized'0 self k + + function index_logic'6 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap28] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find27] index_logic'6 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'3 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping14] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'4 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping14] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'5 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping14] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find20] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'3 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'3 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'3 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'5 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'5 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'5 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'5 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'4 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'1 map + end) + + use set.Fset + + meta "compute_max_steps" 1000000 + + let rec new'0 (_1:()) (return' (ret:t_UnionFind'0))= (! bb0 + [ bb0 = s0 [ s0 = [ &_2 <- [%#sunion_find0] Snapshot.new (Fset.empty : Fset.fset (t_Element'0)) ] s1 | s1 = bb1 ] + | bb1 = s0 [ s0 = new'1 {[%#sunion_find1] ()} (fun (_ret':t_GhostBox'0) -> [ &_4 <- _ret' ] s1) | s1 = bb2 ] + | bb2 = s0 + [ s0 = + [ &_5 <- [%#sunion_find2] Snapshot.new (such_that'0 (Mapping.from_fn (fun (_2 : Map.map (t_Element'0) t_T'0) -> true))) ] + + s1 + | s1 = bb3 ] + + | bb3 = s0 + [ s0 = + [ &_7 <- [%#sunion_find3] Snapshot.new (such_that'1 (Mapping.from_fn (fun (_2 : Map.map (t_Element'0) int) -> true))) ] + + s1 + | s1 = bb4 ] + + | bb4 = s0 + [ s0 = + [ &_9 <- [%#sunion_find4] Snapshot.new (such_that'2 (Mapping.from_fn (fun (_2 : Map.map (t_Element'0) (t_Element'0)) -> true))) ] + + s1 + | s1 = bb5 ] + + | bb5 = s0 [ s0 = [ &_11 <- [%#sunion_find5] Snapshot.new 0 ] s1 | s1 = bb6 ] + | bb6 = s0 + [ s0 = + [ &_0 <- { t_UnionFind__domain'0 = _2; + t_UnionFind__map'0 = _4; + t_UnionFind__values'0 = _5; + t_UnionFind__distance'0 = _7; + t_UnionFind__root_of'0 = _9; + t_UnionFind__max_depth'0 = _11 } ] + + s1 + | s1 = bb7 ] + + | bb7 = return' {_0} ] + ) + [ & _0 : t_UnionFind'0 = any_l () + | & _2 : Snapshot.snap_ty (Fset.fset (t_Element'0)) = any_l () + | & _4 : t_GhostBox'0 = any_l () + | & _5 : Snapshot.snap_ty (Map.map (t_Element'0) t_T'0) = any_l () + | & _7 : Snapshot.snap_ty (Map.map (t_Element'0) int) = any_l () + | & _9 : Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)) = any_l () + | & _11 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_UnionFind'0)-> {[@expl:new result type invariant] [%#sunion_find6] inv'0 result} + {[@expl:new ensures] [%#sunion_find7] Fset.is_empty (Snapshot.inner result.t_UnionFind__domain'0)} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__domain [#"union_find.rs" 135 8 135 47] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 133 19 133 28 + let%span sunion_find1 = "union_find.rs" 134 18 134 150 + let%span sunion_find2 = "union_find.rs" 131 8 131 16 + let%span sfset3 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find4 = "union_find.rs" 21 8 21 16 + let%span sunion_find5 = "union_find.rs" 80 8 80 20 + let%span sghost6 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap7 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find8 = "union_find.rs" 125 8 125 16 + let%span smapping9 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sfmap10 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap11 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap12 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap13 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap14 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed15 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil16 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil17 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap18 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own19 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr20 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr21 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset3] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find4] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost6] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap12] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap10] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap7] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil16] op <> C_None'0) + -> ([%#sutil17] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap14] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap13] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap11] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find8] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use prelude.prelude.Borrow + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping9] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping9] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping9] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find5] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'0 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'4 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'4 [@rewrite] : forall x : Snapshot.snap_ty int [inv'4 x] . inv'4 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr21] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr20] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'9 (_1 : t_T'0) + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x + = match x with + | C_Root'0 rank value -> inv'9 value + | C_Link'0 a_0 -> true + end + + predicate invariant'5 (self : t_Content'0) = + [%#sboxed15] inv'8 self + + predicate inv'7 (_1 : t_Content'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_Content'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sptr_own19] not is_null_logic'0 (ptr'0 self) /\ inv'7 (val'0 self) + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_PtrOwn'0) = + [%#sboxed15] inv'6 self + + predicate inv'5 (_1 : t_PtrOwn'0) + + axiom inv_axiom'5 [@rewrite] : forall x : t_PtrOwn'0 [inv'5 x] . inv'5 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sfmap18] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'4 k /\ inv'5 (lookup_unsized'0 self k) + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate invariant'1 (self : t_FMap'0) = + [%#sboxed15] inv'3 self + + predicate inv'2 (_1 : t_FMap'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_FMap'0 [inv'2 x] . inv'2 x = invariant'1 x + + predicate inv'1 (_1 : t_GhostBox'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_GhostBox'0 [inv'1 x] . inv'1 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'2 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'1 map + end) + + constant self : t_UnionFind'0 + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) + + goal vc_domain'0 : ([%#sunion_find0] inv'0 self) + -> (let result = Snapshot.inner self.t_UnionFind__domain'0 in [%#sunion_find1] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 result e1 + /\ contains'0 result e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) +end +module M_union_find__implementation__qyi16869121482064879694__root_of [#"union_find.rs" 147 8 147 63] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 145 19 145 28 + let%span sunion_find1 = "union_find.rs" 146 18 146 98 + let%span sunion_find2 = "union_find.rs" 143 8 143 16 + let%span sfset3 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span smapping4 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find5 = "union_find.rs" 80 8 80 20 + let%span sunion_find6 = "union_find.rs" 21 8 21 16 + let%span sghost7 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap8 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find9 = "union_find.rs" 125 8 125 16 + let%span sfmap10 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap11 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap12 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap13 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap14 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed15 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil16 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil17 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap18 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own19 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr20 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr21 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset3] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find6] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost7] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap12] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap10] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap8] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil16] op <> C_None'0) + -> ([%#sutil17] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap14] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap13] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap11] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find9] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use prelude.prelude.Borrow + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping4] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping4] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping4] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find5] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'4 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'4 [@rewrite] : forall x : Snapshot.snap_ty int [inv'4 x] . inv'4 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr21] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr20] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'9 (_1 : t_T'0) + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x + = match x with + | C_Root'0 rank value -> inv'9 value + | C_Link'0 a_0 -> true + end + + predicate invariant'5 (self : t_Content'0) = + [%#sboxed15] inv'8 self + + predicate inv'7 (_1 : t_Content'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_Content'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sptr_own19] not is_null_logic'0 (ptr'0 self) /\ inv'7 (val'0 self) + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_PtrOwn'0) = + [%#sboxed15] inv'6 self + + predicate inv'5 (_1 : t_PtrOwn'0) + + axiom inv_axiom'5 [@rewrite] : forall x : t_PtrOwn'0 [inv'5 x] . inv'5 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sfmap18] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'4 k /\ inv'5 (lookup_unsized'0 self k) + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate invariant'1 (self : t_FMap'0) = + [%#sboxed15] inv'3 self + + predicate inv'2 (_1 : t_FMap'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_FMap'0 [inv'2 x] . inv'2 x = invariant'1 x + + predicate inv'1 (_1 : t_GhostBox'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_GhostBox'0 [inv'1 x] . inv'1 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'2 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'1 map + end) + + constant self : t_UnionFind'0 + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) + + goal vc_root_of'0 : ([%#sunion_find0] inv'0 self) + -> (let result = Snapshot.inner self.t_UnionFind__root_of'0 in [%#sunion_find1] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 result e = index_logic'0 result (index_logic'0 result e)) +end +module M_union_find__implementation__qyi16869121482064879694__values [#"union_find.rs" 156 8 156 53] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 154 19 154 28 + let%span sunion_find1 = "union_find.rs" 155 18 155 106 + let%span sunion_find2 = "union_find.rs" 152 8 152 16 + let%span sfset3 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span smapping4 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find5 = "union_find.rs" 145 19 145 28 + let%span sunion_find6 = "union_find.rs" 146 18 146 98 + let%span sunion_find7 = "union_find.rs" 143 8 143 16 + let%span sunion_find8 = "union_find.rs" 80 8 80 20 + let%span sunion_find9 = "union_find.rs" 21 8 21 16 + let%span sghost10 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap11 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find12 = "union_find.rs" 125 8 125 16 + let%span sfmap13 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap14 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap15 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap16 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap17 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed18 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil19 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil20 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap21 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own22 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr23 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr24 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset3] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find9] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost10] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap15] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap13] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap11] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil19] op <> C_None'0) + -> ([%#sutil20] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap17] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap16] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap14] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find12] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use prelude.prelude.Borrow + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping4] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping4] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping4] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find8] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'0 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'1 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'4 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'4 [@rewrite] : forall x : Snapshot.snap_ty int [inv'4 x] . inv'4 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr24] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr23] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'9 (_1 : t_T'0) + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x + = match x with + | C_Root'0 rank value -> inv'9 value + | C_Link'0 a_0 -> true + end + + predicate invariant'5 (self : t_Content'0) = + [%#sboxed18] inv'8 self + + predicate inv'7 (_1 : t_Content'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_Content'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sptr_own22] not is_null_logic'0 (ptr'0 self) /\ inv'7 (val'0 self) + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_PtrOwn'0) = + [%#sboxed18] inv'6 self + + predicate inv'5 (_1 : t_PtrOwn'0) + + axiom inv_axiom'5 [@rewrite] : forall x : t_PtrOwn'0 [inv'5 x] . inv'5 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sfmap21] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'4 k /\ inv'5 (lookup_unsized'0 self k) + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate invariant'1 (self : t_FMap'0) = + [%#sboxed18] inv'3 self + + predicate inv'2 (_1 : t_FMap'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_FMap'0 [inv'2 x] . inv'2 x = invariant'1 x + + predicate inv'1 (_1 : t_GhostBox'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_GhostBox'0 [inv'1 x] . inv'1 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'2 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'1 map + end) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find7] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find5] inv'0 self) + -> ([%#sunion_find6] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (root_of'0 self) e = index_logic'1 (root_of'0 self) (index_logic'1 (root_of'0 self) e)) + + constant self : t_UnionFind'0 + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 + + goal vc_values'0 : ([%#sunion_find0] inv'0 self) + -> (let result = Snapshot.inner self.t_UnionFind__values'0 in [%#sunion_find1] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 result e = index_logic'0 result (index_logic'1 (root_of'0 self) e)) +end +module M_union_find__implementation__qyi16869121482064879694__make [#"union_find.rs" 175 8 175 54] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 176 64 176 65 + let%span sunion_find1 = "union_find.rs" 187 26 187 64 + let%span sunion_find2 = "union_find.rs" 188 26 188 68 + let%span sunion_find3 = "union_find.rs" 189 28 189 68 + let%span sunion_find4 = "union_find.rs" 190 27 190 72 + let%span sunion_find5 = "union_find.rs" 175 25 175 29 + let%span sunion_find6 = "union_find.rs" 175 31 175 36 + let%span sunion_find7 = "union_find.rs" 171 18 171 52 + let%span sunion_find8 = "union_find.rs" 172 18 172 69 + let%span sunion_find9 = "union_find.rs" 173 18 173 76 + let%span sunion_find10 = "union_find.rs" 174 18 174 73 + let%span sptr_own11 = "../../../creusot-contracts/src/ptr_own.rs" 52 15 52 16 + let%span sptr_own12 = "../../../creusot-contracts/src/ptr_own.rs" 52 4 52 56 + let%span sptr_own13 = "../../../creusot-contracts/src/ptr_own.rs" 51 14 51 64 + let%span sghost14 = "../../../creusot-contracts/src/ghost.rs" 138 27 138 31 + let%span sghost15 = "../../../creusot-contracts/src/ghost.rs" 138 4 138 52 + let%span sghost16 = "../../../creusot-contracts/src/ghost.rs" 137 14 137 39 + let%span sfset17 = "../../../creusot-contracts/src/logic/fset.rs" 65 8 65 26 + let%span sunion_find18 = "union_find.rs" 133 19 133 28 + let%span sunion_find19 = "union_find.rs" 134 18 134 150 + let%span sunion_find20 = "union_find.rs" 131 8 131 16 + let%span sfset21 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find22 = "union_find.rs" 145 19 145 28 + let%span sunion_find23 = "union_find.rs" 146 18 146 98 + let%span sunion_find24 = "union_find.rs" 143 8 143 16 + let%span sunion_find25 = "union_find.rs" 154 19 154 28 + let%span sunion_find26 = "union_find.rs" 155 18 155 106 + let%span sunion_find27 = "union_find.rs" 152 8 152 16 + let%span sghost28 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sghost29 = "../../../creusot-contracts/src/ghost.rs" 199 22 199 26 + let%span sghost30 = "../../../creusot-contracts/src/ghost.rs" 199 4 199 32 + let%span sghost31 = "../../../creusot-contracts/src/ghost.rs" 197 14 197 31 + let%span sghost32 = "../../../creusot-contracts/src/ghost.rs" 85 22 85 26 + let%span sghost33 = "../../../creusot-contracts/src/ghost.rs" 85 4 85 48 + let%span sghost34 = "../../../creusot-contracts/src/ghost.rs" 84 14 84 36 + let%span sunion_find35 = "union_find.rs" 30 18 30 46 + let%span sfmap36 = "../../../creusot-contracts/src/logic/fmap.rs" 348 30 348 34 + let%span sfmap37 = "../../../creusot-contracts/src/logic/fmap.rs" 348 36 348 39 + let%span sfmap38 = "../../../creusot-contracts/src/logic/fmap.rs" 348 4 348 62 + let%span sfmap39 = "../../../creusot-contracts/src/logic/fmap.rs" 336 4 345 11 + let%span sfmap40 = "../../../creusot-contracts/src/logic/fmap.rs" 346 14 346 89 + let%span sfmap41 = "../../../creusot-contracts/src/logic/fmap.rs" 347 14 347 44 + let%span sptr_own42 = "../../../creusot-contracts/src/ptr_own.rs" 108 26 108 30 + let%span sptr_own43 = "../../../creusot-contracts/src/ptr_own.rs" 108 48 108 52 + let%span sptr_own44 = "../../../creusot-contracts/src/ptr_own.rs" 105 14 105 64 + let%span sptr_own45 = "../../../creusot-contracts/src/ptr_own.rs" 106 14 106 28 + let%span sfmap46 = "../../../creusot-contracts/src/logic/fmap.rs" 376 29 376 33 + let%span sfmap47 = "../../../creusot-contracts/src/logic/fmap.rs" 376 35 376 38 + let%span sfmap48 = "../../../creusot-contracts/src/logic/fmap.rs" 376 43 376 48 + let%span sfmap49 = "../../../creusot-contracts/src/logic/fmap.rs" 376 4 378 17 + let%span sfmap50 = "../../../creusot-contracts/src/logic/fmap.rs" 374 14 374 49 + let%span sfmap51 = "../../../creusot-contracts/src/logic/fmap.rs" 375 14 375 40 + let%span sghost52 = "../../../creusot-contracts/src/ghost.rs" 181 15 181 16 + let%span sghost53 = "../../../creusot-contracts/src/ghost.rs" 181 4 181 28 + let%span sghost54 = "../../../creusot-contracts/src/ghost.rs" 179 14 179 28 + let%span sghost55 = "../../../creusot-contracts/src/ghost.rs" 110 8 110 24 + let%span sresolve56 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sunion_find57 = "union_find.rs" 21 8 21 16 + let%span smapping58 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sfmap59 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sfmap60 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sfmap61 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap62 = "../../../creusot-contracts/src/logic/fmap.rs" 48 14 48 25 + let%span sfmap63 = "../../../creusot-contracts/src/logic/fmap.rs" 66 14 66 71 + let%span sfmap64 = "../../../creusot-contracts/src/logic/fmap.rs" 67 14 67 61 + let%span sfmap65 = "../../../creusot-contracts/src/logic/fmap.rs" 68 14 68 66 + let%span sfmap66 = "../../../creusot-contracts/src/logic/fmap.rs" 92 8 95 9 + let%span sresolve67 = "../../../creusot-contracts/src/resolve.rs" 82 8 85 9 + let%span sinvariant68 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sfmap69 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sutil70 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil71 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap72 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sptr_own73 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sutil74 = "../../../creusot-contracts/src/util.rs" 21 14 21 30 + let%span sresolve75 = "../../../creusot-contracts/src/resolve.rs" 68 8 68 23 + let%span sunion_find76 = "union_find.rs" 80 8 80 20 + let%span sboxed77 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sptr78 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr79 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + let%span sinvariant80 = "../../../creusot-contracts/src/invariant.rs" 24 8 24 18 + let%span sunion_find81 = "union_find.rs" 125 8 125 16 + let%span sfmap82 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap83 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + + use prelude.prelude.UIntSize + + type t_T'0 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + predicate inv'3 (_1 : t_T'0) + + predicate inv'4 (_1 : t_Content'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_Content'0 [inv'4 x] . inv'4 x + = match x with + | C_Root'0 rank value -> inv'3 value + | C_Link'0 a_0 -> true + end + + type t_PtrOwn'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_PtrOwn'0 } + + use prelude.prelude.Borrow + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Int + + function addr_logic'0 (self : opaque_ptr) : int + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr79] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr78] is_null_logic'0 self = (addr_logic'0 self = 0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + predicate invariant'13 (self : t_Content'0) = + [%#sboxed77] inv'4 self + + predicate inv'26 (_1 : t_Content'0) + + axiom inv_axiom'25 [@rewrite] : forall x : t_Content'0 [inv'26 x] . inv'26 x = invariant'13 x + + predicate invariant'3 (self : t_PtrOwn'0) = + [%#sptr_own73] not is_null_logic'0 (ptr'0 self) /\ inv'26 (val'0 self) + + predicate inv'8 (_1 : t_PtrOwn'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_PtrOwn'0 [inv'8 x] . inv'8 x = invariant'3 x + + predicate invariant'12 (self : t_PtrOwn'0) = + [%#sboxed77] inv'8 self + + predicate inv'25 (_1 : t_PtrOwn'0) + + axiom inv_axiom'24 [@rewrite] : forall x : t_PtrOwn'0 [inv'25 x] . inv'25 x = invariant'12 x + + predicate inv'17 (_1 : t_GhostBox'0) + + axiom inv_axiom'16 [@rewrite] : forall x : t_GhostBox'0 [inv'17 x] . inv'17 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'25 a_0 + end + + predicate inv'5 (_1 : (opaque_ptr, t_GhostBox'0)) + + axiom inv_axiom'4 [@rewrite] : forall x : (opaque_ptr, t_GhostBox'0) [inv'5 x] . inv'5 x + = (let (x0, x1) = x in inv'17 x1) + + function inner_logic'0 (self : t_GhostBox'0) : t_PtrOwn'0 = + [%#sghost28] self.t_GhostBox__0'0 + + let rec new'0 (v:t_Content'0) (return' (ret:(opaque_ptr, t_GhostBox'0)))= {[@expl:new 'v' type invariant] [%#sptr_own11] inv'4 v} + any + [ return' (result:(opaque_ptr, t_GhostBox'0))-> {[%#sptr_own12] inv'5 result} + {[%#sptr_own13] ptr'0 (inner_logic'0 (let (_, a) = result in a)) = (let (a, _) = result in a) + /\ val'0 (inner_logic'0 (let (_, a) = result in a)) = v} + (! return' {result}) ] + + + type t_FMap'0 + + type t_GhostBox'1 = + { t_GhostBox__0'1: t_FMap'0 } + + use prelude.prelude.Snapshot + + type t_Option'2 = + | C_None'2 + | C_Some'2 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'2) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap72] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'2 = + [%#sfmap61] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap59] get_unsized'0 self k <> C_None'2 + + predicate inv'22 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'21 [@rewrite] : forall x : Snapshot.snap_ty int [inv'22 x] . inv'22 x = true + + function unwrap'0 (op : t_Option'2) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'2 . ([%#sutil70] op <> C_None'2) + -> ([%#sutil71] C_Some'2 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap60] unwrap'0 (get_unsized'0 self k) + + predicate invariant'2 (self : t_FMap'0) = + [%#sfmap69] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'22 k /\ inv'25 (lookup_unsized'0 self k) + + predicate inv'7 (_1 : t_FMap'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_FMap'0 [inv'7 x] . inv'7 x = invariant'2 x + + predicate invariant'8 (self : t_FMap'0) = + [%#sboxed77] inv'7 self + + predicate inv'15 (_1 : t_FMap'0) + + axiom inv_axiom'14 [@rewrite] : forall x : t_FMap'0 [inv'15 x] . inv'15 x = invariant'8 x + + predicate inv'0 (_1 : t_GhostBox'1) + + axiom inv_axiom'0 [@rewrite] : forall x : t_GhostBox'1 [inv'0 x] . inv'0 x + = match x with + | {t_GhostBox__0'1 = a_0} -> inv'15 a_0 + end + + use set.Fset + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'1; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + predicate invariant'1 (self : borrowed (t_GhostBox'1)) = + [%#sinvariant68] inv'0 self.current /\ inv'0 self.final + + predicate inv'6 (_1 : borrowed (t_GhostBox'1)) + + axiom inv_axiom'5 [@rewrite] : forall x : borrowed (t_GhostBox'1) [inv'6 x] . inv'6 x = invariant'1 x + + type t_GhostBox'2 = + { t_GhostBox__0'2: borrowed (t_FMap'0) } + + predicate invariant'10 (self : borrowed (t_FMap'0)) = + [%#sinvariant68] inv'7 self.current /\ inv'7 self.final + + predicate inv'18 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'17 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'18 x] . inv'18 x = invariant'10 x + + predicate invariant'9 (self : borrowed (t_FMap'0)) = + [%#sboxed77] inv'18 self + + predicate inv'16 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'15 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'16 x] . inv'16 x = invariant'9 x + + predicate inv'1 (_1 : t_GhostBox'2) + + axiom inv_axiom'1 [@rewrite] : forall x : t_GhostBox'2 [inv'1 x] . inv'1 x + = match x with + | {t_GhostBox__0'2 = a_0} -> inv'16 a_0 + end + + let rec borrow_mut'0 (self:borrowed (t_GhostBox'1)) (return' (ret:t_GhostBox'2))= {[@expl:borrow_mut 'self' type invariant] [%#sghost14] inv'6 self} + any + [ return' (result:t_GhostBox'2)-> {[%#sghost15] inv'1 result} + {[%#sghost16] result.t_GhostBox__0'2 + = Borrow.borrow_logic (self.current).t_GhostBox__0'1 (self.final).t_GhostBox__0'1 (Borrow.inherit_id (Borrow.get_id self) 1)} + (! return' {result}) ] + + + let rec into_inner'0 (self:t_GhostBox'0) (return' (ret:t_PtrOwn'0))= {[@expl:into_inner 'self' type invariant] [%#sghost29] inv'17 self} + any + [ return' (result:t_PtrOwn'0)-> {[%#sghost30] inv'8 result} + {[%#sghost31] result = self.t_GhostBox__0'0} + (! return' {result}) ] + + + predicate invariant'6 (self : borrowed (t_GhostBox'2)) = + [%#sinvariant68] inv'1 self.current /\ inv'1 self.final + + predicate inv'12 (_1 : borrowed (t_GhostBox'2)) + + axiom inv_axiom'11 [@rewrite] : forall x : borrowed (t_GhostBox'2) [inv'12 x] . inv'12 x = invariant'6 x + + predicate invariant'5 (self : borrowed (borrowed (t_FMap'0))) = + [%#sinvariant68] inv'18 self.current /\ inv'18 self.final + + predicate inv'10 (_1 : borrowed (borrowed (t_FMap'0))) + + axiom inv_axiom'9 [@rewrite] : forall x : borrowed (borrowed (t_FMap'0)) [inv'10 x] . inv'10 x = invariant'5 x + + let rec deref_mut'0 (self:borrowed (t_GhostBox'2)) (return' (ret:borrowed (borrowed (t_FMap'0))))= {[@expl:deref_mut 'self' type invariant] [%#sghost32] inv'12 self} + any + [ return' (result:borrowed (borrowed (t_FMap'0)))-> {[%#sghost33] inv'10 result} + {[%#sghost34] result + = Borrow.borrow_logic (self.current).t_GhostBox__0'2 (self.final).t_GhostBox__0'2 (Borrow.inherit_id (Borrow.get_id self) 1)} + (! return' {result}) ] + + + use prelude.prelude.Snapshot + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find57] addr_logic'0 self.t_Element__0'0 + + let rec addr'0 (self:t_Element'0) (return' (ret:Snapshot.snap_ty int))= any + [ return' (result:Snapshot.snap_ty int)-> {[%#sunion_find35] Snapshot.inner result = deep_model'0 self} + (! return' {result}) ] + + + predicate inv'19 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'18 [@rewrite] : forall x : Snapshot.snap_ty int [inv'19 x] . inv'19 x = true + + type t_Option'0 = + | C_None'0 + | C_Some'0 (borrowed (t_PtrOwn'0)) + + predicate invariant'4 (self : borrowed (t_PtrOwn'0)) = + [%#sinvariant68] inv'8 self.current /\ inv'8 self.final + + predicate inv'9 (_1 : borrowed (t_PtrOwn'0)) + + axiom inv_axiom'8 [@rewrite] : forall x : borrowed (t_PtrOwn'0) [inv'9 x] . inv'9 x = invariant'4 x + + predicate inv'20 (_1 : t_Option'0) + + axiom inv_axiom'19 [@rewrite] : forall x : t_Option'0 [inv'20 x] . inv'20 x + = match x with + | C_None'0 -> true + | C_Some'0 a_0 -> inv'9 a_0 + end + + function len'0 (self : t_FMap'0) : int + + axiom len'0_spec : forall self : t_FMap'0 . [%#sfmap62] len'0 self >= 0 + + let rec get_mut_ghost'0 (self:borrowed (t_FMap'0)) (key:Snapshot.snap_ty int) (return' (ret:t_Option'0))= {[@expl:get_mut_ghost 'self' type invariant] [%#sfmap36] inv'18 self} + {[@expl:get_mut_ghost 'key' type invariant] [%#sfmap37] inv'19 key} + any + [ return' (result:t_Option'0)-> {[%#sfmap38] inv'20 result} + {[%#sfmap39] if contains'1 self.current key then + match result with + | C_None'0 -> false + | C_Some'0 r -> contains'1 self.final key + /\ lookup_unsized'0 self.current key = r.current /\ lookup_unsized'0 self.final key = r.final + end + else + result = C_None'0 /\ self.current = self.final + } + {[%#sfmap40] forall k : Snapshot.snap_ty int . k <> key + -> get_unsized'0 self.current k = get_unsized'0 self.final k} + {[%#sfmap41] len'0 self.current = len'0 self.final} + (! return' {result}) ] + + + let rec v_Some'0 (input:t_Option'0) (ret (field_0:borrowed (t_PtrOwn'0)))= any + [ good (field_0:borrowed (t_PtrOwn'0))-> {C_Some'0 field_0 = input} (! ret {field_0}) + | bad -> {forall field_0 : borrowed (t_PtrOwn'0) [C_Some'0 field_0 : t_Option'0] . C_Some'0 field_0 <> input} + (! {false} + any) ] + + + predicate invariant'11 (self : t_PtrOwn'0) = + [%#sinvariant80] inv'8 self + + predicate inv'21 (_1 : t_PtrOwn'0) + + axiom inv_axiom'20 [@rewrite] : forall x : t_PtrOwn'0 [inv'21 x] . inv'21 x = invariant'11 x + + let rec disjoint_lemma'0 (own1:borrowed (t_PtrOwn'0)) (own2:t_PtrOwn'0) (return' (ret:()))= {[@expl:disjoint_lemma 'own1' type invariant] [%#sptr_own42] inv'9 own1} + {[@expl:disjoint_lemma 'own2' type invariant] [%#sptr_own43] inv'21 own2} + any + [ return' (result:())-> {[%#sptr_own44] addr_logic'0 (ptr'0 own1.current) <> addr_logic'0 (ptr'0 own2)} + {[%#sptr_own45] own1.current = own1.final} + (! return' {result}) ] + + + predicate resolve'8 (self : borrowed (t_PtrOwn'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'2 (_1 : borrowed (t_PtrOwn'0)) = + resolve'8 _1 + + predicate resolve'9 (self : borrowed (borrowed (t_FMap'0))) = + [%#sresolve56] self.final = self.current + + predicate resolve'3 (_1 : borrowed (borrowed (t_FMap'0))) = + resolve'9 _1 + + type t_Option'1 = + | C_None'1 + | C_Some'1 (t_PtrOwn'0) + + predicate inv'11 (_1 : t_Option'1) + + axiom inv_axiom'10 [@rewrite] : forall x : t_Option'1 [inv'11 x] . inv'11 x + = match x with + | C_None'1 -> true + | C_Some'1 a_0 -> inv'8 a_0 + end + + function make_sized'0 (self : t_PtrOwn'0) : t_PtrOwn'0 + + axiom make_sized'0_spec : forall self : t_PtrOwn'0 . [%#sutil74] make_sized'0 self = self + + use map.Map + + function insert'1 (self : t_FMap'0) (k : Snapshot.snap_ty int) (v : t_PtrOwn'0) : t_FMap'0 + + axiom insert'1_spec : forall self : t_FMap'0, k : Snapshot.snap_ty int, v : t_PtrOwn'0 . ([%#sfmap63] view'0 (insert'1 self k v) + = Map.set (view'0 self) k (C_Some'2 (make_sized'0 v))) + && ([%#sfmap64] contains'1 self k -> len'0 (insert'1 self k v) = len'0 self) + && ([%#sfmap65] not contains'1 self k -> len'0 (insert'1 self k v) = len'0 self + 1) + + function get'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'1 = + [%#sfmap66] match get_unsized'0 self k with + | C_None'2 -> C_None'1 + | C_Some'2 x -> C_Some'1 x + end + + let rec insert_ghost'0 (self:borrowed (t_FMap'0)) (key:Snapshot.snap_ty int) (value:t_PtrOwn'0) (return' (ret:t_Option'1))= {[@expl:insert_ghost 'self' type invariant] [%#sfmap46] inv'18 self} + {[@expl:insert_ghost 'key' type invariant] [%#sfmap47] inv'22 key} + {[@expl:insert_ghost 'value' type invariant] [%#sfmap48] inv'8 value} + any + [ return' (result:t_Option'1)-> {[%#sfmap49] inv'11 result} + {[%#sfmap50] self.final = insert'1 self.current key value} + {[%#sfmap51] result = get'0 self.current key} + (! return' {result}) ] + + + predicate resolve'13 (_1 : t_PtrOwn'0) = + true + + predicate resolve'10 (self : t_Option'1) = + [%#sresolve67] match self with + | C_Some'1 x -> resolve'13 x + | C_None'1 -> true + end + + predicate resolve'4 (_1 : t_Option'1) = + resolve'10 _1 + + predicate resolve'11 (self : borrowed (t_GhostBox'2)) = + [%#sresolve56] self.final = self.current + + predicate resolve'5 (_1 : borrowed (t_GhostBox'2)) = + resolve'11 _1 + + predicate inv'23 (_1 : ()) + + axiom inv_axiom'22 [@rewrite] : forall x : () [inv'23 x] . inv'23 x = true + + type t_GhostBox'3 = + { t_GhostBox__0'3: () } + + predicate inv'24 (_1 : t_GhostBox'3) + + axiom inv_axiom'23 [@rewrite] : forall x : t_GhostBox'3 [inv'24 x] . inv'24 x = true + + let rec new'1 (x:()) (return' (ret:t_GhostBox'3))= {[@expl:new 'x' type invariant] [%#sghost52] inv'23 x} + any + [ return' (result:t_GhostBox'3)-> {[%#sghost53] inv'24 result} + {[%#sghost54] result.t_GhostBox__0'3 = x} + (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + type closure4'1 = + { field_0'0: t_GhostBox'0; field_1'0: borrowed (t_GhostBox'2); field_2'0: t_Element'0 } + + predicate inv'13 (_1 : closure4'1) + + axiom inv_axiom'12 [@rewrite] : forall x : closure4'1 [inv'13 x] . inv'13 x + = (let {field_0'0 = x0 ; field_1'0 = x1 ; field_2'0 = x2} = x in inv'17 x0 /\ inv'12 x1) + + let rec closure4'0 (_1:closure4'1) (return' (ret:t_GhostBox'3))= {[@expl:closure '_1' type invariant] inv'13 _1} + bb0 + [ bb0 = s0 [ s0 = into_inner'0 {_1.field_0'0} (fun (_ret':t_PtrOwn'0) -> [ &perm <- _ret' ] s1) | s1 = bb1 ] + | bb1 = s0 + [ s0 = {inv'1 (_1.field_1'0).current} + Borrow.borrow_mut {(_1.field_1'0).current} + (fun (_ret':borrowed (t_GhostBox'2)) -> + [ &_9 <- _ret' ] + -{inv'1 _ret'.final}- + [ &_1 <- { _1 with field_1'0 = { _1.field_1'0 with current = _ret'.final } } ] + s1) + | s1 = deref_mut'0 {_9} (fun (_ret':borrowed (borrowed (t_FMap'0))) -> [ &_8 <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = {inv'7 (_8.current).current} + Borrow.borrow_mut {(_8.current).current} + (fun (_ret':borrowed (t_FMap'0)) -> + [ &_7 <- _ret' ] + -{inv'7 _ret'.final}- + [ &_8 <- { _8 with current = { _8.current with current = _ret'.final } } ] + s1) + | s1 = addr'0 {_1.field_2'0} (fun (_ret':Snapshot.snap_ty int) -> [ &_12 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 + [ s0 = [ &_11 <- _12 ] s1 + | s1 = get_mut_ghost'0 {_7} {_11} (fun (_ret':t_Option'0) -> [ &_6 <- _ret' ] s2) + | s2 = bb4 ] + + | bb4 = any [ br0 -> {_6 = C_None'0 } (! bb6) | br1 (x0:borrowed (t_PtrOwn'0))-> {_6 = C_Some'0 x0} (! bb7) ] + | bb7 = s0 + [ s0 = v_Some'0 {_6} (fun (r0'0:borrowed (t_PtrOwn'0)) -> [ &other_perm <- r0'0 ] s1) + | s1 = {inv'8 other_perm.current} + Borrow.borrow_final {other_perm.current} {Borrow.get_id other_perm} + (fun (_ret':borrowed (t_PtrOwn'0)) -> + [ &_16 <- _ret' ] + -{inv'8 _ret'.final}- + [ &other_perm <- { other_perm with current = _ret'.final } ] + s2) + | s2 = [ &_18 <- perm ] s3 + | s3 = disjoint_lemma'0 {_16} {_18} (fun (_ret':()) -> [ &_5 <- _ret' ] s4) + | s4 = bb9 ] + + | bb9 = s0 + [ s0 = {[@expl:type invariant] inv'9 other_perm} s1 + | s1 = -{resolve'2 other_perm}- s2 + | s2 = {[@expl:type invariant] inv'10 _8} s3 + | s3 = -{resolve'3 _8}- s4 + | s4 = bb10 ] + + | bb6 = bb8 + | bb8 = s0 [ s0 = {[@expl:type invariant] inv'10 _8} s1 | s1 = -{resolve'3 _8}- s2 | s2 = bb10 ] + | bb10 = s0 + [ s0 = {inv'1 (_1.field_1'0).current} + Borrow.borrow_final {(_1.field_1'0).current} {Borrow.get_id _1.field_1'0} + (fun (_ret':borrowed (t_GhostBox'2)) -> + [ &_22 <- _ret' ] + -{inv'1 _ret'.final}- + [ &_1 <- { _1 with field_1'0 = { _1.field_1'0 with current = _ret'.final } } ] + s1) + | s1 = deref_mut'0 {_22} (fun (_ret':borrowed (borrowed (t_FMap'0))) -> [ &_21 <- _ret' ] s2) + | s2 = bb11 ] + + | bb11 = s0 + [ s0 = {inv'7 (_21.current).current} + Borrow.borrow_mut {(_21.current).current} + (fun (_ret':borrowed (t_FMap'0)) -> + [ &_20 <- _ret' ] + -{inv'7 _ret'.final}- + [ &_21 <- { _21 with current = { _21.current with current = _ret'.final } } ] + s1) + | s1 = addr'0 {_1.field_2'0} (fun (_ret':Snapshot.snap_ty int) -> [ &_23 <- _ret' ] s2) + | s2 = bb12 ] + + | bb12 = s0 + [ s0 = insert_ghost'0 {_20} {_23} {perm} (fun (_ret':t_Option'1) -> [ &_19 <- _ret' ] s1) + | s1 = {[@expl:type invariant] inv'11 _19} s2 + | s2 = -{resolve'4 _19}- s3 + | s3 = bb13 ] + + | bb13 = s0 + [ s0 = {[@expl:type invariant] inv'10 _21} s1 + | s1 = -{resolve'3 _21}- s2 + | s2 = {[@expl:type invariant] match _1 with + | {field_1'0 = x'2} -> inv'12 x'2 + | _ -> true + end} + s3 + | s3 = -{match _1 with + | {field_1'0 = x'3} -> resolve'5 x'3 + | _ -> true + end}- + s4 + | s4 = new'1 {_2} (fun (_ret':t_GhostBox'3) -> [ &_0 <- _ret' ] s5) + | s5 = bb14 ] + + | bb14 = bb15 + | bb15 = return' {_0} ] + + [ & _0 : t_GhostBox'3 = any_l () + | & _1 : closure4'1 = _1 + | & _2 : () = any_l () + | & perm : t_PtrOwn'0 = any_l () + | & _5 : () = any_l () + | & _6 : t_Option'0 = any_l () + | & _7 : borrowed (t_FMap'0) = any_l () + | & _8 : borrowed (borrowed (t_FMap'0)) = any_l () + | & _9 : borrowed (t_GhostBox'2) = any_l () + | & _11 : Snapshot.snap_ty int = any_l () + | & _12 : Snapshot.snap_ty int = any_l () + | & other_perm : borrowed (t_PtrOwn'0) = any_l () + | & _16 : borrowed (t_PtrOwn'0) = any_l () + | & _18 : t_PtrOwn'0 = any_l () + | & _19 : t_Option'1 = any_l () + | & _20 : borrowed (t_FMap'0) = any_l () + | & _21 : borrowed (borrowed (t_FMap'0)) = any_l () + | & _22 : borrowed (t_GhostBox'2) = any_l () + | & _23 : Snapshot.snap_ty int = any_l () ] + [ return' (result:t_GhostBox'3)-> return' {result} ] + + predicate resolve'16 (self : borrowed (t_FMap'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'15 (_1 : borrowed (t_FMap'0)) = + resolve'16 _1 + + predicate resolve'14 (self : borrowed (t_FMap'0)) = + [%#sresolve75] resolve'15 self + + predicate resolve'12 (_1 : borrowed (t_FMap'0)) = + resolve'14 _1 + + predicate resolve'6 (self : t_GhostBox'2) = + [%#sghost55] resolve'12 self.t_GhostBox__0'2 + + predicate resolve'0 (_1 : t_GhostBox'2) = + resolve'6 _1 + + use prelude.prelude.Snapshot + + use set.Fset + + function insert'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) : Fset.fset (t_Element'0) = + [%#sfset17] Fset.add e self + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset21] Fset.mem e self + + function inner_logic'1 (self : t_GhostBox'1) : t_FMap'0 = + [%#sghost28] self.t_GhostBox__0'1 + + use prelude.prelude.Snapshot + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap83] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap82] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find81] index_logic'3 (inner_logic'1 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping58] Map.get self a + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping58] Map.get self a + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping58] Map.get self a + + predicate invariant'7 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find76] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'1 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'14 (_1 : t_UnionFind'0) + + axiom inv_axiom'13 [@rewrite] : forall x : t_UnionFind'0 [inv'14 x] . inv'14 x + = (invariant'7 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'0 map + end) + + predicate invariant'0 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant68] inv'14 self.current /\ inv'14 self.final + + predicate inv'2 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'2 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'2 x] . inv'2 x = invariant'0 x + + predicate resolve'7 (self : borrowed (t_UnionFind'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'1 (_1 : borrowed (t_UnionFind'0)) = + resolve'7 _1 + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find20] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find18] inv'14 self) + -> ([%#sunion_find19] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find24] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find22] inv'14 self) + -> ([%#sunion_find23] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find27] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find25] inv'14 self) + -> ([%#sunion_find26] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + meta "compute_max_steps" 1000000 + + let rec make'0 (self:borrowed (t_UnionFind'0)) (value:t_T'0) (return' (ret:t_Element'0))= {[@expl:make 'self' type invariant] [%#sunion_find5] inv'2 self} + {[@expl:make 'value' type invariant] [%#sunion_find6] inv'3 value} + (! bb0 + [ bb0 = bb1 + | bb1 = s0 [ s0 = [ &_10 <- C_Root'0 ([%#sunion_find0] (0 : usize)) value ] s1 | s1 = bb2 ] + | bb2 = s0 [ s0 = new'0 {_10} (fun (_ret':(opaque_ptr, t_GhostBox'0)) -> [ &_9 <- _ret' ] s1) | s1 = bb3 ] + | bb3 = s0 + [ s0 = [ &ptr <- let (r'0, _) = _9 in r'0 ] s1 | s1 = [ &perm <- let (_, r'1) = _9 in r'1 ] s2 | s2 = bb4 ] + + | bb4 = s0 + [ s0 = [ &element <- { t_Element__0'0 = ptr } ] s1 + | s1 = {inv'0 (self.current).t_UnionFind__map'0} + Borrow.borrow_final + + {(self.current).t_UnionFind__map'0} + {Borrow.inherit_id (Borrow.get_id self) 2} + (fun (_ret':borrowed (t_GhostBox'1)) -> + [ &_15 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = { self.current with t_UnionFind__map'0 = _ret'.final } } ] + s2) + | s2 = borrow_mut'0 {_15} (fun (_ret':t_GhostBox'2) -> [ &map <- _ret' ] s3) + | s3 = bb5 ] + + | bb5 = s0 + [ s0 = {inv'1 map} + Borrow.borrow_mut {map} + (fun (_ret':borrowed (t_GhostBox'2)) -> [ &_18 <- _ret' ] -{inv'1 _ret'.final}- [ &map <- _ret'.final ] s1) + | s1 = [ &_17 <- { field_0'0 = perm; field_1'0 = _18; field_2'0 = element } ] s2 + | s2 = closure4'0 {_17} (fun (_ret':t_GhostBox'3) -> [ &_16 <- _ret' ] s3) + | s3 = bb6 ] + + | bb6 = s0 [ s0 = {[@expl:type invariant] inv'1 map} s1 | s1 = -{resolve'0 map}- s2 | s2 = bb7 ] + | bb7 = s0 + [ s0 = + [ &_21 <- [%#sunion_find1] Snapshot.new (insert'0 (Snapshot.inner (self.current).t_UnionFind__domain'0) element) ] + + s1 + | s1 = bb8 ] + + | bb8 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__domain'0 = _21 } } ] s1 + | s1 = + [ &_23 <- [%#sunion_find2] Snapshot.new (Map.set (Snapshot.inner (self.current).t_UnionFind__values'0) element value) ] + + s2 + | s2 = bb9 ] + + | bb9 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__values'0 = _23 } } ] s1 + | s1 = + [ &_25 <- [%#sunion_find3] Snapshot.new (Map.set (Snapshot.inner (self.current).t_UnionFind__distance'0) element 0) ] + + s2 + | s2 = bb10 ] + + | bb10 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__distance'0 = _25 } } ] s1 + | s1 = + [ &_27 <- [%#sunion_find4] Snapshot.new (Map.set (Snapshot.inner (self.current).t_UnionFind__root_of'0) element element) ] + + s2 + | s2 = bb11 ] + + | bb11 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__root_of'0 = _27 } } ] s1 + | s1 = {[@expl:type invariant] inv'2 self} s2 + | s2 = -{resolve'1 self}- s3 + | s3 = [ &_0 <- element ] s4 + | s4 = bb12 ] + + | bb12 = bb13 + | bb13 = bb14 + | bb14 = return' {_0} ] + ) + [ & _0 : t_Element'0 = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & value : t_T'0 = value + | & ptr : opaque_ptr = any_l () + | & perm : t_GhostBox'0 = any_l () + | & _9 : (opaque_ptr, t_GhostBox'0) = any_l () + | & _10 : t_Content'0 = any_l () + | & element : t_Element'0 = any_l () + | & map : t_GhostBox'2 = any_l () + | & _15 : borrowed (t_GhostBox'1) = any_l () + | & _16 : t_GhostBox'3 = any_l () + | & _17 : closure4'1 = any_l () + | & _18 : borrowed (t_GhostBox'2) = any_l () + | & _20 : () = any_l () + | & _21 : Snapshot.snap_ty (Fset.fset (t_Element'0)) = any_l () + | & _23 : Snapshot.snap_ty (Map.map (t_Element'0) t_T'0) = any_l () + | & _25 : Snapshot.snap_ty (Map.map (t_Element'0) int) = any_l () + | & _27 : Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)) = any_l () ] + + [ return' (result:t_Element'0)-> {[@expl:make ensures #0] [%#sunion_find7] not contains'0 (domain'0 self.current) result} + {[@expl:make ensures #1] [%#sunion_find8] domain'0 self.final = insert'0 (domain'0 self.current) result} + {[@expl:make ensures #2] [%#sunion_find9] root_of'0 self.final = Map.set (root_of'0 self.current) result result} + {[@expl:make ensures #3] [%#sunion_find10] values'0 self.final = Map.set (values'0 self.current) result value} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__find_inner [#"union_find.rs" 201 8 201 64] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 201 27 201 31 + let%span sunion_find1 = "union_find.rs" 195 19 195 47 + let%span sunion_find2 = "union_find.rs" 196 18 196 48 + let%span sunion_find3 = "union_find.rs" 197 18 197 34 + let%span sunion_find4 = "union_find.rs" 199 18 199 54 + let%span sunion_find5 = "union_find.rs" 200 18 200 62 + let%span sghost6 = "../../../creusot-contracts/src/ghost.rs" 124 19 124 23 + let%span sghost7 = "../../../creusot-contracts/src/ghost.rs" 124 4 124 40 + let%span sghost8 = "../../../creusot-contracts/src/ghost.rs" 123 14 123 35 + let%span sunion_find9 = "union_find.rs" 203 23 203 67 + let%span sptr_own10 = "../../../creusot-contracts/src/ptr_own.rs" 71 34 71 37 + let%span sptr_own11 = "../../../creusot-contracts/src/ptr_own.rs" 68 15 68 31 + let%span sptr_own12 = "../../../creusot-contracts/src/ptr_own.rs" 71 4 71 66 + let%span sptr_own13 = "../../../creusot-contracts/src/ptr_own.rs" 69 14 69 35 + let%span sghost14 = "../../../creusot-contracts/src/ghost.rs" 138 27 138 31 + let%span sghost15 = "../../../creusot-contracts/src/ghost.rs" 138 4 138 52 + let%span sghost16 = "../../../creusot-contracts/src/ghost.rs" 137 14 137 39 + let%span sunion_find17 = "union_find.rs" 211 35 211 83 + let%span sptr_own18 = "../../../creusot-contracts/src/ptr_own.rs" 83 34 83 37 + let%span sptr_own19 = "../../../creusot-contracts/src/ptr_own.rs" 78 15 78 31 + let%span sptr_own20 = "../../../creusot-contracts/src/ptr_own.rs" 83 4 83 74 + let%span sptr_own21 = "../../../creusot-contracts/src/ptr_own.rs" 79 14 79 35 + let%span sptr_own22 = "../../../creusot-contracts/src/ptr_own.rs" 81 14 81 53 + let%span sptr_own23 = "../../../creusot-contracts/src/ptr_own.rs" 82 14 82 52 + let%span sunion_find24 = "union_find.rs" 133 19 133 28 + let%span sunion_find25 = "union_find.rs" 134 18 134 150 + let%span sunion_find26 = "union_find.rs" 131 8 131 16 + let%span sfset27 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find28 = "union_find.rs" 145 19 145 28 + let%span sunion_find29 = "union_find.rs" 146 18 146 98 + let%span sunion_find30 = "union_find.rs" 143 8 143 16 + let%span smapping31 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find32 = "union_find.rs" 165 16 167 52 + let%span sghost33 = "../../../creusot-contracts/src/ghost.rs" 69 14 69 18 + let%span sghost34 = "../../../creusot-contracts/src/ghost.rs" 69 4 69 36 + let%span sghost35 = "../../../creusot-contracts/src/ghost.rs" 68 14 68 35 + let%span sunion_find36 = "union_find.rs" 30 18 30 46 + let%span sfmap37 = "../../../creusot-contracts/src/logic/fmap.rs" 314 22 314 26 + let%span sfmap38 = "../../../creusot-contracts/src/logic/fmap.rs" 314 28 314 31 + let%span sfmap39 = "../../../creusot-contracts/src/logic/fmap.rs" 314 4 314 50 + let%span sfmap40 = "../../../creusot-contracts/src/logic/fmap.rs" 306 4 313 11 + let%span soption41 = "../../../creusot-contracts/src/std/option.rs" 31 0 423 1 + let%span sghost42 = "../../../creusot-contracts/src/ghost.rs" 181 15 181 16 + let%span sghost43 = "../../../creusot-contracts/src/ghost.rs" 181 4 181 28 + let%span sghost44 = "../../../creusot-contracts/src/ghost.rs" 179 14 179 28 + let%span sghost45 = "../../../creusot-contracts/src/ghost.rs" 110 8 110 24 + let%span sghost46 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sghost47 = "../../../creusot-contracts/src/ghost.rs" 85 22 85 26 + let%span sghost48 = "../../../creusot-contracts/src/ghost.rs" 85 4 85 48 + let%span sghost49 = "../../../creusot-contracts/src/ghost.rs" 84 14 84 36 + let%span sfmap50 = "../../../creusot-contracts/src/logic/fmap.rs" 348 30 348 34 + let%span sfmap51 = "../../../creusot-contracts/src/logic/fmap.rs" 348 36 348 39 + let%span sfmap52 = "../../../creusot-contracts/src/logic/fmap.rs" 348 4 348 62 + let%span sfmap53 = "../../../creusot-contracts/src/logic/fmap.rs" 336 4 345 11 + let%span sfmap54 = "../../../creusot-contracts/src/logic/fmap.rs" 346 14 346 89 + let%span sfmap55 = "../../../creusot-contracts/src/logic/fmap.rs" 347 14 347 44 + let%span sresolve56 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sunion_find57 = "union_find.rs" 21 8 21 16 + let%span sunion_find58 = "union_find.rs" 154 19 154 28 + let%span sunion_find59 = "union_find.rs" 155 18 155 106 + let%span sunion_find60 = "union_find.rs" 152 8 152 16 + let%span sfmap61 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sfmap62 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sunion_find63 = "union_find.rs" 80 8 80 20 + let%span sfmap64 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap65 = "../../../creusot-contracts/src/logic/fmap.rs" 48 14 48 25 + let%span sinvariant66 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sinvariant67 = "../../../creusot-contracts/src/invariant.rs" 24 8 24 18 + let%span sutil68 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil69 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sresolve70 = "../../../creusot-contracts/src/resolve.rs" 68 8 68 23 + let%span sunion_find71 = "union_find.rs" 125 8 125 16 + let%span sfmap72 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sfmap73 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sptr_own74 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sboxed75 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sfmap76 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sptr77 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr78 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + let%span sfmap79 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'2 = + { t_GhostBox__0'1: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'2; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Borrow + + type t_PtrOwn'0 + + type t_Option'2 = + | C_None'2 + | C_Some'2 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'2) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap73] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'2 = + [%#sfmap64] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap61] get_unsized'0 self k <> C_None'2 + + predicate inv'33 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'32 [@rewrite] : forall x : Snapshot.snap_ty int [inv'33 x] . inv'33 x = true + + function unwrap'2 (op : t_Option'2) : t_PtrOwn'0 + + axiom unwrap'2_spec : forall op : t_Option'2 . ([%#sutil68] op <> C_None'2) + -> ([%#sutil69] C_Some'2 (unwrap'2 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap62] unwrap'2 (get_unsized'0 self k) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + function addr_logic'0 (self : opaque_ptr) : int + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr78] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr77] is_null_logic'0 self = (addr_logic'0 self = 0) + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + predicate inv'30 (_1 : t_T'0) + + predicate inv'4 (_1 : t_Content'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_Content'0 [inv'4 x] . inv'4 x + = match x with + | C_Root'0 rank value -> inv'30 value + | C_Link'0 a_0 -> true + end + + predicate invariant'22 (self : t_Content'0) = + [%#sboxed75] inv'4 self + + predicate inv'35 (_1 : t_Content'0) + + axiom inv_axiom'34 [@rewrite] : forall x : t_Content'0 [inv'35 x] . inv'35 x = invariant'22 x + + predicate invariant'7 (self : t_PtrOwn'0) = + [%#sptr_own74] not is_null_logic'0 (ptr'0 self) /\ inv'35 (val'0 self) + + predicate inv'13 (_1 : t_PtrOwn'0) + + axiom inv_axiom'13 [@rewrite] : forall x : t_PtrOwn'0 [inv'13 x] . inv'13 x = invariant'7 x + + predicate invariant'21 (self : t_PtrOwn'0) = + [%#sboxed75] inv'13 self + + predicate inv'34 (_1 : t_PtrOwn'0) + + axiom inv_axiom'33 [@rewrite] : forall x : t_PtrOwn'0 [inv'34 x] . inv'34 x = invariant'21 x + + predicate invariant'6 (self : t_FMap'0) = + [%#sfmap72] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'33 k /\ inv'34 (lookup_unsized'0 self k) + + predicate inv'12 (_1 : t_FMap'0) + + axiom inv_axiom'12 [@rewrite] : forall x : t_FMap'0 [inv'12 x] . inv'12 x = invariant'6 x + + predicate invariant'15 (self : t_FMap'0) = + [%#sboxed75] inv'12 self + + predicate inv'25 (_1 : t_FMap'0) + + axiom inv_axiom'25 [@rewrite] : forall x : t_FMap'0 [inv'25 x] . inv'25 x = invariant'15 x + + predicate inv'2 (_1 : t_GhostBox'2) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'2 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'1 = a_0} -> inv'25 a_0 + end + + predicate invariant'3 (self : t_GhostBox'2) = + [%#sinvariant67] inv'2 self + + predicate inv'7 (_1 : t_GhostBox'2) + + axiom inv_axiom'7 [@rewrite] : forall x : t_GhostBox'2 [inv'7 x] . inv'7 x = invariant'3 x + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + predicate invariant'12 (self : t_FMap'0) = + [%#sinvariant67] inv'12 self + + predicate inv'20 (_1 : t_FMap'0) + + axiom inv_axiom'20 [@rewrite] : forall x : t_FMap'0 [inv'20 x] . inv'20 x = invariant'12 x + + predicate invariant'14 (self : t_FMap'0) = + [%#sboxed75] inv'20 self + + predicate inv'24 (_1 : t_FMap'0) + + axiom inv_axiom'24 [@rewrite] : forall x : t_FMap'0 [inv'24 x] . inv'24 x = invariant'14 x + + predicate inv'0 (_1 : t_GhostBox'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_GhostBox'0 [inv'0 x] . inv'0 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'24 a_0 + end + + let rec borrow'0 (self:t_GhostBox'2) (return' (ret:t_GhostBox'0))= {[@expl:borrow 'self' type invariant] [%#sghost6] inv'7 self} + any + [ return' (result:t_GhostBox'0)-> {[%#sghost7] inv'0 result} + {[%#sghost8] result.t_GhostBox__0'0 = self.t_GhostBox__0'1} + (! return' {result}) ] + + + predicate invariant'10 (self : t_GhostBox'0) = + [%#sinvariant67] inv'0 self + + predicate inv'18 (_1 : t_GhostBox'0) + + axiom inv_axiom'18 [@rewrite] : forall x : t_GhostBox'0 [inv'18 x] . inv'18 x = invariant'10 x + + predicate invariant'11 (self : t_FMap'0) = + [%#sinvariant67] inv'20 self + + predicate inv'19 (_1 : t_FMap'0) + + axiom inv_axiom'19 [@rewrite] : forall x : t_FMap'0 [inv'19 x] . inv'19 x = invariant'11 x + + let rec deref'0 (self:t_GhostBox'0) (return' (ret:t_FMap'0))= {[@expl:deref 'self' type invariant] [%#sghost33] inv'18 self} + any + [ return' (result:t_FMap'0)-> {[%#sghost34] inv'19 result} + {[%#sghost35] self.t_GhostBox__0'0 = result} + (! return' {result}) ] + + + use prelude.prelude.Snapshot + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find57] addr_logic'0 self.t_Element__0'0 + + let rec addr'0 (self:t_Element'0) (return' (ret:Snapshot.snap_ty int))= any + [ return' (result:Snapshot.snap_ty int)-> {[%#sunion_find36] Snapshot.inner result = deep_model'0 self} + (! return' {result}) ] + + + predicate inv'21 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'21 [@rewrite] : forall x : Snapshot.snap_ty int [inv'21 x] . inv'21 x = true + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + predicate invariant'13 (self : t_PtrOwn'0) = + [%#sinvariant67] inv'13 self + + predicate inv'23 (_1 : t_PtrOwn'0) + + axiom inv_axiom'23 [@rewrite] : forall x : t_PtrOwn'0 [inv'23 x] . inv'23 x = invariant'13 x + + predicate inv'22 (_1 : t_Option'0) + + axiom inv_axiom'22 [@rewrite] : forall x : t_Option'0 [inv'22 x] . inv'22 x + = match x with + | C_None'0 -> true + | C_Some'0 a_0 -> inv'23 a_0 + end + + let rec get_ghost'0 (self:t_FMap'0) (key:Snapshot.snap_ty int) (return' (ret:t_Option'0))= {[@expl:get_ghost 'self' type invariant] [%#sfmap37] inv'20 self} + {[@expl:get_ghost 'key' type invariant] [%#sfmap38] inv'21 key} + any + [ return' (result:t_Option'0)-> {[%#sfmap39] inv'22 result} + {[%#sfmap40] if contains'1 self key then + match result with + | C_None'0 -> false + | C_Some'0 r -> lookup_unsized'0 self key = r + end + else + result = C_None'0 + } + (! return' {result}) ] + + + let rec unwrap'0 (self:t_Option'0) (return' (ret:t_PtrOwn'0))= {[@expl:unwrap 'self' type invariant] inv'22 self} + {[@expl:unwrap requires] [%#soption41] self <> C_None'0} + any [ return' (result:t_PtrOwn'0)-> {inv'23 result} {[%#soption41] C_Some'0 result = self} (! return' {result}) ] + + type t_GhostBox'1 = + { t_GhostBox__0'2: t_PtrOwn'0 } + + predicate invariant'19 (self : t_PtrOwn'0) = + [%#sboxed75] inv'23 self + + predicate inv'31 (_1 : t_PtrOwn'0) + + axiom inv_axiom'30 [@rewrite] : forall x : t_PtrOwn'0 [inv'31 x] . inv'31 x = invariant'19 x + + predicate inv'9 (_1 : t_GhostBox'1) + + axiom inv_axiom'9 [@rewrite] : forall x : t_GhostBox'1 [inv'9 x] . inv'9 x + = match x with + | {t_GhostBox__0'2 = a_0} -> inv'31 a_0 + end + + let rec new'0 (x:t_PtrOwn'0) (return' (ret:t_GhostBox'1))= {[@expl:new 'x' type invariant] [%#sghost42] inv'23 x} + any + [ return' (result:t_GhostBox'1)-> {[%#sghost43] inv'9 result} + {[%#sghost44] result.t_GhostBox__0'2 = x} + (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + type closure5'1 = + { field_0'0: t_GhostBox'0; field_1'0: t_Element'0 } + + predicate inv'8 (_1 : closure5'1) + + axiom inv_axiom'8 [@rewrite] : forall x : closure5'1 [inv'8 x] . inv'8 x + = (let {field_0'0 = x0 ; field_1'0 = x1} = x in inv'18 x0) + + let rec closure5'0 (_1:closure5'1) (return' (ret:t_GhostBox'1))= {[@expl:closure '_1' type invariant] inv'8 _1} + bb0 + [ bb0 = s0 [ s0 = deref'0 {_1.field_0'0} (fun (_ret':t_FMap'0) -> [ &_5 <- _ret' ] s1) | s1 = bb1 ] + | bb1 = s0 [ s0 = addr'0 {_1.field_1'0} (fun (_ret':Snapshot.snap_ty int) -> [ &_9 <- _ret' ] s1) | s1 = bb2 ] + | bb2 = s0 + [ s0 = [ &_8 <- _9 ] s1 + | s1 = get_ghost'0 {_5} {_8} (fun (_ret':t_Option'0) -> [ &_3 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'0 {_3} (fun (_ret':t_PtrOwn'0) -> [ &_2 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 [ s0 = new'0 {_2} (fun (_ret':t_GhostBox'1) -> [ &_0 <- _ret' ] s1) | s1 = bb5 ] + | bb5 = return' {_0} ] + + [ & _0 : t_GhostBox'1 = any_l () + | & _1 : closure5'1 = _1 + | & _2 : t_PtrOwn'0 = any_l () + | & _3 : t_Option'0 = any_l () + | & _5 : t_FMap'0 = any_l () + | & _8 : Snapshot.snap_ty int = any_l () + | & _9 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'1)-> {[@expl:closure result type invariant] [%#sunion_find9] inv'9 result} + return' {result} ] + + + predicate resolve'19 (_1 : t_FMap'0) = + true + + predicate resolve'16 (self : t_FMap'0) = + [%#sresolve70] resolve'19 self + + predicate resolve'11 (_1 : t_FMap'0) = + resolve'16 _1 + + predicate resolve'4 (self : t_GhostBox'0) = + [%#sghost45] resolve'11 self.t_GhostBox__0'0 + + predicate resolve'0 (_1 : t_GhostBox'0) = + resolve'4 _1 + + function inner_logic'0 (self : t_GhostBox'1) : t_PtrOwn'0 = + [%#sghost46] self.t_GhostBox__0'2 + + predicate invariant'4 (self : t_Content'0) = + [%#sinvariant67] inv'4 self + + predicate inv'10 (_1 : t_Content'0) + + axiom inv_axiom'10 [@rewrite] : forall x : t_Content'0 [inv'10 x] . inv'10 x = invariant'4 x + + let rec as_ref'0 (ptr:opaque_ptr) (own:t_GhostBox'1) (return' (ret:t_Content'0))= {[@expl:as_ref 'own' type invariant] [%#sptr_own10] inv'9 own} + {[@expl:as_ref requires] [%#sptr_own11] ptr = ptr'0 (inner_logic'0 own)} + any + [ return' (result:t_Content'0)-> {[%#sptr_own12] inv'10 result} + {[%#sptr_own13] result = val'0 (inner_logic'0 own)} + (! return' {result}) ] + + + let rec v_Link'0 (input:t_Content'0) (ret (field_0:t_Element'0))= any + [ good (field_0:t_Element'0)-> {C_Link'0 field_0 = input} (! ret {field_0}) + | bad -> {forall field_0 : t_Element'0 [C_Link'0 field_0 : t_Content'0] . C_Link'0 field_0 <> input} + (! {false} + any) ] + + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset27] Fset.mem e self + + function inner_logic'2 (self : t_GhostBox'2) : t_FMap'0 = + [%#sghost46] self.t_GhostBox__0'1 + + use prelude.prelude.Snapshot + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap79] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap76] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find71] index_logic'3 (inner_logic'2 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping31] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping31] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping31] Map.get self a + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find63] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'2 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'2 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'2 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'2 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'1 (_1 : t_UnionFind'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_UnionFind'0 [inv'1 x] . inv'1 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'2 map + end) + + predicate invariant'5 (self : borrowed (t_GhostBox'2)) = + [%#sinvariant66] inv'2 self.current /\ inv'2 self.final + + predicate inv'11 (_1 : borrowed (t_GhostBox'2)) + + axiom inv_axiom'11 [@rewrite] : forall x : borrowed (t_GhostBox'2) [inv'11 x] . inv'11 x = invariant'5 x + + type t_GhostBox'3 = + { t_GhostBox__0'3: borrowed (t_FMap'0) } + + predicate invariant'18 (self : borrowed (t_FMap'0)) = + [%#sinvariant66] inv'12 self.current /\ inv'12 self.final + + predicate inv'28 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'28 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'28 x] . inv'28 x = invariant'18 x + + predicate invariant'16 (self : borrowed (t_FMap'0)) = + [%#sboxed75] inv'28 self + + predicate inv'26 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'26 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'26 x] . inv'26 x = invariant'16 x + + predicate inv'3 (_1 : t_GhostBox'3) + + axiom inv_axiom'3 [@rewrite] : forall x : t_GhostBox'3 [inv'3 x] . inv'3 x + = match x with + | {t_GhostBox__0'3 = a_0} -> inv'26 a_0 + end + + let rec borrow_mut'0 (self:borrowed (t_GhostBox'2)) (return' (ret:t_GhostBox'3))= {[@expl:borrow_mut 'self' type invariant] [%#sghost14] inv'11 self} + any + [ return' (result:t_GhostBox'3)-> {[%#sghost15] inv'3 result} + {[%#sghost16] result.t_GhostBox__0'3 + = Borrow.borrow_logic (self.current).t_GhostBox__0'1 (self.final).t_GhostBox__0'1 (Borrow.inherit_id (Borrow.get_id self) 1)} + (! return' {result}) ] + + + predicate invariant'17 (self : borrowed (t_GhostBox'3)) = + [%#sinvariant66] inv'3 self.current /\ inv'3 self.final + + predicate inv'27 (_1 : borrowed (t_GhostBox'3)) + + axiom inv_axiom'27 [@rewrite] : forall x : borrowed (t_GhostBox'3) [inv'27 x] . inv'27 x = invariant'17 x + + predicate invariant'8 (self : borrowed (borrowed (t_FMap'0))) = + [%#sinvariant66] inv'28 self.current /\ inv'28 self.final + + predicate inv'14 (_1 : borrowed (borrowed (t_FMap'0))) + + axiom inv_axiom'14 [@rewrite] : forall x : borrowed (borrowed (t_FMap'0)) [inv'14 x] . inv'14 x = invariant'8 x + + let rec deref_mut'0 (self:borrowed (t_GhostBox'3)) (return' (ret:borrowed (borrowed (t_FMap'0))))= {[@expl:deref_mut 'self' type invariant] [%#sghost47] inv'27 self} + any + [ return' (result:borrowed (borrowed (t_FMap'0)))-> {[%#sghost48] inv'14 result} + {[%#sghost49] result + = Borrow.borrow_logic (self.current).t_GhostBox__0'3 (self.final).t_GhostBox__0'3 (Borrow.inherit_id (Borrow.get_id self) 1)} + (! return' {result}) ] + + + type t_Option'1 = + | C_None'1 + | C_Some'1 (borrowed (t_PtrOwn'0)) + + predicate invariant'9 (self : borrowed (t_PtrOwn'0)) = + [%#sinvariant66] inv'13 self.current /\ inv'13 self.final + + predicate inv'15 (_1 : borrowed (t_PtrOwn'0)) + + axiom inv_axiom'15 [@rewrite] : forall x : borrowed (t_PtrOwn'0) [inv'15 x] . inv'15 x = invariant'9 x + + predicate inv'29 (_1 : t_Option'1) + + axiom inv_axiom'29 [@rewrite] : forall x : t_Option'1 [inv'29 x] . inv'29 x + = match x with + | C_None'1 -> true + | C_Some'1 a_0 -> inv'15 a_0 + end + + function len'0 (self : t_FMap'0) : int + + axiom len'0_spec : forall self : t_FMap'0 . [%#sfmap65] len'0 self >= 0 + + let rec get_mut_ghost'0 (self:borrowed (t_FMap'0)) (key:Snapshot.snap_ty int) (return' (ret:t_Option'1))= {[@expl:get_mut_ghost 'self' type invariant] [%#sfmap50] inv'28 self} + {[@expl:get_mut_ghost 'key' type invariant] [%#sfmap51] inv'21 key} + any + [ return' (result:t_Option'1)-> {[%#sfmap52] inv'29 result} + {[%#sfmap53] if contains'1 self.current key then + match result with + | C_None'1 -> false + | C_Some'1 r -> contains'1 self.final key + /\ lookup_unsized'0 self.current key = r.current /\ lookup_unsized'0 self.final key = r.final + end + else + result = C_None'1 /\ self.current = self.final + } + {[%#sfmap54] forall k : Snapshot.snap_ty int . k <> key + -> get_unsized'0 self.current k = get_unsized'0 self.final k} + {[%#sfmap55] len'0 self.current = len'0 self.final} + (! return' {result}) ] + + + let rec unwrap'1 (self:t_Option'1) (return' (ret:borrowed (t_PtrOwn'0)))= {[@expl:unwrap 'self' type invariant] inv'29 self} + {[@expl:unwrap requires] [%#soption41] self <> C_None'1} + any + [ return' (result:borrowed (t_PtrOwn'0))-> {inv'15 result} + {[%#soption41] C_Some'1 result = self} + (! return' {result}) ] + + + type t_GhostBox'4 = + { t_GhostBox__0'4: borrowed (t_PtrOwn'0) } + + predicate invariant'20 (self : borrowed (t_PtrOwn'0)) = + [%#sboxed75] inv'15 self + + predicate inv'32 (_1 : borrowed (t_PtrOwn'0)) + + axiom inv_axiom'31 [@rewrite] : forall x : borrowed (t_PtrOwn'0) [inv'32 x] . inv'32 x = invariant'20 x + + predicate inv'17 (_1 : t_GhostBox'4) + + axiom inv_axiom'17 [@rewrite] : forall x : t_GhostBox'4 [inv'17 x] . inv'17 x + = match x with + | {t_GhostBox__0'4 = a_0} -> inv'32 a_0 + end + + let rec new'1 (x:borrowed (t_PtrOwn'0)) (return' (ret:t_GhostBox'4))= {[@expl:new 'x' type invariant] [%#sghost42] inv'15 x} + any + [ return' (result:t_GhostBox'4)-> {[%#sghost43] inv'17 result} + {[%#sghost44] result.t_GhostBox__0'4 = x} + (! return' {result}) ] + + + predicate resolve'12 (self : borrowed (borrowed (t_FMap'0))) = + [%#sresolve56] self.final = self.current + + predicate resolve'5 (_1 : borrowed (borrowed (t_FMap'0))) = + resolve'12 _1 + + predicate resolve'13 (self : borrowed (t_PtrOwn'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'6 (_1 : borrowed (t_PtrOwn'0)) = + resolve'13 _1 + + type closure6'1 = + { field_0'1: borrowed (t_GhostBox'3); field_1'1: t_Element'0 } + + predicate inv'16 (_1 : closure6'1) + + axiom inv_axiom'16 [@rewrite] : forall x : closure6'1 [inv'16 x] . inv'16 x + = (let {field_0'1 = x0 ; field_1'1 = x1} = x in inv'27 x0) + + predicate resolve'17 (self : borrowed (t_GhostBox'3)) = + [%#sresolve56] self.final = self.current + + predicate resolve'14 (_1 : borrowed (t_GhostBox'3)) = + resolve'17 _1 + + predicate resolve'7 (_1 : closure6'1) = + resolve'14 _1.field_0'1 + + let rec closure6'0 (_1:closure6'1) (return' (ret:t_GhostBox'4))= {[@expl:closure '_1' type invariant] inv'16 _1} + bb0 + [ bb0 = s0 + [ s0 = {inv'3 (_1.field_0'1).current} + Borrow.borrow_final {(_1.field_0'1).current} {Borrow.get_id _1.field_0'1} + (fun (_ret':borrowed (t_GhostBox'3)) -> + [ &_7 <- _ret' ] + -{inv'3 _ret'.final}- + [ &_1 <- { _1 with field_0'1 = { _1.field_0'1 with current = _ret'.final } } ] + s1) + | s1 = deref_mut'0 {_7} (fun (_ret':borrowed (borrowed (t_FMap'0))) -> [ &_6 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 + [ s0 = {inv'12 (_6.current).current} + Borrow.borrow_mut {(_6.current).current} + (fun (_ret':borrowed (t_FMap'0)) -> + [ &_5 <- _ret' ] + -{inv'12 _ret'.final}- + [ &_6 <- { _6 with current = { _6.current with current = _ret'.final } } ] + s1) + | s1 = addr'0 {_1.field_1'1} (fun (_ret':Snapshot.snap_ty int) -> [ &_10 <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = [ &_9 <- _10 ] s1 + | s1 = get_mut_ghost'0 {_5} {_9} (fun (_ret':t_Option'1) -> [ &_4 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'1 {_4} (fun (_ret':borrowed (t_PtrOwn'0)) -> [ &_3 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 + [ s0 = {inv'13 _3.current} + Borrow.borrow_final {_3.current} {Borrow.get_id _3} + (fun (_ret':borrowed (t_PtrOwn'0)) -> + [ &_2 <- _ret' ] + -{inv'13 _ret'.final}- + [ &_3 <- { _3 with current = _ret'.final } ] + s1) + | s1 = new'1 {_2} (fun (_ret':t_GhostBox'4) -> [ &_0 <- _ret' ] s2) + | s2 = bb5 ] + + | bb5 = s0 + [ s0 = {[@expl:type invariant] inv'14 _6} s1 + | s1 = -{resolve'5 _6}- s2 + | s2 = {[@expl:type invariant] inv'15 _3} s3 + | s3 = -{resolve'6 _3}- s4 + | s4 = {[@expl:type invariant] inv'16 _1} s5 + | s5 = -{resolve'7 _1}- s6 + | s6 = return' {_0} ] + ] + + [ & _0 : t_GhostBox'4 = any_l () + | & _1 : closure6'1 = _1 + | & _2 : borrowed (t_PtrOwn'0) = any_l () + | & _3 : borrowed (t_PtrOwn'0) = any_l () + | & _4 : t_Option'1 = any_l () + | & _5 : borrowed (t_FMap'0) = any_l () + | & _6 : borrowed (borrowed (t_FMap'0)) = any_l () + | & _7 : borrowed (t_GhostBox'3) = any_l () + | & _9 : Snapshot.snap_ty int = any_l () + | & _10 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'4)-> {[@expl:closure result type invariant] [%#sunion_find17] inv'17 result} + return' {result} ] + + + function inner_logic'1 (self : t_GhostBox'4) : borrowed (t_PtrOwn'0) = + [%#sghost46] self.t_GhostBox__0'4 + + predicate invariant'1 (self : borrowed (t_Content'0)) = + [%#sinvariant66] inv'4 self.current /\ inv'4 self.final + + predicate inv'5 (_1 : borrowed (t_Content'0)) + + axiom inv_axiom'5 [@rewrite] : forall x : borrowed (t_Content'0) [inv'5 x] . inv'5 x = invariant'1 x + + let rec as_mut'0 (ptr:opaque_ptr) (own:t_GhostBox'4) (return' (ret:borrowed (t_Content'0)))= {[@expl:as_mut 'own' type invariant] [%#sptr_own18] inv'17 own} + {[@expl:as_mut requires] [%#sptr_own19] ptr = ptr'0 (inner_logic'1 own).current} + any + [ return' (result:borrowed (t_Content'0))-> {[%#sptr_own20] inv'5 result} + {[%#sptr_own21] result.current = val'0 (inner_logic'1 own).current} + {[%#sptr_own22] ptr'0 (inner_logic'1 own).final = ptr'0 (inner_logic'1 own).current} + {[%#sptr_own23] val'0 (inner_logic'1 own).final = result.final} + (! return' {result}) ] + + + predicate resolve'8 (self : borrowed (t_Content'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'1 (_1 : borrowed (t_Content'0)) = + resolve'8 _1 + + predicate resolve'21 (self : borrowed (t_FMap'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'20 (_1 : borrowed (t_FMap'0)) = + resolve'21 _1 + + predicate resolve'18 (self : borrowed (t_FMap'0)) = + [%#sresolve70] resolve'20 self + + predicate resolve'15 (_1 : borrowed (t_FMap'0)) = + resolve'18 _1 + + predicate resolve'9 (self : t_GhostBox'3) = + [%#sghost45] resolve'15 self.t_GhostBox__0'3 + + predicate resolve'2 (_1 : t_GhostBox'3) = + resolve'9 _1 + + predicate invariant'2 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant66] inv'1 self.current /\ inv'1 self.final + + predicate inv'6 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'6 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'6 x] . inv'6 x = invariant'2 x + + predicate resolve'10 (self : borrowed (t_UnionFind'0)) = + [%#sresolve56] self.final = self.current + + predicate resolve'3 (_1 : borrowed (t_UnionFind'0)) = + resolve'10 _1 + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find26] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find24] inv'1 self) + -> ([%#sunion_find25] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find30] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find28] inv'1 self) + -> ([%#sunion_find29] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find60] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find58] inv'1 self) + -> ([%#sunion_find59] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'2 (values'0 self) e = index_logic'2 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate unchanged'0 [#"union_find.rs" 163 8 163 43] (self : borrowed (t_UnionFind'0)) = + [%#sunion_find32] domain'0 self.current = domain'0 self.final + /\ root_of'0 self.current = root_of'0 self.final /\ values'0 self.current = values'0 self.final + + meta "compute_max_steps" 1000000 + + let rec find_inner'0 (self:borrowed (t_UnionFind'0)) (elem:t_Element'0) (return' (ret:t_Element'0))= {[@expl:find_inner 'self' type invariant] [%#sunion_find0] inv'6 self} + {[@expl:find_inner requires] [%#sunion_find1] contains'0 (domain'0 self.current) elem} + (! bb0 + [ bb0 = s0 + [ s0 = borrow'0 {(self.current).t_UnionFind__map'0} (fun (_ret':t_GhostBox'0) -> [ &map <- _ret' ] s1) + | s1 = bb1 ] + + | bb1 = s0 + [ s0 = [ &_11 <- { field_0'0 = map; field_1'0 = elem } ] s1 + | s1 = closure5'0 {_11} (fun (_ret':t_GhostBox'1) -> [ &perm <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = {[@expl:type invariant] inv'0 map} s1 + | s1 = -{resolve'0 map}- s2 + | s2 = as_ref'0 {elem.t_Element__0'0} {perm} (fun (_ret':t_Content'0) -> [ &value <- _ret' ] s3) + | s3 = bb3 ] + + | bb3 = any + [ br0 (x0:usize) (x1:t_T'0)-> {value = C_Root'0 x0 x1} (! bb5) + | br1 (x0:t_Element'0)-> {value = C_Link'0 x0} (! bb6) ] + + | bb6 = s0 + [ s0 = v_Link'0 {value} (fun (r0'0:t_Element'0) -> [ &e <- r0'0 ] s1) + | s1 = {inv'1 self.current} + Borrow.borrow_mut {self.current} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_21 <- _ret' ] + -{inv'1 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s2) + | s2 = find_inner'0 {_21} {e} (fun (_ret':t_Element'0) -> [ &root <- _ret' ] s3) + | s3 = bb8 ] + + | bb8 = s0 + [ s0 = {inv'2 (self.current).t_UnionFind__map'0} + Borrow.borrow_final + + {(self.current).t_UnionFind__map'0} + {Borrow.inherit_id (Borrow.get_id self) 2} + (fun (_ret':borrowed (t_GhostBox'2)) -> + [ &_24 <- _ret' ] + -{inv'2 _ret'.final}- + [ &self <- { self with current = { self.current with t_UnionFind__map'0 = _ret'.final } } ] + s1) + | s1 = borrow_mut'0 {_24} (fun (_ret':t_GhostBox'3) -> [ &map1 <- _ret' ] s2) + | s2 = bb9 ] + + | bb9 = s0 + [ s0 = {inv'3 map1} + Borrow.borrow_mut {map1} + (fun (_ret':borrowed (t_GhostBox'3)) -> [ &_27 <- _ret' ] -{inv'3 _ret'.final}- [ &map1 <- _ret'.final ] s1) + | s1 = [ &_26 <- { field_0'1 = _27; field_1'1 = elem } ] s2 + | s2 = closure6'0 {_26} (fun (_ret':t_GhostBox'4) -> [ &mut_perm <- _ret' ] s3) + | s3 = bb10 ] + + | bb10 = s0 + [ s0 = [ &_30 <- C_Link'0 root ] s1 + | s1 = as_mut'0 {elem.t_Element__0'0} {mut_perm} (fun (_ret':borrowed (t_Content'0)) -> [ &_32 <- _ret' ] s2) + | s2 = bb11 ] + + | bb11 = bb12 + | bb12 = s0 + [ s0 = {[@expl:type invariant] match _32 with + | {current = x'0} -> inv'4 x'0 + | _ -> true + end} + s1 + | s1 = [ &_32 <- { _32 with current = _30 } ] s2 + | s2 = {[@expl:type invariant] inv'5 _32} s3 + | s3 = -{resolve'1 _32}- s4 + | s4 = {[@expl:type invariant] inv'3 map1} s5 + | s5 = -{resolve'2 map1}- s6 + | s6 = {[@expl:type invariant] inv'6 self} s7 + | s7 = -{resolve'3 self}- s8 + | s8 = bb14 ] + + | bb14 = s0 [ s0 = [ &_0 <- root ] s1 | s1 = bb15 ] + | bb15 = bb16 + | bb16 = bb17 + | bb5 = bb7 + | bb7 = s0 + [ s0 = {[@expl:type invariant] inv'6 self} s1 + | s1 = -{resolve'3 self}- s2 + | s2 = [ &_0 <- elem ] s3 + | s3 = bb17 ] + + | bb17 = bb18 + | bb18 = bb19 + | bb19 = return' {_0} ] + ) + [ & _0 : t_Element'0 = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & elem : t_Element'0 = elem + | & map : t_GhostBox'0 = any_l () + | & perm : t_GhostBox'1 = any_l () + | & _11 : closure5'1 = any_l () + | & _14 : () = any_l () + | & value : t_Content'0 = any_l () + | & e : t_Element'0 = any_l () + | & root : t_Element'0 = any_l () + | & _21 : borrowed (t_UnionFind'0) = any_l () + | & map1 : t_GhostBox'3 = any_l () + | & _24 : borrowed (t_GhostBox'2) = any_l () + | & mut_perm : t_GhostBox'4 = any_l () + | & _26 : closure6'1 = any_l () + | & _27 : borrowed (t_GhostBox'3) = any_l () + | & _29 : () = any_l () + | & _30 : t_Content'0 = any_l () + | & _32 : borrowed (t_Content'0) = any_l () ] + + [ return' (result:t_Element'0)-> {[@expl:find_inner ensures #0] [%#sunion_find2] result + = index_logic'0 (root_of'0 self.current) elem} + {[@expl:find_inner ensures #1] [%#sunion_find3] unchanged'0 self} + {[@expl:find_inner ensures #2] [%#sunion_find4] (self.final).t_UnionFind__distance'0 + = (self.current).t_UnionFind__distance'0} + {[@expl:find_inner ensures #3] [%#sunion_find5] index_logic'1 (Snapshot.inner (self.current).t_UnionFind__distance'0) result + >= index_logic'1 (Snapshot.inner (self.current).t_UnionFind__distance'0) elem} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__find [#"union_find.rs" 222 8 222 62] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 222 25 222 29 + let%span sunion_find1 = "union_find.rs" 219 19 219 47 + let%span sunion_find2 = "union_find.rs" 220 18 220 48 + let%span sunion_find3 = "union_find.rs" 221 18 221 34 + let%span sunion_find4 = "union_find.rs" 201 27 201 31 + let%span sunion_find5 = "union_find.rs" 195 19 195 47 + let%span sunion_find6 = "union_find.rs" 196 18 196 48 + let%span sunion_find7 = "union_find.rs" 197 18 197 34 + let%span sunion_find8 = "union_find.rs" 199 18 199 54 + let%span sunion_find9 = "union_find.rs" 200 18 200 62 + let%span sunion_find10 = "union_find.rs" 133 19 133 28 + let%span sunion_find11 = "union_find.rs" 134 18 134 150 + let%span sunion_find12 = "union_find.rs" 131 8 131 16 + let%span sfset13 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find14 = "union_find.rs" 145 19 145 28 + let%span sunion_find15 = "union_find.rs" 146 18 146 98 + let%span sunion_find16 = "union_find.rs" 143 8 143 16 + let%span smapping17 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find18 = "union_find.rs" 165 16 167 52 + let%span sresolve19 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sunion_find20 = "union_find.rs" 21 8 21 16 + let%span sunion_find21 = "union_find.rs" 154 19 154 28 + let%span sunion_find22 = "union_find.rs" 155 18 155 106 + let%span sunion_find23 = "union_find.rs" 152 8 152 16 + let%span sunion_find24 = "union_find.rs" 80 8 80 20 + let%span sinvariant25 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sghost26 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap27 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find28 = "union_find.rs" 125 8 125 16 + let%span sfmap29 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap30 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap31 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap32 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap33 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed34 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil35 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil36 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap37 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own38 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr39 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr40 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset13] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find20] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost26] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap31] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap29] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap27] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil35] op <> C_None'0) + -> ([%#sutil36] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap33] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap32] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap30] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find28] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping17] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping17] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping17] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find24] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'2 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'2 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'2 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'1 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'5 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'5 [@rewrite] : forall x : Snapshot.snap_ty int [inv'5 x] . inv'5 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr40] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr39] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'10 (_1 : t_T'0) + + predicate inv'9 (_1 : t_Content'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_Content'0 [inv'9 x] . inv'9 x + = match x with + | C_Root'0 rank value -> inv'10 value + | C_Link'0 a_0 -> true + end + + predicate invariant'6 (self : t_Content'0) = + [%#sboxed34] inv'9 self + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x = invariant'6 x + + predicate invariant'5 (self : t_PtrOwn'0) = + [%#sptr_own38] not is_null_logic'0 (ptr'0 self) /\ inv'8 (val'0 self) + + predicate inv'7 (_1 : t_PtrOwn'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_PtrOwn'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sboxed34] inv'7 self + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_FMap'0) = + [%#sfmap37] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'5 k /\ inv'6 (lookup_unsized'0 self k) + + predicate inv'4 (_1 : t_FMap'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_FMap'0 [inv'4 x] . inv'4 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sboxed34] inv'4 self + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate inv'2 (_1 : t_GhostBox'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'0 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'3 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'2 map + end) + + predicate invariant'1 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant25] inv'0 self.current /\ inv'0 self.final + + predicate inv'1 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'1 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'1 x] . inv'1 x = invariant'1 x + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find12] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find10] inv'0 self) + -> ([%#sunion_find11] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find16] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find14] inv'0 self) + -> ([%#sunion_find15] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find23] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find21] inv'0 self) + -> ([%#sunion_find22] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'2 (values'0 self) e = index_logic'2 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate unchanged'0 [#"union_find.rs" 163 8 163 43] (self : borrowed (t_UnionFind'0)) = + [%#sunion_find18] domain'0 self.current = domain'0 self.final + /\ root_of'0 self.current = root_of'0 self.final /\ values'0 self.current = values'0 self.final + + let rec find_inner'0 (self:borrowed (t_UnionFind'0)) (elem:t_Element'0) (return' (ret:t_Element'0))= {[@expl:find_inner 'self' type invariant] [%#sunion_find4] inv'1 self} + {[@expl:find_inner requires] [%#sunion_find5] contains'0 (domain'0 self.current) elem} + any + [ return' (result:t_Element'0)-> {[%#sunion_find6] result = index_logic'0 (root_of'0 self.current) elem} + {[%#sunion_find7] unchanged'0 self} + {[%#sunion_find8] (self.final).t_UnionFind__distance'0 = (self.current).t_UnionFind__distance'0} + {[%#sunion_find9] index_logic'1 (Snapshot.inner (self.current).t_UnionFind__distance'0) result + >= index_logic'1 (Snapshot.inner (self.current).t_UnionFind__distance'0) elem} + (! return' {result}) ] + + + predicate resolve'1 (self : borrowed (t_UnionFind'0)) = + [%#sresolve19] self.final = self.current + + predicate resolve'0 (_1 : borrowed (t_UnionFind'0)) = + resolve'1 _1 + + use prelude.prelude.Intrinsic + + meta "compute_max_steps" 1000000 + + let rec find'0 (self:borrowed (t_UnionFind'0)) (elem:t_Element'0) (return' (ret:t_Element'0))= {[@expl:find 'self' type invariant] [%#sunion_find0] inv'1 self} + {[@expl:find requires] [%#sunion_find1] contains'0 (domain'0 self.current) elem} + (! bb0 + [ bb0 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_final {self.current} {Borrow.get_id self} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_6 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = find_inner'0 {_6} {elem} (fun (_ret':t_Element'0) -> [ &_0 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 [ s0 = {[@expl:type invariant] inv'1 self} s1 | s1 = -{resolve'0 self}- s2 | s2 = return' {_0} ] ] + ) + [ & _0 : t_Element'0 = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & elem : t_Element'0 = elem + | & _6 : borrowed (t_UnionFind'0) = any_l () ] + + [ return' (result:t_Element'0)-> {[@expl:find ensures #0] [%#sunion_find2] result + = index_logic'0 (root_of'0 self.current) elem} + {[@expl:find ensures #1] [%#sunion_find3] unchanged'0 self} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__get [#"union_find.rs" 232 8 232 49] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 232 20 232 24 + let%span sunion_find1 = "union_find.rs" 229 19 229 47 + let%span sunion_find2 = "union_find.rs" 230 19 230 47 + let%span sunion_find3 = "union_find.rs" 232 47 232 49 + let%span sunion_find4 = "union_find.rs" 231 18 231 48 + let%span sghost5 = "../../../creusot-contracts/src/ghost.rs" 124 19 124 23 + let%span sghost6 = "../../../creusot-contracts/src/ghost.rs" 124 4 124 40 + let%span sghost7 = "../../../creusot-contracts/src/ghost.rs" 123 14 123 35 + let%span sunion_find8 = "union_find.rs" 234 23 234 67 + let%span sptr_own9 = "../../../creusot-contracts/src/ptr_own.rs" 71 34 71 37 + let%span sptr_own10 = "../../../creusot-contracts/src/ptr_own.rs" 68 15 68 31 + let%span sptr_own11 = "../../../creusot-contracts/src/ptr_own.rs" 71 4 71 66 + let%span sptr_own12 = "../../../creusot-contracts/src/ptr_own.rs" 69 14 69 35 + let%span sunion_find13 = "union_find.rs" 133 19 133 28 + let%span sunion_find14 = "union_find.rs" 134 18 134 150 + let%span sunion_find15 = "union_find.rs" 131 8 131 16 + let%span sfset16 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find17 = "union_find.rs" 145 19 145 28 + let%span sunion_find18 = "union_find.rs" 146 18 146 98 + let%span sunion_find19 = "union_find.rs" 143 8 143 16 + let%span smapping20 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find21 = "union_find.rs" 154 19 154 28 + let%span sunion_find22 = "union_find.rs" 155 18 155 106 + let%span sunion_find23 = "union_find.rs" 152 8 152 16 + let%span sghost24 = "../../../creusot-contracts/src/ghost.rs" 69 14 69 18 + let%span sghost25 = "../../../creusot-contracts/src/ghost.rs" 69 4 69 36 + let%span sghost26 = "../../../creusot-contracts/src/ghost.rs" 68 14 68 35 + let%span sunion_find27 = "union_find.rs" 30 18 30 46 + let%span sfmap28 = "../../../creusot-contracts/src/logic/fmap.rs" 314 22 314 26 + let%span sfmap29 = "../../../creusot-contracts/src/logic/fmap.rs" 314 28 314 31 + let%span sfmap30 = "../../../creusot-contracts/src/logic/fmap.rs" 314 4 314 50 + let%span sfmap31 = "../../../creusot-contracts/src/logic/fmap.rs" 306 4 313 11 + let%span soption32 = "../../../creusot-contracts/src/std/option.rs" 31 0 423 1 + let%span sghost33 = "../../../creusot-contracts/src/ghost.rs" 181 15 181 16 + let%span sghost34 = "../../../creusot-contracts/src/ghost.rs" 181 4 181 28 + let%span sghost35 = "../../../creusot-contracts/src/ghost.rs" 179 14 179 28 + let%span sghost36 = "../../../creusot-contracts/src/ghost.rs" 110 8 110 24 + let%span sghost37 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sunion_find38 = "union_find.rs" 21 8 21 16 + let%span sfmap39 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sfmap40 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sinvariant41 = "../../../creusot-contracts/src/invariant.rs" 24 8 24 18 + let%span sfmap42 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sutil43 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil44 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sresolve45 = "../../../creusot-contracts/src/resolve.rs" 68 8 68 23 + let%span sunion_find46 = "union_find.rs" 80 8 80 20 + let%span sfmap47 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sboxed48 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sunion_find49 = "union_find.rs" 125 8 125 16 + let%span sfmap50 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap51 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap52 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own53 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr54 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr55 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'2 = + { t_GhostBox__0'1: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'2; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Borrow + + type t_PtrOwn'0 + + type t_Option'1 = + | C_None'1 + | C_Some'1 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'1) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap47] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'1 = + [%#sfmap42] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap39] get_unsized'0 self k <> C_None'1 + + predicate inv'22 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'21 [@rewrite] : forall x : Snapshot.snap_ty int [inv'22 x] . inv'22 x = true + + function unwrap'1 (op : t_Option'1) : t_PtrOwn'0 + + axiom unwrap'1_spec : forall op : t_Option'1 . ([%#sutil43] op <> C_None'1) + -> ([%#sutil44] C_Some'1 (unwrap'1 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap40] unwrap'1 (get_unsized'0 self k) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + function addr_logic'0 (self : opaque_ptr) : int + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr55] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr54] is_null_logic'0 self = (addr_logic'0 self = 0) + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + predicate inv'17 (_1 : t_T'0) + + predicate inv'18 (_1 : t_Content'0) + + axiom inv_axiom'17 [@rewrite] : forall x : t_Content'0 [inv'18 x] . inv'18 x + = match x with + | C_Root'0 rank value -> inv'17 value + | C_Link'0 a_0 -> true + end + + predicate invariant'15 (self : t_Content'0) = + [%#sboxed48] inv'18 self + + predicate inv'24 (_1 : t_Content'0) + + axiom inv_axiom'23 [@rewrite] : forall x : t_Content'0 [inv'24 x] . inv'24 x = invariant'15 x + + predicate invariant'12 (self : t_PtrOwn'0) = + [%#sptr_own53] not is_null_logic'0 (ptr'0 self) /\ inv'24 (val'0 self) + + predicate inv'20 (_1 : t_PtrOwn'0) + + axiom inv_axiom'19 [@rewrite] : forall x : t_PtrOwn'0 [inv'20 x] . inv'20 x = invariant'12 x + + predicate invariant'14 (self : t_PtrOwn'0) = + [%#sboxed48] inv'20 self + + predicate inv'23 (_1 : t_PtrOwn'0) + + axiom inv_axiom'22 [@rewrite] : forall x : t_PtrOwn'0 [inv'23 x] . inv'23 x = invariant'14 x + + predicate invariant'11 (self : t_FMap'0) = + [%#sfmap52] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'22 k /\ inv'23 (lookup_unsized'0 self k) + + predicate inv'19 (_1 : t_FMap'0) + + axiom inv_axiom'18 [@rewrite] : forall x : t_FMap'0 [inv'19 x] . inv'19 x = invariant'11 x + + predicate invariant'13 (self : t_FMap'0) = + [%#sboxed48] inv'19 self + + predicate inv'21 (_1 : t_FMap'0) + + axiom inv_axiom'20 [@rewrite] : forall x : t_FMap'0 [inv'21 x] . inv'21 x = invariant'13 x + + predicate inv'16 (_1 : t_GhostBox'2) + + axiom inv_axiom'16 [@rewrite] : forall x : t_GhostBox'2 [inv'16 x] . inv'16 x + = match x with + | {t_GhostBox__0'1 = a_0} -> inv'21 a_0 + end + + predicate invariant'2 (self : t_GhostBox'2) = + [%#sinvariant41] inv'16 self + + predicate inv'3 (_1 : t_GhostBox'2) + + axiom inv_axiom'3 [@rewrite] : forall x : t_GhostBox'2 [inv'3 x] . inv'3 x = invariant'2 x + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + predicate invariant'7 (self : t_FMap'0) = + [%#sinvariant41] inv'19 self + + predicate inv'10 (_1 : t_FMap'0) + + axiom inv_axiom'10 [@rewrite] : forall x : t_FMap'0 [inv'10 x] . inv'10 x = invariant'7 x + + predicate invariant'9 (self : t_FMap'0) = + [%#sboxed48] inv'10 self + + predicate inv'14 (_1 : t_FMap'0) + + axiom inv_axiom'14 [@rewrite] : forall x : t_FMap'0 [inv'14 x] . inv'14 x = invariant'9 x + + predicate inv'0 (_1 : t_GhostBox'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_GhostBox'0 [inv'0 x] . inv'0 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'14 a_0 + end + + let rec borrow'0 (self:t_GhostBox'2) (return' (ret:t_GhostBox'0))= {[@expl:borrow 'self' type invariant] [%#sghost5] inv'3 self} + any + [ return' (result:t_GhostBox'0)-> {[%#sghost6] inv'0 result} + {[%#sghost7] result.t_GhostBox__0'0 = self.t_GhostBox__0'1} + (! return' {result}) ] + + + predicate invariant'5 (self : t_GhostBox'0) = + [%#sinvariant41] inv'0 self + + predicate inv'8 (_1 : t_GhostBox'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_GhostBox'0 [inv'8 x] . inv'8 x = invariant'5 x + + predicate invariant'6 (self : t_FMap'0) = + [%#sinvariant41] inv'10 self + + predicate inv'9 (_1 : t_FMap'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_FMap'0 [inv'9 x] . inv'9 x = invariant'6 x + + let rec deref'0 (self:t_GhostBox'0) (return' (ret:t_FMap'0))= {[@expl:deref 'self' type invariant] [%#sghost24] inv'8 self} + any + [ return' (result:t_FMap'0)-> {[%#sghost25] inv'9 result} + {[%#sghost26] self.t_GhostBox__0'0 = result} + (! return' {result}) ] + + + use prelude.prelude.Snapshot + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find38] addr_logic'0 self.t_Element__0'0 + + let rec addr'0 (self:t_Element'0) (return' (ret:Snapshot.snap_ty int))= any + [ return' (result:Snapshot.snap_ty int)-> {[%#sunion_find27] Snapshot.inner result = deep_model'0 self} + (! return' {result}) ] + + + predicate inv'11 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'11 [@rewrite] : forall x : Snapshot.snap_ty int [inv'11 x] . inv'11 x = true + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + predicate invariant'8 (self : t_PtrOwn'0) = + [%#sinvariant41] inv'20 self + + predicate inv'13 (_1 : t_PtrOwn'0) + + axiom inv_axiom'13 [@rewrite] : forall x : t_PtrOwn'0 [inv'13 x] . inv'13 x = invariant'8 x + + predicate inv'12 (_1 : t_Option'0) + + axiom inv_axiom'12 [@rewrite] : forall x : t_Option'0 [inv'12 x] . inv'12 x + = match x with + | C_None'0 -> true + | C_Some'0 a_0 -> inv'13 a_0 + end + + let rec get_ghost'0 (self:t_FMap'0) (key:Snapshot.snap_ty int) (return' (ret:t_Option'0))= {[@expl:get_ghost 'self' type invariant] [%#sfmap28] inv'10 self} + {[@expl:get_ghost 'key' type invariant] [%#sfmap29] inv'11 key} + any + [ return' (result:t_Option'0)-> {[%#sfmap30] inv'12 result} + {[%#sfmap31] if contains'1 self key then + match result with + | C_None'0 -> false + | C_Some'0 r -> lookup_unsized'0 self key = r + end + else + result = C_None'0 + } + (! return' {result}) ] + + + let rec unwrap'0 (self:t_Option'0) (return' (ret:t_PtrOwn'0))= {[@expl:unwrap 'self' type invariant] inv'12 self} + {[@expl:unwrap requires] [%#soption32] self <> C_None'0} + any [ return' (result:t_PtrOwn'0)-> {inv'13 result} {[%#soption32] C_Some'0 result = self} (! return' {result}) ] + + type t_GhostBox'1 = + { t_GhostBox__0'2: t_PtrOwn'0 } + + predicate invariant'10 (self : t_PtrOwn'0) = + [%#sboxed48] inv'13 self + + predicate inv'15 (_1 : t_PtrOwn'0) + + axiom inv_axiom'15 [@rewrite] : forall x : t_PtrOwn'0 [inv'15 x] . inv'15 x = invariant'10 x + + predicate inv'5 (_1 : t_GhostBox'1) + + axiom inv_axiom'5 [@rewrite] : forall x : t_GhostBox'1 [inv'5 x] . inv'5 x + = match x with + | {t_GhostBox__0'2 = a_0} -> inv'15 a_0 + end + + let rec new'0 (x:t_PtrOwn'0) (return' (ret:t_GhostBox'1))= {[@expl:new 'x' type invariant] [%#sghost33] inv'13 x} + any + [ return' (result:t_GhostBox'1)-> {[%#sghost34] inv'5 result} + {[%#sghost35] result.t_GhostBox__0'2 = x} + (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + type closure3'1 = + { field_0'0: t_GhostBox'0; field_1'0: t_Element'0 } + + predicate inv'4 (_1 : closure3'1) + + axiom inv_axiom'4 [@rewrite] : forall x : closure3'1 [inv'4 x] . inv'4 x + = (let {field_0'0 = x0 ; field_1'0 = x1} = x in inv'8 x0) + + let rec closure3'0 (_1:closure3'1) (return' (ret:t_GhostBox'1))= {[@expl:closure '_1' type invariant] inv'4 _1} + bb0 + [ bb0 = s0 [ s0 = deref'0 {_1.field_0'0} (fun (_ret':t_FMap'0) -> [ &_5 <- _ret' ] s1) | s1 = bb1 ] + | bb1 = s0 [ s0 = addr'0 {_1.field_1'0} (fun (_ret':Snapshot.snap_ty int) -> [ &_9 <- _ret' ] s1) | s1 = bb2 ] + | bb2 = s0 + [ s0 = [ &_8 <- _9 ] s1 + | s1 = get_ghost'0 {_5} {_8} (fun (_ret':t_Option'0) -> [ &_3 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'0 {_3} (fun (_ret':t_PtrOwn'0) -> [ &_2 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 [ s0 = new'0 {_2} (fun (_ret':t_GhostBox'1) -> [ &_0 <- _ret' ] s1) | s1 = bb5 ] + | bb5 = return' {_0} ] + + [ & _0 : t_GhostBox'1 = any_l () + | & _1 : closure3'1 = _1 + | & _2 : t_PtrOwn'0 = any_l () + | & _3 : t_Option'0 = any_l () + | & _5 : t_FMap'0 = any_l () + | & _8 : Snapshot.snap_ty int = any_l () + | & _9 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'1)-> {[@expl:closure result type invariant] [%#sunion_find8] inv'5 result} + return' {result} ] + + + predicate resolve'4 (_1 : t_FMap'0) = + true + + predicate resolve'3 (self : t_FMap'0) = + [%#sresolve45] resolve'4 self + + predicate resolve'2 (_1 : t_FMap'0) = + resolve'3 _1 + + predicate resolve'1 (self : t_GhostBox'0) = + [%#sghost36] resolve'2 self.t_GhostBox__0'0 + + predicate resolve'0 (_1 : t_GhostBox'0) = + resolve'1 _1 + + function inner_logic'0 (self : t_GhostBox'1) : t_PtrOwn'0 = + [%#sghost37] self.t_GhostBox__0'2 + + predicate invariant'3 (self : t_Content'0) = + [%#sinvariant41] inv'18 self + + predicate inv'6 (_1 : t_Content'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_Content'0 [inv'6 x] . inv'6 x = invariant'3 x + + let rec as_ref'0 (ptr:opaque_ptr) (own:t_GhostBox'1) (return' (ret:t_Content'0))= {[@expl:as_ref 'own' type invariant] [%#sptr_own9] inv'5 own} + {[@expl:as_ref requires] [%#sptr_own10] ptr = ptr'0 (inner_logic'0 own)} + any + [ return' (result:t_Content'0)-> {[%#sptr_own11] inv'6 result} + {[%#sptr_own12] result = val'0 (inner_logic'0 own)} + (! return' {result}) ] + + + let rec v_Root'0 (input:t_Content'0) (ret (rank:usize) (value:t_T'0))= any + [ good (rank:usize) (value:t_T'0)-> {C_Root'0 rank value = input} (! ret {rank} {value}) + | bad -> {forall rank : usize, value : t_T'0 [C_Root'0 rank value : t_Content'0] . C_Root'0 rank value <> input} + (! {false} + any) ] + + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset16] Fset.mem e self + + function inner_logic'1 (self : t_GhostBox'2) : t_FMap'0 = + [%#sghost37] self.t_GhostBox__0'1 + + use prelude.prelude.Snapshot + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap51] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap50] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find49] index_logic'3 (inner_logic'1 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping20] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping20] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping20] Map.get self a + + predicate invariant'4 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find46] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'1 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'7 (_1 : t_UnionFind'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_UnionFind'0 [inv'7 x] . inv'7 x + = (invariant'4 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'16 map + end) + + predicate invariant'0 (self : t_UnionFind'0) = + [%#sinvariant41] inv'7 self + + predicate inv'1 (_1 : t_UnionFind'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_UnionFind'0 [inv'1 x] . inv'1 x = invariant'0 x + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find15] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find13] inv'7 self) + -> ([%#sunion_find14] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find19] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find17] inv'7 self) + -> ([%#sunion_find18] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate invariant'1 (self : t_T'0) = + [%#sinvariant41] inv'17 self + + predicate inv'2 (_1 : t_T'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_T'0 [inv'2 x] . inv'2 x = invariant'1 x + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find23] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find21] inv'7 self) + -> ([%#sunion_find22] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + meta "compute_max_steps" 1000000 + + let rec get'0 (self:t_UnionFind'0) (elem:t_Element'0) (return' (ret:t_T'0))= {[@expl:get 'self' type invariant] [%#sunion_find0] inv'1 self} + {[@expl:get requires #0] [%#sunion_find1] contains'0 (domain'0 self) elem} + {[@expl:get requires #1] [%#sunion_find2] index_logic'0 (root_of'0 self) elem = elem} + (! bb0 + [ bb0 = s0 + [ s0 = borrow'0 {self.t_UnionFind__map'0} (fun (_ret':t_GhostBox'0) -> [ &map <- _ret' ] s1) | s1 = bb1 ] + + | bb1 = s0 + [ s0 = [ &_9 <- { field_0'0 = map; field_1'0 = elem } ] s1 + | s1 = closure3'0 {_9} (fun (_ret':t_GhostBox'1) -> [ &perm <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = {[@expl:type invariant] inv'0 map} s1 + | s1 = -{resolve'0 map}- s2 + | s2 = as_ref'0 {elem.t_Element__0'0} {perm} (fun (_ret':t_Content'0) -> [ &_13 <- _ret' ] s3) + | s3 = bb3 ] + + | bb3 = any + [ br0 (x0:usize) (x1:t_T'0)-> {_13 = C_Root'0 x0 x1} (! bb5) + | br1 (x0:t_Element'0)-> {_13 = C_Link'0 x0} (! bb4) ] + + | bb4 = bb7 + | bb7 = bb7 [ bb7 = (! bb8) [ bb8 = bb7 ] ] + | bb5 = bb6 + | bb6 = s0 + [ s0 = v_Root'0 {_13} (fun (rrank'0:usize) (rvalue'0:t_T'0) -> [ &value <- rvalue'0 ] s1) + | s1 = [ &_0 <- value ] s2 + | s2 = bb9 ] + + | bb9 = bb10 + | bb10 = return' {_0} ] + ) + [ & _0 : t_T'0 = any_l () + | & self : t_UnionFind'0 = self + | & elem : t_Element'0 = elem + | & map : t_GhostBox'0 = any_l () + | & perm : t_GhostBox'1 = any_l () + | & _9 : closure3'1 = any_l () + | & _12 : () = any_l () + | & _13 : t_Content'0 = any_l () + | & value : t_T'0 = any_l () ] + + [ return' (result:t_T'0)-> {[@expl:get result type invariant] [%#sunion_find3] inv'2 result} + {[@expl:get ensures] [%#sunion_find4] result = index_logic'1 (values'0 self) elem} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__equiv [#"union_find.rs" 246 8 246 71] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 246 26 246 30 + let%span sunion_find1 = "union_find.rs" 242 19 242 48 + let%span sunion_find2 = "union_find.rs" 243 19 243 48 + let%span sunion_find3 = "union_find.rs" 244 18 244 70 + let%span sunion_find4 = "union_find.rs" 245 18 245 34 + let%span sunion_find5 = "union_find.rs" 222 25 222 29 + let%span sunion_find6 = "union_find.rs" 219 19 219 47 + let%span sunion_find7 = "union_find.rs" 220 18 220 48 + let%span sunion_find8 = "union_find.rs" 221 18 221 34 + let%span sptr9 = "../../../creusot-contracts/src/std/ptr.rs" 131 22 131 66 + let%span sunion_find10 = "union_find.rs" 133 19 133 28 + let%span sunion_find11 = "union_find.rs" 134 18 134 150 + let%span sunion_find12 = "union_find.rs" 131 8 131 16 + let%span sfset13 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find14 = "union_find.rs" 145 19 145 28 + let%span sunion_find15 = "union_find.rs" 146 18 146 98 + let%span sunion_find16 = "union_find.rs" 143 8 143 16 + let%span smapping17 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find18 = "union_find.rs" 165 16 167 52 + let%span sresolve19 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sunion_find20 = "union_find.rs" 21 8 21 16 + let%span sunion_find21 = "union_find.rs" 154 19 154 28 + let%span sunion_find22 = "union_find.rs" 155 18 155 106 + let%span sunion_find23 = "union_find.rs" 152 8 152 16 + let%span sunion_find24 = "union_find.rs" 80 8 80 20 + let%span sinvariant25 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sghost26 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap27 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find28 = "union_find.rs" 125 8 125 16 + let%span sfmap29 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap30 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap31 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap32 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap33 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed34 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil35 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil36 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap37 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own38 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr39 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr40 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset13] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find20] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost26] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap31] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap29] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap27] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil35] op <> C_None'0) + -> ([%#sutil36] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap33] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap32] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap30] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find28] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping17] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping17] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping17] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find24] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'5 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'5 [@rewrite] : forall x : Snapshot.snap_ty int [inv'5 x] . inv'5 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr40] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr39] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'10 (_1 : t_T'0) + + predicate inv'9 (_1 : t_Content'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_Content'0 [inv'9 x] . inv'9 x + = match x with + | C_Root'0 rank value -> inv'10 value + | C_Link'0 a_0 -> true + end + + predicate invariant'6 (self : t_Content'0) = + [%#sboxed34] inv'9 self + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x = invariant'6 x + + predicate invariant'5 (self : t_PtrOwn'0) = + [%#sptr_own38] not is_null_logic'0 (ptr'0 self) /\ inv'8 (val'0 self) + + predicate inv'7 (_1 : t_PtrOwn'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_PtrOwn'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sboxed34] inv'7 self + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_FMap'0) = + [%#sfmap37] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'5 k /\ inv'6 (lookup_unsized'0 self k) + + predicate inv'4 (_1 : t_FMap'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_FMap'0 [inv'4 x] . inv'4 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sboxed34] inv'4 self + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate inv'2 (_1 : t_GhostBox'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'0 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'3 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'2 map + end) + + predicate invariant'1 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant25] inv'0 self.current /\ inv'0 self.final + + predicate inv'1 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'1 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'1 x] . inv'1 x = invariant'1 x + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find12] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find10] inv'0 self) + -> ([%#sunion_find11] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find16] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find14] inv'0 self) + -> ([%#sunion_find15] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find23] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find21] inv'0 self) + -> ([%#sunion_find22] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate unchanged'0 [#"union_find.rs" 163 8 163 43] (self : borrowed (t_UnionFind'0)) = + [%#sunion_find18] domain'0 self.current = domain'0 self.final + /\ root_of'0 self.current = root_of'0 self.final /\ values'0 self.current = values'0 self.final + + let rec find'0 (self:borrowed (t_UnionFind'0)) (elem:t_Element'0) (return' (ret:t_Element'0))= {[@expl:find 'self' type invariant] [%#sunion_find5] inv'1 self} + {[@expl:find requires] [%#sunion_find6] contains'0 (domain'0 self.current) elem} + any + [ return' (result:t_Element'0)-> {[%#sunion_find7] result = index_logic'0 (root_of'0 self.current) elem} + {[%#sunion_find8] unchanged'0 self} + (! return' {result}) ] + + + predicate resolve'1 (self : borrowed (t_UnionFind'0)) = + [%#sresolve19] self.final = self.current + + predicate resolve'0 (_1 : borrowed (t_UnionFind'0)) = + resolve'1 _1 + + let rec addr_eq'0 (p:opaque_ptr) (q:opaque_ptr) (return' (ret:bool))= any + [ return' (result:bool)-> {[%#sptr9] result = (addr_logic'0 p = addr_logic'0 q)} (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + meta "compute_max_steps" 1000000 + + let rec equiv'0 (self:borrowed (t_UnionFind'0)) (e1:t_Element'0) (e2:t_Element'0) (return' (ret:bool))= {[@expl:equiv 'self' type invariant] [%#sunion_find0] inv'1 self} + {[@expl:equiv requires #0] [%#sunion_find1] contains'0 (domain'0 self.current) e1} + {[@expl:equiv requires #1] [%#sunion_find2] contains'0 (domain'0 self.current) e2} + (! bb0 + [ bb0 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_mut {self.current} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_9 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = find'0 {_9} {e1} (fun (_ret':t_Element'0) -> [ &r1 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_final {self.current} {Borrow.get_id self} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_12 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = find'0 {_12} {e2} (fun (_ret':t_Element'0) -> [ &r2 <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = {[@expl:type invariant] inv'1 self} s1 + | s1 = -{resolve'0 self}- s2 + | s2 = addr_eq'0 {r1.t_Element__0'0} {r2.t_Element__0'0} (fun (_ret':bool) -> [ &_0 <- _ret' ] s3) + | s3 = bb3 ] + + | bb3 = return' {_0} ] + ) + [ & _0 : bool = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & e1 : t_Element'0 = e1 + | & e2 : t_Element'0 = e2 + | & r1 : t_Element'0 = any_l () + | & _9 : borrowed (t_UnionFind'0) = any_l () + | & r2 : t_Element'0 = any_l () + | & _12 : borrowed (t_UnionFind'0) = any_l () ] + + [ return' (result:bool)-> {[@expl:equiv ensures #0] [%#sunion_find3] result + = (index_logic'0 (root_of'0 self.current) e1 = index_logic'0 (root_of'0 self.current) e2)} + {[@expl:equiv ensures #1] [%#sunion_find4] unchanged'0 self} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__link [#"union_find.rs" 283 8 283 70] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 299 31 305 18 + let%span sunion_find1 = "union_find.rs" 306 30 312 18 + let%span sunion_find2 = "union_find.rs" 313 33 313 63 + let%span sunion_find3 = "union_find.rs" 315 20 315 95 + let%span sunion_find4 = "union_find.rs" 323 88 323 89 + let%span sunion_find5 = "union_find.rs" 327 31 333 18 + let%span sunion_find6 = "union_find.rs" 334 30 340 18 + let%span sunion_find7 = "union_find.rs" 341 33 341 63 + let%span sunion_find8 = "union_find.rs" 343 20 343 95 + let%span sunion_find9 = "union_find.rs" 283 21 283 25 + let%span sunion_find10 = "union_find.rs" 262 19 262 44 + let%span sunion_find11 = "union_find.rs" 263 19 263 41 + let%span sunion_find12 = "union_find.rs" 264 19 264 44 + let%span sunion_find13 = "union_find.rs" 265 19 265 41 + let%span sunion_find14 = "union_find.rs" 266 18 266 54 + let%span sunion_find15 = "union_find.rs" 267 18 267 82 + let%span sunion_find16 = "union_find.rs" 268 18 268 53 + let%span sunion_find17 = "union_find.rs" 269 18 274 13 + let%span sunion_find18 = "union_find.rs" 276 18 281 13 + let%span sunion_find19 = "union_find.rs" 14 18 14 69 + let%span sghost20 = "../../../creusot-contracts/src/ghost.rs" 138 27 138 31 + let%span sghost21 = "../../../creusot-contracts/src/ghost.rs" 138 4 138 52 + let%span sghost22 = "../../../creusot-contracts/src/ghost.rs" 137 14 137 39 + let%span sunion_find23 = "union_find.rs" 288 25 288 66 + let%span sunion_find24 = "union_find.rs" 289 25 289 66 + let%span sptr_own25 = "../../../creusot-contracts/src/ptr_own.rs" 71 34 71 37 + let%span sptr_own26 = "../../../creusot-contracts/src/ptr_own.rs" 68 15 68 31 + let%span sptr_own27 = "../../../creusot-contracts/src/ptr_own.rs" 71 4 71 66 + let%span sptr_own28 = "../../../creusot-contracts/src/ptr_own.rs" 69 14 69 35 + let%span sunion_find29 = "union_find.rs" 297 33 297 78 + let%span sptr_own30 = "../../../creusot-contracts/src/ptr_own.rs" 83 34 83 37 + let%span sptr_own31 = "../../../creusot-contracts/src/ptr_own.rs" 78 15 78 31 + let%span sptr_own32 = "../../../creusot-contracts/src/ptr_own.rs" 83 4 83 74 + let%span sptr_own33 = "../../../creusot-contracts/src/ptr_own.rs" 79 14 79 35 + let%span sptr_own34 = "../../../creusot-contracts/src/ptr_own.rs" 81 14 81 53 + let%span sptr_own35 = "../../../creusot-contracts/src/ptr_own.rs" 82 14 82 52 + let%span smapping36 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find37 = "union_find.rs" 318 33 318 78 + let%span sunion_find38 = "union_find.rs" 321 37 321 82 + let%span sunion_find39 = "union_find.rs" 73 15 73 19 + let%span sunion_find40 = "union_find.rs" 74 14 74 32 + let%span sunion_find41 = "union_find.rs" 133 19 133 28 + let%span sunion_find42 = "union_find.rs" 134 18 134 150 + let%span sunion_find43 = "union_find.rs" 131 8 131 16 + let%span sfset44 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find45 = "union_find.rs" 145 19 145 28 + let%span sunion_find46 = "union_find.rs" 146 18 146 98 + let%span sunion_find47 = "union_find.rs" 143 8 143 16 + let%span sunion_find48 = "union_find.rs" 258 12 258 50 + let%span sunion_find49 = "union_find.rs" 154 19 154 28 + let%span sunion_find50 = "union_find.rs" 155 18 155 106 + let%span sunion_find51 = "union_find.rs" 152 8 152 16 + let%span smodel52 = "../../../creusot-contracts/src/model.rs" 83 8 83 28 + let%span sresolve53 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sghost54 = "../../../creusot-contracts/src/ghost.rs" 69 14 69 18 + let%span sghost55 = "../../../creusot-contracts/src/ghost.rs" 69 4 69 36 + let%span sghost56 = "../../../creusot-contracts/src/ghost.rs" 68 14 68 35 + let%span sunion_find57 = "union_find.rs" 30 18 30 46 + let%span sfmap58 = "../../../creusot-contracts/src/logic/fmap.rs" 314 22 314 26 + let%span sfmap59 = "../../../creusot-contracts/src/logic/fmap.rs" 314 28 314 31 + let%span sfmap60 = "../../../creusot-contracts/src/logic/fmap.rs" 314 4 314 50 + let%span sfmap61 = "../../../creusot-contracts/src/logic/fmap.rs" 306 4 313 11 + let%span soption62 = "../../../creusot-contracts/src/std/option.rs" 31 0 423 1 + let%span sghost63 = "../../../creusot-contracts/src/ghost.rs" 181 15 181 16 + let%span sghost64 = "../../../creusot-contracts/src/ghost.rs" 181 4 181 28 + let%span sghost65 = "../../../creusot-contracts/src/ghost.rs" 179 14 179 28 + let%span sghost66 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sghost67 = "../../../creusot-contracts/src/ghost.rs" 110 8 110 24 + let%span sghost68 = "../../../creusot-contracts/src/ghost.rs" 85 22 85 26 + let%span sghost69 = "../../../creusot-contracts/src/ghost.rs" 85 4 85 48 + let%span sghost70 = "../../../creusot-contracts/src/ghost.rs" 84 14 84 36 + let%span sfmap71 = "../../../creusot-contracts/src/logic/fmap.rs" 348 30 348 34 + let%span sfmap72 = "../../../creusot-contracts/src/logic/fmap.rs" 348 36 348 39 + let%span sfmap73 = "../../../creusot-contracts/src/logic/fmap.rs" 348 4 348 62 + let%span sfmap74 = "../../../creusot-contracts/src/logic/fmap.rs" 336 4 345 11 + let%span sfmap75 = "../../../creusot-contracts/src/logic/fmap.rs" 346 14 346 89 + let%span sfmap76 = "../../../creusot-contracts/src/logic/fmap.rs" 347 14 347 44 + let%span sunion_find77 = "union_find.rs" 21 8 21 16 + let%span sinvariant78 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sfmap79 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sfmap80 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sfmap81 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap82 = "../../../creusot-contracts/src/logic/fmap.rs" 48 14 48 25 + let%span sutil83 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil84 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sinvariant85 = "../../../creusot-contracts/src/invariant.rs" 24 8 24 18 + let%span sresolve86 = "../../../creusot-contracts/src/resolve.rs" 68 8 68 23 + let%span sfmap87 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sfmap88 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sptr_own89 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sunion_find90 = "union_find.rs" 80 8 80 20 + let%span sboxed91 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sptr92 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr93 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + let%span sunion_find94 = "union_find.rs" 125 8 125 16 + let%span sfmap95 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap96 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use prelude.prelude.Int + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'1 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find77] addr_logic'0 self.t_Element__0'0 + + function deep_model'0 (self : t_Element'0) : int = + [%#smodel52] deep_model'1 self + + let rec eq'0 (self:t_Element'0) (other:t_Element'0) (return' (ret:bool))= any + [ return' (result:bool)-> {[%#sunion_find19] result = (deep_model'0 self = deep_model'0 other)} + (! return' {result}) ] + + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset44] Fset.mem e self + + function inner_logic'2 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost66] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'2 = + | C_None'2 + | C_Some'2 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'2) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap88] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'2 = + [%#sfmap81] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap79] get_unsized'0 self k <> C_None'2 + + function unwrap'2 (op : t_Option'2) : t_PtrOwn'0 + + axiom unwrap'2_spec : forall op : t_Option'2 . ([%#sutil83] op <> C_None'2) + -> ([%#sutil84] C_Some'2 (unwrap'2 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap80] unwrap'2 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap96] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap95] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find94] index_logic'3 (inner_logic'2 self.t_UnionFind__map'0) (Snapshot.new (deep_model'1 e)) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping36] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping36] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping36] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'8 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find90] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'1 e1 = deep_model'1 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'2 self.t_UnionFind__map'0) (Snapshot.new (deep_model'1 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'33 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'32 [@rewrite] : forall x : Snapshot.snap_ty int [inv'33 x] . inv'33 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr93] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr92] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'31 (_1 : t_T'0) + + predicate inv'4 (_1 : t_Content'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_Content'0 [inv'4 x] . inv'4 x + = match x with + | C_Root'0 rank value -> inv'31 value + | C_Link'0 a_0 -> true + end + + predicate invariant'20 (self : t_Content'0) = + [%#sboxed91] inv'4 self + + predicate inv'35 (_1 : t_Content'0) + + axiom inv_axiom'34 [@rewrite] : forall x : t_Content'0 [inv'35 x] . inv'35 x = invariant'20 x + + predicate invariant'5 (self : t_PtrOwn'0) = + [%#sptr_own89] not is_null_logic'0 (ptr'0 self) /\ inv'35 (val'0 self) + + predicate inv'11 (_1 : t_PtrOwn'0) + + axiom inv_axiom'11 [@rewrite] : forall x : t_PtrOwn'0 [inv'11 x] . inv'11 x = invariant'5 x + + predicate invariant'19 (self : t_PtrOwn'0) = + [%#sboxed91] inv'11 self + + predicate inv'34 (_1 : t_PtrOwn'0) + + axiom inv_axiom'33 [@rewrite] : forall x : t_PtrOwn'0 [inv'34 x] . inv'34 x = invariant'19 x + + predicate invariant'4 (self : t_FMap'0) = + [%#sfmap87] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'33 k /\ inv'34 (lookup_unsized'0 self k) + + predicate inv'10 (_1 : t_FMap'0) + + axiom inv_axiom'10 [@rewrite] : forall x : t_FMap'0 [inv'10 x] . inv'10 x = invariant'4 x + + predicate invariant'9 (self : t_FMap'0) = + [%#sboxed91] inv'10 self + + predicate inv'19 (_1 : t_FMap'0) + + axiom inv_axiom'19 [@rewrite] : forall x : t_FMap'0 [inv'19 x] . inv'19 x = invariant'9 x + + predicate inv'1 (_1 : t_GhostBox'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_GhostBox'0 [inv'1 x] . inv'1 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'19 a_0 + end + + predicate inv'18 (_1 : t_UnionFind'0) + + axiom inv_axiom'18 [@rewrite] : forall x : t_UnionFind'0 [inv'18 x] . inv'18 x + = (invariant'8 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'1 map + end) + + predicate invariant'0 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant78] inv'18 self.current /\ inv'18 self.final + + predicate inv'0 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'0 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'0 x] . inv'0 x = invariant'0 x + + predicate resolve'5 (self : borrowed (t_UnionFind'0)) = + [%#sresolve53] self.final = self.current + + predicate resolve'0 (_1 : borrowed (t_UnionFind'0)) = + resolve'5 _1 + + predicate invariant'2 (self : borrowed (t_GhostBox'0)) = + [%#sinvariant78] inv'1 self.current /\ inv'1 self.final + + predicate inv'6 (_1 : borrowed (t_GhostBox'0)) + + axiom inv_axiom'6 [@rewrite] : forall x : borrowed (t_GhostBox'0) [inv'6 x] . inv'6 x = invariant'2 x + + type t_GhostBox'1 = + { t_GhostBox__0'1: borrowed (t_FMap'0) } + + predicate invariant'17 (self : borrowed (t_FMap'0)) = + [%#sinvariant78] inv'10 self.current /\ inv'10 self.final + + predicate inv'29 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'29 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'29 x] . inv'29 x = invariant'17 x + + predicate invariant'15 (self : borrowed (t_FMap'0)) = + [%#sboxed91] inv'29 self + + predicate inv'27 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'27 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'27 x] . inv'27 x = invariant'15 x + + predicate inv'3 (_1 : t_GhostBox'1) + + axiom inv_axiom'3 [@rewrite] : forall x : t_GhostBox'1 [inv'3 x] . inv'3 x + = match x with + | {t_GhostBox__0'1 = a_0} -> inv'27 a_0 + end + + let rec borrow_mut'0 (self:borrowed (t_GhostBox'0)) (return' (ret:t_GhostBox'1))= {[@expl:borrow_mut 'self' type invariant] [%#sghost20] inv'6 self} + any + [ return' (result:t_GhostBox'1)-> {[%#sghost21] inv'3 result} + {[%#sghost22] result.t_GhostBox__0'1 + = Borrow.borrow_logic (self.current).t_GhostBox__0'0 (self.final).t_GhostBox__0'0 (Borrow.inherit_id (Borrow.get_id self) 1)} + (! return' {result}) ] + + + predicate invariant'10 (self : t_GhostBox'1) = + [%#sinvariant85] inv'3 self + + predicate inv'20 (_1 : t_GhostBox'1) + + axiom inv_axiom'20 [@rewrite] : forall x : t_GhostBox'1 [inv'20 x] . inv'20 x = invariant'10 x + + predicate invariant'11 (self : borrowed (t_FMap'0)) = + [%#sinvariant85] inv'29 self + + predicate inv'21 (_1 : borrowed (t_FMap'0)) + + axiom inv_axiom'21 [@rewrite] : forall x : borrowed (t_FMap'0) [inv'21 x] . inv'21 x = invariant'11 x + + let rec deref'0 (self:t_GhostBox'1) (return' (ret:borrowed (t_FMap'0)))= {[@expl:deref 'self' type invariant] [%#sghost54] inv'20 self} + any + [ return' (result:borrowed (t_FMap'0))-> {[%#sghost55] inv'21 result} + {[%#sghost56] self.t_GhostBox__0'1 = result} + (! return' {result}) ] + + + let rec addr'0 (self:t_Element'0) (return' (ret:Snapshot.snap_ty int))= any + [ return' (result:Snapshot.snap_ty int)-> {[%#sunion_find57] Snapshot.inner result = deep_model'1 self} + (! return' {result}) ] + + + predicate invariant'12 (self : t_FMap'0) = + [%#sinvariant85] inv'10 self + + predicate inv'22 (_1 : t_FMap'0) + + axiom inv_axiom'22 [@rewrite] : forall x : t_FMap'0 [inv'22 x] . inv'22 x = invariant'12 x + + predicate inv'23 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'23 [@rewrite] : forall x : Snapshot.snap_ty int [inv'23 x] . inv'23 x = true + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + predicate invariant'13 (self : t_PtrOwn'0) = + [%#sinvariant85] inv'11 self + + predicate inv'25 (_1 : t_PtrOwn'0) + + axiom inv_axiom'25 [@rewrite] : forall x : t_PtrOwn'0 [inv'25 x] . inv'25 x = invariant'13 x + + predicate inv'24 (_1 : t_Option'0) + + axiom inv_axiom'24 [@rewrite] : forall x : t_Option'0 [inv'24 x] . inv'24 x + = match x with + | C_None'0 -> true + | C_Some'0 a_0 -> inv'25 a_0 + end + + let rec get_ghost'0 (self:t_FMap'0) (key:Snapshot.snap_ty int) (return' (ret:t_Option'0))= {[@expl:get_ghost 'self' type invariant] [%#sfmap58] inv'22 self} + {[@expl:get_ghost 'key' type invariant] [%#sfmap59] inv'23 key} + any + [ return' (result:t_Option'0)-> {[%#sfmap60] inv'24 result} + {[%#sfmap61] if contains'1 self key then + match result with + | C_None'0 -> false + | C_Some'0 r -> lookup_unsized'0 self key = r + end + else + result = C_None'0 + } + (! return' {result}) ] + + + let rec unwrap'0 (self:t_Option'0) (return' (ret:t_PtrOwn'0))= {[@expl:unwrap 'self' type invariant] inv'24 self} + {[@expl:unwrap requires] [%#soption62] self <> C_None'0} + any [ return' (result:t_PtrOwn'0)-> {inv'25 result} {[%#soption62] C_Some'0 result = self} (! return' {result}) ] + + type t_GhostBox'2 = + { t_GhostBox__0'2: t_PtrOwn'0 } + + predicate invariant'14 (self : t_PtrOwn'0) = + [%#sboxed91] inv'25 self + + predicate inv'26 (_1 : t_PtrOwn'0) + + axiom inv_axiom'26 [@rewrite] : forall x : t_PtrOwn'0 [inv'26 x] . inv'26 x = invariant'14 x + + predicate inv'2 (_1 : t_GhostBox'2) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'2 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'2 = a_0} -> inv'26 a_0 + end + + let rec new'0 (x:t_PtrOwn'0) (return' (ret:t_GhostBox'2))= {[@expl:new 'x' type invariant] [%#sghost63] inv'25 x} + any + [ return' (result:t_GhostBox'2)-> {[%#sghost64] inv'2 result} + {[%#sghost65] result.t_GhostBox__0'2 = x} + (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + type closure9'1 = + { field_0'0: t_GhostBox'1; field_1'0: t_Element'0 } + + predicate inv'7 (_1 : closure9'1) + + axiom inv_axiom'7 [@rewrite] : forall x : closure9'1 [inv'7 x] . inv'7 x + = (let {field_0'0 = x0 ; field_1'0 = x1} = x in inv'20 x0) + + let rec closure9'0 (_1:closure9'1) (return' (ret:t_GhostBox'2))= {[@expl:closure '_1' type invariant] inv'7 _1} + bb0 + [ bb0 = s0 [ s0 = deref'0 {_1.field_0'0} (fun (_ret':borrowed (t_FMap'0)) -> [ &_5 <- _ret' ] s1) | s1 = bb1 ] + | bb1 = s0 [ s0 = addr'0 {_1.field_1'0} (fun (_ret':Snapshot.snap_ty int) -> [ &_9 <- _ret' ] s1) | s1 = bb2 ] + | bb2 = s0 + [ s0 = [ &_8 <- _9 ] s1 + | s1 = get_ghost'0 {_5.current} {_8} (fun (_ret':t_Option'0) -> [ &_3 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'0 {_3} (fun (_ret':t_PtrOwn'0) -> [ &_2 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 [ s0 = new'0 {_2} (fun (_ret':t_GhostBox'2) -> [ &_0 <- _ret' ] s1) | s1 = bb5 ] + | bb5 = return' {_0} ] + + [ & _0 : t_GhostBox'2 = any_l () + | & _1 : closure9'1 = _1 + | & _2 : t_PtrOwn'0 = any_l () + | & _3 : t_Option'0 = any_l () + | & _5 : borrowed (t_FMap'0) = any_l () + | & _8 : Snapshot.snap_ty int = any_l () + | & _9 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'2)-> {[@expl:closure result type invariant] [%#sunion_find23] inv'2 result} + return' {result} ] + + + type closure10'1 = + { field_0'1: t_GhostBox'1; field_1'1: t_Element'0 } + + predicate inv'8 (_1 : closure10'1) + + axiom inv_axiom'8 [@rewrite] : forall x : closure10'1 [inv'8 x] . inv'8 x + = (let {field_0'1 = x0 ; field_1'1 = x1} = x in inv'20 x0) + + let rec closure10'0 (_1:closure10'1) (return' (ret:t_GhostBox'2))= {[@expl:closure '_1' type invariant] inv'8 _1} + bb0 + [ bb0 = s0 [ s0 = deref'0 {_1.field_0'1} (fun (_ret':borrowed (t_FMap'0)) -> [ &_5 <- _ret' ] s1) | s1 = bb1 ] + | bb1 = s0 [ s0 = addr'0 {_1.field_1'1} (fun (_ret':Snapshot.snap_ty int) -> [ &_9 <- _ret' ] s1) | s1 = bb2 ] + | bb2 = s0 + [ s0 = [ &_8 <- _9 ] s1 + | s1 = get_ghost'0 {_5.current} {_8} (fun (_ret':t_Option'0) -> [ &_3 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'0 {_3} (fun (_ret':t_PtrOwn'0) -> [ &_2 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 [ s0 = new'0 {_2} (fun (_ret':t_GhostBox'2) -> [ &_0 <- _ret' ] s1) | s1 = bb5 ] + | bb5 = return' {_0} ] + + [ & _0 : t_GhostBox'2 = any_l () + | & _1 : closure10'1 = _1 + | & _2 : t_PtrOwn'0 = any_l () + | & _3 : t_Option'0 = any_l () + | & _5 : borrowed (t_FMap'0) = any_l () + | & _8 : Snapshot.snap_ty int = any_l () + | & _9 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'2)-> {[@expl:closure result type invariant] [%#sunion_find24] inv'2 result} + return' {result} ] + + + function inner_logic'0 (self : t_GhostBox'2) : t_PtrOwn'0 = + [%#sghost66] self.t_GhostBox__0'2 + + predicate invariant'3 (self : t_Content'0) = + [%#sinvariant85] inv'4 self + + predicate inv'9 (_1 : t_Content'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_Content'0 [inv'9 x] . inv'9 x = invariant'3 x + + let rec as_ref'0 (ptr:opaque_ptr) (own:t_GhostBox'2) (return' (ret:t_Content'0))= {[@expl:as_ref 'own' type invariant] [%#sptr_own25] inv'2 own} + {[@expl:as_ref requires] [%#sptr_own26] ptr = ptr'0 (inner_logic'0 own)} + any + [ return' (result:t_Content'0)-> {[%#sptr_own27] inv'9 result} + {[%#sptr_own28] result = val'0 (inner_logic'0 own)} + (! return' {result}) ] + + + predicate resolve'23 (_1 : t_PtrOwn'0) = + true + + predicate resolve'20 (self : t_PtrOwn'0) = + [%#sresolve86] resolve'23 self + + predicate resolve'15 (_1 : t_PtrOwn'0) = + resolve'20 _1 + + predicate resolve'6 (self : t_GhostBox'2) = + [%#sghost67] resolve'15 self.t_GhostBox__0'2 + + predicate resolve'1 (_1 : t_GhostBox'2) = + resolve'6 _1 + + predicate resolve'25 (self : borrowed (t_FMap'0)) = + [%#sresolve53] self.final = self.current + + predicate resolve'24 (_1 : borrowed (t_FMap'0)) = + resolve'25 _1 + + predicate resolve'21 (self : borrowed (t_FMap'0)) = + [%#sresolve86] resolve'24 self + + predicate resolve'16 (_1 : borrowed (t_FMap'0)) = + resolve'21 _1 + + predicate resolve'7 (self : t_GhostBox'1) = + [%#sghost67] resolve'16 self.t_GhostBox__0'1 + + predicate resolve'2 (_1 : t_GhostBox'1) = + resolve'7 _1 + + let rec v_Root'0 (input:t_Content'0) (ret (rank:usize) (value:t_T'0))= any + [ good (rank:usize) (value:t_T'0)-> {C_Root'0 rank value = input} (! ret {rank} {value}) + | bad -> {forall rank : usize, value : t_T'0 [C_Root'0 rank value : t_Content'0] . C_Root'0 rank value <> input} + (! {false} + any) ] + + + predicate invariant'16 (self : borrowed (t_GhostBox'1)) = + [%#sinvariant78] inv'3 self.current /\ inv'3 self.final + + predicate inv'28 (_1 : borrowed (t_GhostBox'1)) + + axiom inv_axiom'28 [@rewrite] : forall x : borrowed (t_GhostBox'1) [inv'28 x] . inv'28 x = invariant'16 x + + predicate invariant'6 (self : borrowed (borrowed (t_FMap'0))) = + [%#sinvariant78] inv'29 self.current /\ inv'29 self.final + + predicate inv'12 (_1 : borrowed (borrowed (t_FMap'0))) + + axiom inv_axiom'12 [@rewrite] : forall x : borrowed (borrowed (t_FMap'0)) [inv'12 x] . inv'12 x = invariant'6 x + + let rec deref_mut'0 (self:borrowed (t_GhostBox'1)) (return' (ret:borrowed (borrowed (t_FMap'0))))= {[@expl:deref_mut 'self' type invariant] [%#sghost68] inv'28 self} + any + [ return' (result:borrowed (borrowed (t_FMap'0)))-> {[%#sghost69] inv'12 result} + {[%#sghost70] result + = Borrow.borrow_logic (self.current).t_GhostBox__0'1 (self.final).t_GhostBox__0'1 (Borrow.inherit_id (Borrow.get_id self) 1)} + (! return' {result}) ] + + + type t_Option'1 = + | C_None'1 + | C_Some'1 (borrowed (t_PtrOwn'0)) + + predicate invariant'7 (self : borrowed (t_PtrOwn'0)) = + [%#sinvariant78] inv'11 self.current /\ inv'11 self.final + + predicate inv'13 (_1 : borrowed (t_PtrOwn'0)) + + axiom inv_axiom'13 [@rewrite] : forall x : borrowed (t_PtrOwn'0) [inv'13 x] . inv'13 x = invariant'7 x + + predicate inv'30 (_1 : t_Option'1) + + axiom inv_axiom'30 [@rewrite] : forall x : t_Option'1 [inv'30 x] . inv'30 x + = match x with + | C_None'1 -> true + | C_Some'1 a_0 -> inv'13 a_0 + end + + function len'0 (self : t_FMap'0) : int + + axiom len'0_spec : forall self : t_FMap'0 . [%#sfmap82] len'0 self >= 0 + + let rec get_mut_ghost'0 (self:borrowed (t_FMap'0)) (key:Snapshot.snap_ty int) (return' (ret:t_Option'1))= {[@expl:get_mut_ghost 'self' type invariant] [%#sfmap71] inv'29 self} + {[@expl:get_mut_ghost 'key' type invariant] [%#sfmap72] inv'23 key} + any + [ return' (result:t_Option'1)-> {[%#sfmap73] inv'30 result} + {[%#sfmap74] if contains'1 self.current key then + match result with + | C_None'1 -> false + | C_Some'1 r -> contains'1 self.final key + /\ lookup_unsized'0 self.current key = r.current /\ lookup_unsized'0 self.final key = r.final + end + else + result = C_None'1 /\ self.current = self.final + } + {[%#sfmap75] forall k : Snapshot.snap_ty int . k <> key + -> get_unsized'0 self.current k = get_unsized'0 self.final k} + {[%#sfmap76] len'0 self.current = len'0 self.final} + (! return' {result}) ] + + + let rec unwrap'1 (self:t_Option'1) (return' (ret:borrowed (t_PtrOwn'0)))= {[@expl:unwrap 'self' type invariant] inv'30 self} + {[@expl:unwrap requires] [%#soption62] self <> C_None'1} + any + [ return' (result:borrowed (t_PtrOwn'0))-> {inv'13 result} + {[%#soption62] C_Some'1 result = self} + (! return' {result}) ] + + + type t_GhostBox'3 = + { t_GhostBox__0'3: borrowed (t_PtrOwn'0) } + + predicate invariant'18 (self : borrowed (t_PtrOwn'0)) = + [%#sboxed91] inv'13 self + + predicate inv'32 (_1 : borrowed (t_PtrOwn'0)) + + axiom inv_axiom'31 [@rewrite] : forall x : borrowed (t_PtrOwn'0) [inv'32 x] . inv'32 x = invariant'18 x + + predicate inv'15 (_1 : t_GhostBox'3) + + axiom inv_axiom'15 [@rewrite] : forall x : t_GhostBox'3 [inv'15 x] . inv'15 x + = match x with + | {t_GhostBox__0'3 = a_0} -> inv'32 a_0 + end + + let rec new'1 (x:borrowed (t_PtrOwn'0)) (return' (ret:t_GhostBox'3))= {[@expl:new 'x' type invariant] [%#sghost63] inv'13 x} + any + [ return' (result:t_GhostBox'3)-> {[%#sghost64] inv'15 result} + {[%#sghost65] result.t_GhostBox__0'3 = x} + (! return' {result}) ] + + + predicate resolve'17 (self : borrowed (borrowed (t_FMap'0))) = + [%#sresolve53] self.final = self.current + + predicate resolve'8 (_1 : borrowed (borrowed (t_FMap'0))) = + resolve'17 _1 + + predicate resolve'18 (self : borrowed (t_PtrOwn'0)) = + [%#sresolve53] self.final = self.current + + predicate resolve'9 (_1 : borrowed (t_PtrOwn'0)) = + resolve'18 _1 + + type closure11'1 = + { field_0'2: borrowed (t_GhostBox'1); field_1'2: t_Element'0 } + + predicate inv'14 (_1 : closure11'1) + + axiom inv_axiom'14 [@rewrite] : forall x : closure11'1 [inv'14 x] . inv'14 x + = (let {field_0'2 = x0 ; field_1'2 = x1} = x in inv'28 x0) + + predicate resolve'22 (self : borrowed (t_GhostBox'1)) = + [%#sresolve53] self.final = self.current + + predicate resolve'19 (_1 : borrowed (t_GhostBox'1)) = + resolve'22 _1 + + predicate resolve'10 (_1 : closure11'1) = + resolve'19 _1.field_0'2 + + let rec closure11'0 (_1:closure11'1) (return' (ret:t_GhostBox'3))= {[@expl:closure '_1' type invariant] inv'14 _1} + bb0 + [ bb0 = s0 + [ s0 = {inv'3 (_1.field_0'2).current} + Borrow.borrow_final {(_1.field_0'2).current} {Borrow.get_id _1.field_0'2} + (fun (_ret':borrowed (t_GhostBox'1)) -> + [ &_7 <- _ret' ] + -{inv'3 _ret'.final}- + [ &_1 <- { _1 with field_0'2 = { _1.field_0'2 with current = _ret'.final } } ] + s1) + | s1 = deref_mut'0 {_7} (fun (_ret':borrowed (borrowed (t_FMap'0))) -> [ &_6 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 + [ s0 = {inv'10 (_6.current).current} + Borrow.borrow_mut {(_6.current).current} + (fun (_ret':borrowed (t_FMap'0)) -> + [ &_5 <- _ret' ] + -{inv'10 _ret'.final}- + [ &_6 <- { _6 with current = { _6.current with current = _ret'.final } } ] + s1) + | s1 = addr'0 {_1.field_1'2} (fun (_ret':Snapshot.snap_ty int) -> [ &_10 <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = [ &_9 <- _10 ] s1 + | s1 = get_mut_ghost'0 {_5} {_9} (fun (_ret':t_Option'1) -> [ &_4 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'1 {_4} (fun (_ret':borrowed (t_PtrOwn'0)) -> [ &_3 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 + [ s0 = {inv'11 _3.current} + Borrow.borrow_final {_3.current} {Borrow.get_id _3} + (fun (_ret':borrowed (t_PtrOwn'0)) -> + [ &_2 <- _ret' ] + -{inv'11 _ret'.final}- + [ &_3 <- { _3 with current = _ret'.final } ] + s1) + | s1 = new'1 {_2} (fun (_ret':t_GhostBox'3) -> [ &_0 <- _ret' ] s2) + | s2 = bb5 ] + + | bb5 = s0 + [ s0 = {[@expl:type invariant] inv'12 _6} s1 + | s1 = -{resolve'8 _6}- s2 + | s2 = {[@expl:type invariant] inv'13 _3} s3 + | s3 = -{resolve'9 _3}- s4 + | s4 = {[@expl:type invariant] inv'14 _1} s5 + | s5 = -{resolve'10 _1}- s6 + | s6 = return' {_0} ] + ] + + [ & _0 : t_GhostBox'3 = any_l () + | & _1 : closure11'1 = _1 + | & _2 : borrowed (t_PtrOwn'0) = any_l () + | & _3 : borrowed (t_PtrOwn'0) = any_l () + | & _4 : t_Option'1 = any_l () + | & _5 : borrowed (t_FMap'0) = any_l () + | & _6 : borrowed (borrowed (t_FMap'0)) = any_l () + | & _7 : borrowed (t_GhostBox'1) = any_l () + | & _9 : Snapshot.snap_ty int = any_l () + | & _10 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'3)-> {[@expl:closure result type invariant] [%#sunion_find29] inv'15 result} + return' {result} ] + + + function inner_logic'1 (self : t_GhostBox'3) : borrowed (t_PtrOwn'0) = + [%#sghost66] self.t_GhostBox__0'3 + + predicate invariant'1 (self : borrowed (t_Content'0)) = + [%#sinvariant78] inv'4 self.current /\ inv'4 self.final + + predicate inv'5 (_1 : borrowed (t_Content'0)) + + axiom inv_axiom'5 [@rewrite] : forall x : borrowed (t_Content'0) [inv'5 x] . inv'5 x = invariant'1 x + + let rec as_mut'0 (ptr:opaque_ptr) (own:t_GhostBox'3) (return' (ret:borrowed (t_Content'0)))= {[@expl:as_mut 'own' type invariant] [%#sptr_own30] inv'15 own} + {[@expl:as_mut requires] [%#sptr_own31] ptr = ptr'0 (inner_logic'1 own).current} + any + [ return' (result:borrowed (t_Content'0))-> {[%#sptr_own32] inv'5 result} + {[%#sptr_own33] result.current = val'0 (inner_logic'1 own).current} + {[%#sptr_own34] ptr'0 (inner_logic'1 own).final = ptr'0 (inner_logic'1 own).current} + {[%#sptr_own35] val'0 (inner_logic'1 own).final = result.final} + (! return' {result}) ] + + + predicate resolve'11 (self : borrowed (t_Content'0)) = + [%#sresolve53] self.final = self.current + + predicate resolve'3 (_1 : borrowed (t_Content'0)) = + resolve'11 _1 + + use prelude.prelude.Mapping + + use prelude.prelude.Snapshot + + use prelude.prelude.Mapping + + use prelude.prelude.Snapshot + + use int.MinMax + + use map.Map + + use prelude.prelude.Snapshot + + type closure16'1 = + { field_0'3: borrowed (t_GhostBox'1); field_1'3: t_Element'0 } + + predicate inv'16 (_1 : closure16'1) + + axiom inv_axiom'16 [@rewrite] : forall x : closure16'1 [inv'16 x] . inv'16 x + = (let {field_0'3 = x0 ; field_1'3 = x1} = x in inv'28 x0) + + predicate resolve'12 (_1 : closure16'1) = + resolve'19 _1.field_0'3 + + let rec closure16'0 (_1:closure16'1) (return' (ret:t_GhostBox'3))= {[@expl:closure '_1' type invariant] inv'16 _1} + bb0 + [ bb0 = s0 + [ s0 = {inv'3 (_1.field_0'3).current} + Borrow.borrow_final {(_1.field_0'3).current} {Borrow.get_id _1.field_0'3} + (fun (_ret':borrowed (t_GhostBox'1)) -> + [ &_7 <- _ret' ] + -{inv'3 _ret'.final}- + [ &_1 <- { _1 with field_0'3 = { _1.field_0'3 with current = _ret'.final } } ] + s1) + | s1 = deref_mut'0 {_7} (fun (_ret':borrowed (borrowed (t_FMap'0))) -> [ &_6 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 + [ s0 = {inv'10 (_6.current).current} + Borrow.borrow_mut {(_6.current).current} + (fun (_ret':borrowed (t_FMap'0)) -> + [ &_5 <- _ret' ] + -{inv'10 _ret'.final}- + [ &_6 <- { _6 with current = { _6.current with current = _ret'.final } } ] + s1) + | s1 = addr'0 {_1.field_1'3} (fun (_ret':Snapshot.snap_ty int) -> [ &_10 <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = [ &_9 <- _10 ] s1 + | s1 = get_mut_ghost'0 {_5} {_9} (fun (_ret':t_Option'1) -> [ &_4 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'1 {_4} (fun (_ret':borrowed (t_PtrOwn'0)) -> [ &_3 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 + [ s0 = {inv'11 _3.current} + Borrow.borrow_final {_3.current} {Borrow.get_id _3} + (fun (_ret':borrowed (t_PtrOwn'0)) -> + [ &_2 <- _ret' ] + -{inv'11 _ret'.final}- + [ &_3 <- { _3 with current = _ret'.final } ] + s1) + | s1 = new'1 {_2} (fun (_ret':t_GhostBox'3) -> [ &_0 <- _ret' ] s2) + | s2 = bb5 ] + + | bb5 = s0 + [ s0 = {[@expl:type invariant] inv'12 _6} s1 + | s1 = -{resolve'8 _6}- s2 + | s2 = {[@expl:type invariant] inv'13 _3} s3 + | s3 = -{resolve'9 _3}- s4 + | s4 = {[@expl:type invariant] inv'16 _1} s5 + | s5 = -{resolve'12 _1}- s6 + | s6 = return' {_0} ] + ] + + [ & _0 : t_GhostBox'3 = any_l () + | & _1 : closure16'1 = _1 + | & _2 : borrowed (t_PtrOwn'0) = any_l () + | & _3 : borrowed (t_PtrOwn'0) = any_l () + | & _4 : t_Option'1 = any_l () + | & _5 : borrowed (t_FMap'0) = any_l () + | & _6 : borrowed (borrowed (t_FMap'0)) = any_l () + | & _7 : borrowed (t_GhostBox'1) = any_l () + | & _9 : Snapshot.snap_ty int = any_l () + | & _10 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'3)-> {[@expl:closure result type invariant] [%#sunion_find37] inv'15 result} + return' {result} ] + + + type closure17'1 = + { field_0'4: borrowed (t_GhostBox'1); field_1'4: t_Element'0 } + + predicate inv'17 (_1 : closure17'1) + + axiom inv_axiom'17 [@rewrite] : forall x : closure17'1 [inv'17 x] . inv'17 x + = (let {field_0'4 = x0 ; field_1'4 = x1} = x in inv'28 x0) + + predicate resolve'13 (_1 : closure17'1) = + resolve'19 _1.field_0'4 + + let rec closure17'0 (_1:closure17'1) (return' (ret:t_GhostBox'3))= {[@expl:closure '_1' type invariant] inv'17 _1} + bb0 + [ bb0 = s0 + [ s0 = {inv'3 (_1.field_0'4).current} + Borrow.borrow_final {(_1.field_0'4).current} {Borrow.get_id _1.field_0'4} + (fun (_ret':borrowed (t_GhostBox'1)) -> + [ &_7 <- _ret' ] + -{inv'3 _ret'.final}- + [ &_1 <- { _1 with field_0'4 = { _1.field_0'4 with current = _ret'.final } } ] + s1) + | s1 = deref_mut'0 {_7} (fun (_ret':borrowed (borrowed (t_FMap'0))) -> [ &_6 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 + [ s0 = {inv'10 (_6.current).current} + Borrow.borrow_mut {(_6.current).current} + (fun (_ret':borrowed (t_FMap'0)) -> + [ &_5 <- _ret' ] + -{inv'10 _ret'.final}- + [ &_6 <- { _6 with current = { _6.current with current = _ret'.final } } ] + s1) + | s1 = addr'0 {_1.field_1'4} (fun (_ret':Snapshot.snap_ty int) -> [ &_10 <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = [ &_9 <- _10 ] s1 + | s1 = get_mut_ghost'0 {_5} {_9} (fun (_ret':t_Option'1) -> [ &_4 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = unwrap'1 {_4} (fun (_ret':borrowed (t_PtrOwn'0)) -> [ &_3 <- _ret' ] s1) | s1 = bb4 ] + | bb4 = s0 + [ s0 = {inv'11 _3.current} + Borrow.borrow_final {_3.current} {Borrow.get_id _3} + (fun (_ret':borrowed (t_PtrOwn'0)) -> + [ &_2 <- _ret' ] + -{inv'11 _ret'.final}- + [ &_3 <- { _3 with current = _ret'.final } ] + s1) + | s1 = new'1 {_2} (fun (_ret':t_GhostBox'3) -> [ &_0 <- _ret' ] s2) + | s2 = bb5 ] + + | bb5 = s0 + [ s0 = {[@expl:type invariant] inv'12 _6} s1 + | s1 = -{resolve'8 _6}- s2 + | s2 = {[@expl:type invariant] inv'13 _3} s3 + | s3 = -{resolve'9 _3}- s4 + | s4 = {[@expl:type invariant] inv'17 _1} s5 + | s5 = -{resolve'13 _1}- s6 + | s6 = return' {_0} ] + ] + + [ & _0 : t_GhostBox'3 = any_l () + | & _1 : closure17'1 = _1 + | & _2 : borrowed (t_PtrOwn'0) = any_l () + | & _3 : borrowed (t_PtrOwn'0) = any_l () + | & _4 : t_Option'1 = any_l () + | & _5 : borrowed (t_FMap'0) = any_l () + | & _6 : borrowed (borrowed (t_FMap'0)) = any_l () + | & _7 : borrowed (t_GhostBox'1) = any_l () + | & _9 : Snapshot.snap_ty int = any_l () + | & _10 : Snapshot.snap_ty int = any_l () ] + + [ return' (result:t_GhostBox'3)-> {[@expl:closure result type invariant] [%#sunion_find38] inv'15 result} + return' {result} ] + + + use prelude.prelude.UIntSize + + let rec add_no_overflow'0 (x:usize) (y:usize) (return' (ret:usize))= {[@expl:add_no_overflow requires] [%#sunion_find39] true} + any + [ return' (result:usize)-> {[%#sunion_find40] UIntSize.to_int result = UIntSize.to_int x + UIntSize.to_int y} + (! return' {result}) ] + + + predicate resolve'14 (self : borrowed usize) = + [%#sresolve53] self.final = self.current + + predicate resolve'4 (_1 : borrowed usize) = + resolve'14 _1 + + use prelude.prelude.Mapping + + use prelude.prelude.Mapping + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find43] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find41] inv'18 self) + -> ([%#sunion_find42] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'1 e1 = deep_model'1 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find47] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find45] inv'18 self) + -> ([%#sunion_find46] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate equiv_log'0 [#"union_find.rs" 257 8 257 68] (self : t_UnionFind'0) (x : t_Element'0) (y : t_Element'0) = + [%#sunion_find48] index_logic'0 (root_of'0 self) x = index_logic'0 (root_of'0 self) y + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find51] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find49] inv'18 self) + -> ([%#sunion_find50] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + meta "compute_max_steps" 1000000 + + let rec link'0 (self:borrowed (t_UnionFind'0)) (x:t_Element'0) (y:t_Element'0) (return' (ret:t_Element'0))= {[@expl:link 'self' type invariant] [%#sunion_find9] inv'0 self} + {[@expl:link requires #0] [%#sunion_find10] contains'0 (domain'0 self.current) x} + {[@expl:link requires #1] [%#sunion_find11] index_logic'0 (root_of'0 self.current) x = x} + {[@expl:link requires #2] [%#sunion_find12] contains'0 (domain'0 self.current) y} + {[@expl:link requires #3] [%#sunion_find13] index_logic'0 (root_of'0 self.current) y = y} + (! bb0 + [ bb0 = s0 [ s0 = eq'0 {x} {y} (fun (_ret':bool) -> [ &_14 <- _ret' ] s1) | s1 = bb1 ] + | bb1 = any [ br0 -> {_14 = false} (! bb3) | br1 -> {_14} (! bb2) ] + | bb2 = s0 + [ s0 = {[@expl:type invariant] inv'0 self} s1 | s1 = -{resolve'0 self}- s2 | s2 = [ &_0 <- x ] s3 | s3 = bb52 ] + + | bb3 = s0 + [ s0 = {inv'1 (self.current).t_UnionFind__map'0} + Borrow.borrow_final + + {(self.current).t_UnionFind__map'0} + {Borrow.inherit_id (Borrow.get_id self) 2} + (fun (_ret':borrowed (t_GhostBox'0)) -> + [ &_19 <- _ret' ] + -{inv'1 _ret'.final}- + [ &self <- { self with current = { self.current with t_UnionFind__map'0 = _ret'.final } } ] + s1) + | s1 = borrow_mut'0 {_19} (fun (_ret':t_GhostBox'1) -> [ &map <- _ret' ] s2) + | s2 = bb4 ] + + | bb4 = s0 + [ s0 = [ &_21 <- { field_0'0 = map; field_1'0 = x } ] s1 + | s1 = closure9'0 {_21} (fun (_ret':t_GhostBox'2) -> [ &perm_x <- _ret' ] s2) + | s2 = bb5 ] + + | bb5 = s0 + [ s0 = [ &_26 <- { field_0'1 = map; field_1'1 = y } ] s1 + | s1 = closure10'0 {_26} (fun (_ret':t_GhostBox'2) -> [ &perm_y <- _ret' ] s2) + | s2 = bb6 ] + + | bb6 = s0 + [ s0 = as_ref'0 {x.t_Element__0'0} {perm_x} (fun (_ret':t_Content'0) -> [ &_33 <- _ret' ] s1) | s1 = bb7 ] + + | bb7 = any + [ br0 (x0:usize) (x1:t_T'0)-> {_33 = C_Root'0 x0 x1} (! bb8) + | br1 (x0:t_Element'0)-> {_33 = C_Link'0 x0} (! bb10) ] + + | bb10 = s0 + [ s0 = {[@expl:type invariant] inv'2 perm_y} s1 + | s1 = -{resolve'1 perm_y}- s2 + | s2 = {[@expl:type invariant] inv'3 map} s3 + | s3 = -{resolve'2 map}- s4 + | s4 = {[@expl:type invariant] inv'0 self} s5 + | s5 = -{resolve'0 self}- s6 + | s6 = {false} any ] + + | bb8 = bb9 + | bb9 = s0 + [ s0 = v_Root'0 {_33} (fun (rrank'0:usize) (rvalue'0:t_T'0) -> [ &rx <- rrank'0 ] s1) + | s1 = v_Root'0 {_33} (fun (rrank'1:usize) (rvalue'1:t_T'0) -> [ &vx <- rvalue'1 ] s2) + | s2 = as_ref'0 {y.t_Element__0'0} {perm_y} (fun (_ret':t_Content'0) -> [ &_40 <- _ret' ] s3) + | s3 = bb11 ] + + | bb11 = any + [ br0 (x0:usize) (x1:t_T'0)-> {_40 = C_Root'0 x0 x1} (! bb12) + | br1 (x0:t_Element'0)-> {_40 = C_Link'0 x0} (! bb14) ] + + | bb14 = s0 + [ s0 = {[@expl:type invariant] inv'3 map} s1 + | s1 = -{resolve'2 map}- s2 + | s2 = {[@expl:type invariant] inv'0 self} s3 + | s3 = -{resolve'0 self}- s4 + | s4 = {false} any ] + + | bb12 = bb13 + | bb13 = s0 + [ s0 = v_Root'0 {_40} (fun (rrank'0:usize) (rvalue'0:t_T'0) -> [ &ry <- rrank'0 ] s1) + | s1 = v_Root'0 {_40} (fun (rrank'1:usize) (rvalue'1:t_T'0) -> [ &vy <- rvalue'1 ] s2) + | s2 = UIntSize.lt {rx} {ry} (fun (_ret':bool) -> [ &_44 <- _ret' ] s3) + | s3 = any [ br0 -> {_44 = false} (! bb26) | br1 -> {_44} (! bb15) ] ] + + | bb15 = s0 + [ s0 = {inv'3 map} + Borrow.borrow_mut {map} + (fun (_ret':borrowed (t_GhostBox'1)) -> [ &_49 <- _ret' ] -{inv'3 _ret'.final}- [ &map <- _ret'.final ] s1) + | s1 = [ &_48 <- { field_0'2 = _49; field_1'2 = x } ] s2 + | s2 = closure11'0 {_48} (fun (_ret':t_GhostBox'3) -> [ &perm_mut_x <- _ret' ] s3) + | s3 = bb16 ] + + | bb16 = s0 + [ s0 = [ &_52 <- C_Link'0 y ] s1 + | s1 = as_mut'0 {x.t_Element__0'0} {perm_mut_x} (fun (_ret':borrowed (t_Content'0)) -> [ &_54 <- _ret' ] s2) + | s2 = bb17 ] + + | bb17 = bb18 + | bb18 = s0 + [ s0 = {[@expl:type invariant] match _54 with + | {current = x'0} -> inv'4 x'0 + | _ -> true + end} + s1 + | s1 = [ &_54 <- { _54 with current = _52 } ] s2 + | s2 = {[@expl:type invariant] inv'5 _54} s3 + | s3 = -{resolve'3 _54}- s4 + | s4 = {[@expl:type invariant] inv'3 map} s5 + | s5 = -{resolve'2 map}- s6 + | s6 = bb20 ] + + | bb20 = s0 + [ s0 = + [ &_57 <- [%#sunion_find0] Snapshot.new (Mapping.from_fn (fun (z : t_Element'0) -> if index_logic'0 (Snapshot.inner (self.current).t_UnionFind__root_of'0) z + = x then + y + else + index_logic'0 (Snapshot.inner (self.current).t_UnionFind__root_of'0) z + )) ] + + s1 + | s1 = bb21 ] + + | bb21 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__root_of'0 = _57 } } ] s1 + | s1 = + [ &_59 <- [%#sunion_find1] Snapshot.new (Mapping.from_fn (fun (z : t_Element'0) -> if index_logic'0 (Snapshot.inner (self.current).t_UnionFind__root_of'0) z + = y then + vy + else + index_logic'1 (Snapshot.inner (self.current).t_UnionFind__values'0) z + )) ] + + s2 + | s2 = bb22 ] + + | bb22 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__values'0 = _59 } } ] s1 + | s1 = [ &_61 <- [%#sunion_find2] Snapshot.new (Snapshot.inner (self.current).t_UnionFind__max_depth'0 + 1) ] s2 + | s2 = bb23 ] + + | bb23 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__max_depth'0 = _61 } } ] s1 + | s1 = + [ &_63 <- [%#sunion_find3] Snapshot.new (Map.set (Snapshot.inner (self.current).t_UnionFind__distance'0) y (1 + + MinMax.max (index_logic'2 (Snapshot.inner (self.current).t_UnionFind__distance'0) x) (index_logic'2 (Snapshot.inner (self.current).t_UnionFind__distance'0) y))) ] + + s2 + | s2 = bb24 ] + + | bb24 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__distance'0 = _63 } } ] s1 + | s1 = {[@expl:type invariant] inv'0 self} s2 + | s2 = -{resolve'0 self}- s3 + | s3 = [ &_0 <- y ] s4 + | s4 = bb25 ] + + | bb25 = bb48 + | bb26 = s0 + [ s0 = {inv'3 map} + Borrow.borrow_mut {map} + (fun (_ret':borrowed (t_GhostBox'1)) -> [ &_67 <- _ret' ] -{inv'3 _ret'.final}- [ &map <- _ret'.final ] s1) + | s1 = [ &_66 <- { field_0'3 = _67; field_1'3 = y } ] s2 + | s2 = closure16'0 {_66} (fun (_ret':t_GhostBox'3) -> [ &perm_mut_y <- _ret' ] s3) + | s3 = bb27 ] + + | bb27 = s0 + [ s0 = [ &_70 <- C_Link'0 x ] s1 + | s1 = as_mut'0 {y.t_Element__0'0} {perm_mut_y} (fun (_ret':borrowed (t_Content'0)) -> [ &_72 <- _ret' ] s2) + | s2 = bb28 ] + + | bb28 = bb29 + | bb29 = s0 + [ s0 = {[@expl:type invariant] match _72 with + | {current = x'0} -> inv'4 x'0 + | _ -> true + end} + s1 + | s1 = [ &_72 <- { _72 with current = _70 } ] s2 + | s2 = {[@expl:type invariant] inv'5 _72} s3 + | s3 = -{resolve'3 _72}- s4 + | s4 = bb31 ] + + | bb31 = s0 + [ s0 = UIntSize.eq {rx} {ry} (fun (_ret':bool) -> [ &_76 <- _ret' ] s1) + | s1 = any [ br0 -> {_76 = false} (! bb41) | br1 -> {_76} (! bb32) ] ] + + | bb32 = s0 + [ s0 = {inv'3 map} + Borrow.borrow_mut {map} + (fun (_ret':borrowed (t_GhostBox'1)) -> [ &_81 <- _ret' ] -{inv'3 _ret'.final}- [ &map <- _ret'.final ] s1) + | s1 = [ &_80 <- { field_0'4 = _81; field_1'4 = x } ] s2 + | s2 = closure17'0 {_80} (fun (_ret':t_GhostBox'3) -> [ &perm_mut_x1 <- _ret' ] s3) + | s3 = bb33 ] + + | bb33 = s0 + [ s0 = as_mut'0 {x.t_Element__0'0} {perm_mut_x1} (fun (_ret':borrowed (t_Content'0)) -> [ &_84 <- _ret' ] s1) + | s1 = bb34 ] + + | bb34 = any + [ br0 (x0:usize) (x1:t_T'0)-> {_84.current = C_Root'0 x0 x1} (! bb36) + | br1 (x0:t_Element'0)-> {_84.current = C_Link'0 x0} (! bb35) ] + + | bb35 = s0 + [ s0 = {[@expl:type invariant] inv'5 _84} s1 + | s1 = -{resolve'3 _84}- s2 + | s2 = {[@expl:type invariant] inv'3 map} s3 + | s3 = -{resolve'2 map}- s4 + | s4 = bb39 ] + + | bb36 = bb37 + | bb37 = s0 + [ s0 = v_Root'0 {_84.current} + (fun (rrank'0:usize) (rvalue'0:t_T'0) -> + Borrow.borrow_final {rrank'0} {Borrow.inherit_id (Borrow.get_id _84) 1} + (fun (_ret':borrowed usize) -> + [ &rank <- _ret' ] + [ &_84 <- { _84 with current = C_Root'0 _ret'.final rvalue'0 } ] + s1)) + | s1 = add_no_overflow'0 {rx} {[%#sunion_find4] (1 : usize)} (fun (_ret':usize) -> [ &_89 <- _ret' ] s2) + | s2 = bb38 ] + + | bb38 = s0 + [ s0 = [ &rank <- { rank with current = _89 } ] s1 + | s1 = -{resolve'4 rank}- s2 + | s2 = {[@expl:type invariant] inv'5 _84} s3 + | s3 = -{resolve'3 _84}- s4 + | s4 = {[@expl:type invariant] inv'3 map} s5 + | s5 = -{resolve'2 map}- s6 + | s6 = bb39 ] + + | bb39 = bb40 + | bb40 = bb42 + | bb41 = s0 [ s0 = {[@expl:type invariant] inv'3 map} s1 | s1 = -{resolve'2 map}- s2 | s2 = bb42 ] + | bb42 = s0 + [ s0 = + [ &_91 <- [%#sunion_find5] Snapshot.new (Mapping.from_fn (fun (z : t_Element'0) -> if index_logic'0 (Snapshot.inner (self.current).t_UnionFind__root_of'0) z + = y then + x + else + index_logic'0 (Snapshot.inner (self.current).t_UnionFind__root_of'0) z + )) ] + + s1 + | s1 = bb43 ] + + | bb43 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__root_of'0 = _91 } } ] s1 + | s1 = + [ &_93 <- [%#sunion_find6] Snapshot.new (Mapping.from_fn (fun (z : t_Element'0) -> if index_logic'0 (Snapshot.inner (self.current).t_UnionFind__root_of'0) z + = x then + vx + else + index_logic'1 (Snapshot.inner (self.current).t_UnionFind__values'0) z + )) ] + + s2 + | s2 = bb44 ] + + | bb44 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__values'0 = _93 } } ] s1 + | s1 = [ &_95 <- [%#sunion_find7] Snapshot.new (Snapshot.inner (self.current).t_UnionFind__max_depth'0 + 1) ] s2 + | s2 = bb45 ] + + | bb45 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__max_depth'0 = _95 } } ] s1 + | s1 = + [ &_97 <- [%#sunion_find8] Snapshot.new (Map.set (Snapshot.inner (self.current).t_UnionFind__distance'0) x (1 + + MinMax.max (index_logic'2 (Snapshot.inner (self.current).t_UnionFind__distance'0) x) (index_logic'2 (Snapshot.inner (self.current).t_UnionFind__distance'0) y))) ] + + s2 + | s2 = bb46 ] + + | bb46 = s0 + [ s0 = [ &self <- { self with current = { self.current with t_UnionFind__distance'0 = _97 } } ] s1 + | s1 = {[@expl:type invariant] inv'0 self} s2 + | s2 = -{resolve'0 self}- s3 + | s3 = [ &_0 <- x ] s4 + | s4 = bb47 ] + + | bb47 = bb48 + | bb48 = bb49 + | bb49 = bb50 + | bb50 = bb51 + | bb51 = bb52 + | bb52 = return' {_0} ] + ) + [ & _0 : t_Element'0 = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & x : t_Element'0 = x + | & y : t_Element'0 = y + | & _14 : bool = any_l () + | & map : t_GhostBox'1 = any_l () + | & _19 : borrowed (t_GhostBox'0) = any_l () + | & perm_x : t_GhostBox'2 = any_l () + | & _21 : closure9'1 = any_l () + | & _24 : () = any_l () + | & perm_y : t_GhostBox'2 = any_l () + | & _26 : closure10'1 = any_l () + | & _29 : () = any_l () + | & rx : usize = any_l () + | & vx : t_T'0 = any_l () + | & _33 : t_Content'0 = any_l () + | & ry : usize = any_l () + | & vy : t_T'0 = any_l () + | & _40 : t_Content'0 = any_l () + | & _44 : bool = any_l () + | & perm_mut_x : t_GhostBox'3 = any_l () + | & _48 : closure11'1 = any_l () + | & _49 : borrowed (t_GhostBox'1) = any_l () + | & _51 : () = any_l () + | & _52 : t_Content'0 = any_l () + | & _54 : borrowed (t_Content'0) = any_l () + | & _57 : Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)) = any_l () + | & _59 : Snapshot.snap_ty (Map.map (t_Element'0) t_T'0) = any_l () + | & _61 : Snapshot.snap_ty int = any_l () + | & _63 : Snapshot.snap_ty (Map.map (t_Element'0) int) = any_l () + | & perm_mut_y : t_GhostBox'3 = any_l () + | & _66 : closure16'1 = any_l () + | & _67 : borrowed (t_GhostBox'1) = any_l () + | & _69 : () = any_l () + | & _70 : t_Content'0 = any_l () + | & _72 : borrowed (t_Content'0) = any_l () + | & _76 : bool = any_l () + | & perm_mut_x1 : t_GhostBox'3 = any_l () + | & _80 : closure17'1 = any_l () + | & _81 : borrowed (t_GhostBox'1) = any_l () + | & _83 : () = any_l () + | & _84 : borrowed (t_Content'0) = any_l () + | & rank : borrowed usize = any_l () + | & _89 : usize = any_l () + | & _91 : Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)) = any_l () + | & _93 : Snapshot.snap_ty (Map.map (t_Element'0) t_T'0) = any_l () + | & _95 : Snapshot.snap_ty int = any_l () + | & _97 : Snapshot.snap_ty (Map.map (t_Element'0) int) = any_l () ] + + [ return' (result:t_Element'0)-> {[@expl:link ensures #0] [%#sunion_find14] domain'0 self.final + = domain'0 self.current} + {[@expl:link ensures #1] [%#sunion_find15] result = index_logic'0 (root_of'0 self.current) x + \/ result = index_logic'0 (root_of'0 self.current) y} + {[@expl:link ensures #2] [%#sunion_find16] result = index_logic'0 (root_of'0 self.final) result} + {[@expl:link ensures #3] [%#sunion_find17] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'0 (root_of'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + result + else + index_logic'0 (root_of'0 self.current) z + )} + {[@expl:link ensures #4] [%#sunion_find18] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'1 (values'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + index_logic'1 (values'0 self.final) result + else + index_logic'1 (values'0 self.current) z + )} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__union_aux [#"union_find.rs" 367 8 367 75] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 367 26 367 30 + let%span sunion_find1 = "union_find.rs" 349 19 349 44 + let%span sunion_find2 = "union_find.rs" 350 19 350 44 + let%span sunion_find3 = "union_find.rs" 351 18 351 54 + let%span sunion_find4 = "union_find.rs" 352 18 352 82 + let%span sunion_find5 = "union_find.rs" 353 18 358 13 + let%span sunion_find6 = "union_find.rs" 360 18 365 13 + let%span sunion_find7 = "union_find.rs" 222 25 222 29 + let%span sunion_find8 = "union_find.rs" 219 19 219 47 + let%span sunion_find9 = "union_find.rs" 220 18 220 48 + let%span sunion_find10 = "union_find.rs" 221 18 221 34 + let%span sunion_find11 = "union_find.rs" 283 21 283 25 + let%span sunion_find12 = "union_find.rs" 262 19 262 44 + let%span sunion_find13 = "union_find.rs" 263 19 263 41 + let%span sunion_find14 = "union_find.rs" 264 19 264 44 + let%span sunion_find15 = "union_find.rs" 265 19 265 41 + let%span sunion_find16 = "union_find.rs" 266 18 266 54 + let%span sunion_find17 = "union_find.rs" 267 18 267 82 + let%span sunion_find18 = "union_find.rs" 268 18 268 53 + let%span sunion_find19 = "union_find.rs" 269 18 274 13 + let%span sunion_find20 = "union_find.rs" 276 18 281 13 + let%span sunion_find21 = "union_find.rs" 133 19 133 28 + let%span sunion_find22 = "union_find.rs" 134 18 134 150 + let%span sunion_find23 = "union_find.rs" 131 8 131 16 + let%span sfset24 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find25 = "union_find.rs" 145 19 145 28 + let%span sunion_find26 = "union_find.rs" 146 18 146 98 + let%span sunion_find27 = "union_find.rs" 143 8 143 16 + let%span smapping28 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find29 = "union_find.rs" 258 12 258 50 + let%span sunion_find30 = "union_find.rs" 154 19 154 28 + let%span sunion_find31 = "union_find.rs" 155 18 155 106 + let%span sunion_find32 = "union_find.rs" 152 8 152 16 + let%span sunion_find33 = "union_find.rs" 165 16 167 52 + let%span sresolve34 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sunion_find35 = "union_find.rs" 21 8 21 16 + let%span sunion_find36 = "union_find.rs" 80 8 80 20 + let%span sinvariant37 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sghost38 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap39 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find40 = "union_find.rs" 125 8 125 16 + let%span sfmap41 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap42 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap43 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap44 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap45 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed46 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil47 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil48 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap49 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own50 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr51 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr52 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset24] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find35] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost38] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap43] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap41] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap39] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil47] op <> C_None'0) + -> ([%#sutil48] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap45] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap44] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap42] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find40] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping28] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping28] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping28] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find36] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'5 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'5 [@rewrite] : forall x : Snapshot.snap_ty int [inv'5 x] . inv'5 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr52] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr51] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'10 (_1 : t_T'0) + + predicate inv'9 (_1 : t_Content'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_Content'0 [inv'9 x] . inv'9 x + = match x with + | C_Root'0 rank value -> inv'10 value + | C_Link'0 a_0 -> true + end + + predicate invariant'6 (self : t_Content'0) = + [%#sboxed46] inv'9 self + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x = invariant'6 x + + predicate invariant'5 (self : t_PtrOwn'0) = + [%#sptr_own50] not is_null_logic'0 (ptr'0 self) /\ inv'8 (val'0 self) + + predicate inv'7 (_1 : t_PtrOwn'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_PtrOwn'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sboxed46] inv'7 self + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_FMap'0) = + [%#sfmap49] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'5 k /\ inv'6 (lookup_unsized'0 self k) + + predicate inv'4 (_1 : t_FMap'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_FMap'0 [inv'4 x] . inv'4 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sboxed46] inv'4 self + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate inv'2 (_1 : t_GhostBox'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'0 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'3 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'2 map + end) + + predicate invariant'1 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant37] inv'0 self.current /\ inv'0 self.final + + predicate inv'1 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'1 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'1 x] . inv'1 x = invariant'1 x + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find23] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find21] inv'0 self) + -> ([%#sunion_find22] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find27] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find25] inv'0 self) + -> ([%#sunion_find26] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find32] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find30] inv'0 self) + -> ([%#sunion_find31] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate unchanged'0 [#"union_find.rs" 163 8 163 43] (self : borrowed (t_UnionFind'0)) = + [%#sunion_find33] domain'0 self.current = domain'0 self.final + /\ root_of'0 self.current = root_of'0 self.final /\ values'0 self.current = values'0 self.final + + let rec find'0 (self:borrowed (t_UnionFind'0)) (elem:t_Element'0) (return' (ret:t_Element'0))= {[@expl:find 'self' type invariant] [%#sunion_find7] inv'1 self} + {[@expl:find requires] [%#sunion_find8] contains'0 (domain'0 self.current) elem} + any + [ return' (result:t_Element'0)-> {[%#sunion_find9] result = index_logic'0 (root_of'0 self.current) elem} + {[%#sunion_find10] unchanged'0 self} + (! return' {result}) ] + + + predicate equiv_log'0 [#"union_find.rs" 257 8 257 68] (self : t_UnionFind'0) (x : t_Element'0) (y : t_Element'0) = + [%#sunion_find29] index_logic'0 (root_of'0 self) x = index_logic'0 (root_of'0 self) y + + let rec link'0 (self:borrowed (t_UnionFind'0)) (x:t_Element'0) (y:t_Element'0) (return' (ret:t_Element'0))= {[@expl:link 'self' type invariant] [%#sunion_find11] inv'1 self} + {[@expl:link requires #0] [%#sunion_find12] contains'0 (domain'0 self.current) x} + {[@expl:link requires #1] [%#sunion_find13] index_logic'0 (root_of'0 self.current) x = x} + {[@expl:link requires #2] [%#sunion_find14] contains'0 (domain'0 self.current) y} + {[@expl:link requires #3] [%#sunion_find15] index_logic'0 (root_of'0 self.current) y = y} + any + [ return' (result:t_Element'0)-> {[%#sunion_find16] domain'0 self.final = domain'0 self.current} + {[%#sunion_find17] result = index_logic'0 (root_of'0 self.current) x + \/ result = index_logic'0 (root_of'0 self.current) y} + {[%#sunion_find18] result = index_logic'0 (root_of'0 self.final) result} + {[%#sunion_find19] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'0 (root_of'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + result + else + index_logic'0 (root_of'0 self.current) z + )} + {[%#sunion_find20] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'1 (values'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + index_logic'1 (values'0 self.final) result + else + index_logic'1 (values'0 self.current) z + )} + (! return' {result}) ] + + + predicate resolve'1 (self : borrowed (t_UnionFind'0)) = + [%#sresolve34] self.final = self.current + + predicate resolve'0 (_1 : borrowed (t_UnionFind'0)) = + resolve'1 _1 + + use prelude.prelude.Intrinsic + + meta "compute_max_steps" 1000000 + + let rec union_aux'0 (self:borrowed (t_UnionFind'0)) (x:t_Element'0) (y:t_Element'0) (return' (ret:t_Element'0))= {[@expl:union_aux 'self' type invariant] [%#sunion_find0] inv'1 self} + {[@expl:union_aux requires #0] [%#sunion_find1] contains'0 (domain'0 self.current) x} + {[@expl:union_aux requires #1] [%#sunion_find2] contains'0 (domain'0 self.current) y} + (! bb0 + [ bb0 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_mut {self.current} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_11 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = find'0 {_11} {x} (fun (_ret':t_Element'0) -> [ &rx <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_mut {self.current} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_14 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = find'0 {_14} {y} (fun (_ret':t_Element'0) -> [ &ry <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_final {self.current} {Borrow.get_id self} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_16 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = link'0 {_16} {rx} {ry} (fun (_ret':t_Element'0) -> [ &_0 <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 [ s0 = {[@expl:type invariant] inv'1 self} s1 | s1 = -{resolve'0 self}- s2 | s2 = return' {_0} ] ] + ) + [ & _0 : t_Element'0 = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & x : t_Element'0 = x + | & y : t_Element'0 = y + | & rx : t_Element'0 = any_l () + | & _11 : borrowed (t_UnionFind'0) = any_l () + | & ry : t_Element'0 = any_l () + | & _14 : borrowed (t_UnionFind'0) = any_l () + | & _16 : borrowed (t_UnionFind'0) = any_l () ] + + [ return' (result:t_Element'0)-> {[@expl:union_aux ensures #0] [%#sunion_find3] domain'0 self.final + = domain'0 self.current} + {[@expl:union_aux ensures #1] [%#sunion_find4] result = index_logic'0 (root_of'0 self.current) x + \/ result = index_logic'0 (root_of'0 self.current) y} + {[@expl:union_aux ensures #2] [%#sunion_find5] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'0 (root_of'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + result + else + index_logic'0 (root_of'0 self.current) z + )} + {[@expl:union_aux ensures #3] [%#sunion_find6] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'1 (values'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + index_logic'1 (values'0 self.final) result + else + index_logic'1 (values'0 self.current) z + )} + (! return' {result}) ] + +end +module M_union_find__implementation__qyi16869121482064879694__union [#"union_find.rs" 390 8 390 61] (* implementation::UnionFind *) + let%span sunion_find0 = "union_find.rs" 390 26 390 30 + let%span sunion_find1 = "union_find.rs" 374 19 374 44 + let%span sunion_find2 = "union_find.rs" 375 19 375 44 + let%span sunion_find3 = "union_find.rs" 376 18 376 54 + let%span sunion_find4 = "union_find.rs" 377 18 389 9 + let%span sunion_find5 = "union_find.rs" 367 26 367 30 + let%span sunion_find6 = "union_find.rs" 349 19 349 44 + let%span sunion_find7 = "union_find.rs" 350 19 350 44 + let%span sunion_find8 = "union_find.rs" 351 18 351 54 + let%span sunion_find9 = "union_find.rs" 352 18 352 82 + let%span sunion_find10 = "union_find.rs" 353 18 358 13 + let%span sunion_find11 = "union_find.rs" 360 18 365 13 + let%span sunion_find12 = "union_find.rs" 133 19 133 28 + let%span sunion_find13 = "union_find.rs" 134 18 134 150 + let%span sunion_find14 = "union_find.rs" 131 8 131 16 + let%span sfset15 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sunion_find16 = "union_find.rs" 145 19 145 28 + let%span sunion_find17 = "union_find.rs" 146 18 146 98 + let%span sunion_find18 = "union_find.rs" 143 8 143 16 + let%span smapping19 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find20 = "union_find.rs" 258 12 258 50 + let%span sunion_find21 = "union_find.rs" 154 19 154 28 + let%span sunion_find22 = "union_find.rs" 155 18 155 106 + let%span sunion_find23 = "union_find.rs" 152 8 152 16 + let%span sresolve24 = "../../../creusot-contracts/src/resolve.rs" 54 20 54 34 + let%span sunion_find25 = "union_find.rs" 21 8 21 16 + let%span sunion_find26 = "union_find.rs" 80 8 80 20 + let%span sinvariant27 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sghost28 = "../../../creusot-contracts/src/ghost.rs" 217 9 217 15 + let%span sfmap29 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sunion_find30 = "union_find.rs" 125 8 125 16 + let%span sfmap31 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sfmap32 = "../../../creusot-contracts/src/logic/fmap.rs" 228 8 228 24 + let%span sfmap33 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sfmap34 = "../../../creusot-contracts/src/logic/fmap.rs" 116 9 116 31 + let%span sfmap35 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sboxed36 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sutil37 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil38 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap39 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sptr_own40 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr41 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr42 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + use prelude.prelude.Snapshot + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset15] Fset.mem e self + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find25] addr_logic'0 self.t_Element__0'0 + + function inner_logic'0 (self : t_GhostBox'0) : t_FMap'0 = + [%#sghost28] self.t_GhostBox__0'0 + + use prelude.prelude.Snapshot + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap33] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap31] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap29] get_unsized'0 self k <> C_None'0 + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil37] op <> C_None'0) + -> ([%#sutil38] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap35] unwrap'0 (get_unsized'0 self k) + + function lookup'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap34] lookup_unsized'0 self k + + function index_logic'3 [@inline:trivial] (self : t_FMap'0) (key : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap32] lookup'0 self key + + function get_perm'0 [#"union_find.rs" 126 8 126 62] (self : t_UnionFind'0) (e : t_Element'0) : t_PtrOwn'0 = + [%#sunion_find30] index_logic'3 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e)) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) t_T'0) (a : t_Element'0) : t_T'0 = + [%#smapping19] Map.get self a + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping19] Map.get self a + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + use prelude.prelude.Snapshot + + use map.Map + + function index_logic'2 (self : Map.map (t_Element'0) int) (a : t_Element'0) : int = + [%#smapping19] Map.get self a + + use prelude.prelude.Snapshot + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) = + [%#sunion_find26] let domain = self.t_UnionFind__domain'0 in (forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (Snapshot.inner domain) e1 + /\ contains'0 (Snapshot.inner domain) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'1 (inner_logic'0 self.t_UnionFind__map'0) (Snapshot.new (deep_model'0 e))) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e -> e.t_Element__0'0 = ptr'0 (get_perm'0 self e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e + = index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> contains'0 (Snapshot.inner domain) (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> e <> e2 + /\ contains'0 (Snapshot.inner domain) e2 + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e + = index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e2 + | C_Root'0 _ v -> index_logic'1 (Snapshot.inner self.t_UnionFind__values'0) e = v + /\ index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e = e + end) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self e) with + | C_Link'0 e2 -> index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + < index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e2 + | C_Root'0 _ _ -> true + end) + /\ Snapshot.inner self.t_UnionFind__max_depth'0 >= 0 + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> 0 <= index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e + /\ index_logic'2 (Snapshot.inner self.t_UnionFind__distance'0) e <= Snapshot.inner self.t_UnionFind__max_depth'0) + /\ (forall e : t_Element'0 . contains'0 (Snapshot.inner domain) e + -> match val'0 (get_perm'0 self (index_logic'0 (Snapshot.inner self.t_UnionFind__root_of'0) e)) with + | C_Root'0 _ _ -> true + | C_Link'0 _ -> false + end) + + predicate inv'5 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'5 [@rewrite] : forall x : Snapshot.snap_ty int [inv'5 x] . inv'5 x = true + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr42] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr41] is_null_logic'0 self = (addr_logic'0 self = 0) + + predicate inv'10 (_1 : t_T'0) + + predicate inv'9 (_1 : t_Content'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_Content'0 [inv'9 x] . inv'9 x + = match x with + | C_Root'0 rank value -> inv'10 value + | C_Link'0 a_0 -> true + end + + predicate invariant'6 (self : t_Content'0) = + [%#sboxed36] inv'9 self + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x = invariant'6 x + + predicate invariant'5 (self : t_PtrOwn'0) = + [%#sptr_own40] not is_null_logic'0 (ptr'0 self) /\ inv'8 (val'0 self) + + predicate inv'7 (_1 : t_PtrOwn'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_PtrOwn'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sboxed36] inv'7 self + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_FMap'0) = + [%#sfmap39] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'5 k /\ inv'6 (lookup_unsized'0 self k) + + predicate inv'4 (_1 : t_FMap'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_FMap'0 [inv'4 x] . inv'4 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sboxed36] inv'4 self + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate inv'2 (_1 : t_GhostBox'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'0 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'3 a_0 + end + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'2 map + end) + + predicate invariant'1 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant27] inv'0 self.current /\ inv'0 self.final + + predicate inv'1 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'1 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'1 x] . inv'1 x = invariant'1 x + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) = + [%#sunion_find14] Snapshot.inner self.t_UnionFind__domain'0 + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find12] inv'0 self) + -> ([%#sunion_find13] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) = + [%#sunion_find18] Snapshot.inner self.t_UnionFind__root_of'0 + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find16] inv'0 self) + -> ([%#sunion_find17] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + predicate equiv_log'0 [#"union_find.rs" 257 8 257 68] (self : t_UnionFind'0) (x : t_Element'0) (y : t_Element'0) = + [%#sunion_find20] index_logic'0 (root_of'0 self) x = index_logic'0 (root_of'0 self) y + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) t_T'0 = + [%#sunion_find23] Snapshot.inner self.t_UnionFind__values'0 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find21] inv'0 self) + -> ([%#sunion_find22] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + let rec union_aux'0 (self:borrowed (t_UnionFind'0)) (x:t_Element'0) (y:t_Element'0) (return' (ret:t_Element'0))= {[@expl:union_aux 'self' type invariant] [%#sunion_find5] inv'1 self} + {[@expl:union_aux requires #0] [%#sunion_find6] contains'0 (domain'0 self.current) x} + {[@expl:union_aux requires #1] [%#sunion_find7] contains'0 (domain'0 self.current) y} + any + [ return' (result:t_Element'0)-> {[%#sunion_find8] domain'0 self.final = domain'0 self.current} + {[%#sunion_find9] result = index_logic'0 (root_of'0 self.current) x + \/ result = index_logic'0 (root_of'0 self.current) y} + {[%#sunion_find10] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'0 (root_of'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + result + else + index_logic'0 (root_of'0 self.current) z + )} + {[%#sunion_find11] forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'1 (values'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + index_logic'1 (values'0 self.final) result + else + index_logic'1 (values'0 self.current) z + )} + (! return' {result}) ] + + + predicate resolve'1 (self : borrowed (t_UnionFind'0)) = + [%#sresolve24] self.final = self.current + + predicate resolve'0 (_1 : borrowed (t_UnionFind'0)) = + resolve'1 _1 + + use prelude.prelude.Intrinsic + + meta "compute_max_steps" 1000000 + + let rec union'0 (self:borrowed (t_UnionFind'0)) (x:t_Element'0) (y:t_Element'0) (return' (ret:()))= {[@expl:union 'self' type invariant] [%#sunion_find0] inv'1 self} + {[@expl:union requires #0] [%#sunion_find1] contains'0 (domain'0 self.current) x} + {[@expl:union requires #1] [%#sunion_find2] contains'0 (domain'0 self.current) y} + (! bb0 + [ bb0 = s0 + [ s0 = {inv'0 self.current} + Borrow.borrow_final {self.current} {Borrow.get_id self} + (fun (_ret':borrowed (t_UnionFind'0)) -> + [ &_9 <- _ret' ] + -{inv'0 _ret'.final}- + [ &self <- { self with current = _ret'.final } ] + s1) + | s1 = union_aux'0 {_9} {x} {y} (fun (_ret':t_Element'0) -> [ &_8 <- _ret' ] s2) + | s2 = bb1 ] + + | bb1 = s0 [ s0 = {[@expl:type invariant] inv'1 self} s1 | s1 = -{resolve'0 self}- s2 | s2 = return' {_0} ] ] + ) + [ & _0 : () = any_l () + | & self : borrowed (t_UnionFind'0) = self + | & x : t_Element'0 = x + | & y : t_Element'0 = y + | & _8 : t_Element'0 = any_l () + | & _9 : borrowed (t_UnionFind'0) = any_l () ] + + [ return' (result:())-> {[@expl:union ensures #0] [%#sunion_find3] domain'0 self.final = domain'0 self.current} + {[@expl:union ensures #1] [%#sunion_find4] exists r : t_Element'0 . (r = index_logic'0 (root_of'0 self.current) x + \/ r = index_logic'0 (root_of'0 self.current) y) + /\ (forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'0 (root_of'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + r + else + index_logic'0 (root_of'0 self.current) z + ) + /\ index_logic'1 (values'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + index_logic'1 (values'0 self.final) r + else + index_logic'1 (values'0 self.current) z + ))} + (! return' {result}) ] + +end +module M_union_find__example [#"union_find.rs" 399 0 399 16] + let%span sunion_find0 = "union_find.rs" 400 17 400 40 + let%span sunion_find1 = "union_find.rs" 402 20 402 21 + let%span sunion_find2 = "union_find.rs" 403 20 403 21 + let%span sunion_find3 = "union_find.rs" 404 20 404 21 + let%span sunion_find4 = "union_find.rs" 406 26 406 27 + let%span sunion_find5 = "union_find.rs" 407 26 407 27 + let%span sunion_find6 = "union_find.rs" 408 26 408 27 + let%span sunion_find7 = "union_find.rs" 415 26 415 27 + let%span sunion_find8 = "union_find.rs" 415 4 415 28 + let%span sunion_find9 = "union_find.rs" 414 4 414 37 + let%span sunion_find10 = "union_find.rs" 408 4 408 28 + let%span sunion_find11 = "union_find.rs" 407 4 407 28 + let%span sunion_find12 = "union_find.rs" 406 4 406 28 + let%span sunion_find13 = "union_find.rs" 114 24 114 28 + let%span sunion_find14 = "union_find.rs" 113 8 113 44 + let%span sunion_find15 = "union_find.rs" 175 25 175 29 + let%span sunion_find16 = "union_find.rs" 175 31 175 36 + let%span sunion_find17 = "union_find.rs" 171 18 171 52 + let%span sunion_find18 = "union_find.rs" 172 18 172 69 + let%span sunion_find19 = "union_find.rs" 173 18 173 76 + let%span sunion_find20 = "union_find.rs" 174 18 174 73 + let%span sunion_find21 = "union_find.rs" 232 20 232 24 + let%span sunion_find22 = "union_find.rs" 229 19 229 47 + let%span sunion_find23 = "union_find.rs" 230 19 230 47 + let%span sunion_find24 = "union_find.rs" 232 47 232 49 + let%span sunion_find25 = "union_find.rs" 231 18 231 48 + let%span sunion_find26 = "union_find.rs" 390 26 390 30 + let%span sunion_find27 = "union_find.rs" 374 19 374 44 + let%span sunion_find28 = "union_find.rs" 375 19 375 44 + let%span sunion_find29 = "union_find.rs" 376 18 376 54 + let%span sunion_find30 = "union_find.rs" 377 18 389 9 + let%span sunion_find31 = "union_find.rs" 222 25 222 29 + let%span sunion_find32 = "union_find.rs" 219 19 219 47 + let%span sunion_find33 = "union_find.rs" 220 18 220 48 + let%span sunion_find34 = "union_find.rs" 221 18 221 34 + let%span sunion_find35 = "union_find.rs" 133 19 133 28 + let%span sunion_find36 = "union_find.rs" 134 18 134 150 + let%span sfset37 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span sfset38 = "../../../creusot-contracts/src/logic/fset.rs" 65 8 65 26 + let%span sunion_find39 = "union_find.rs" 145 19 145 28 + let%span sunion_find40 = "union_find.rs" 146 18 146 98 + let%span sunion_find41 = "union_find.rs" 154 19 154 28 + let%span sunion_find42 = "union_find.rs" 155 18 155 106 + let%span smapping43 = "../../../creusot-contracts/src/logic/mapping.rs" 60 8 60 19 + let%span sunion_find44 = "union_find.rs" 258 12 258 50 + let%span sunion_find45 = "union_find.rs" 165 16 167 52 + let%span sinvariant46 = "../../../creusot-contracts/src/invariant.rs" 34 20 34 44 + let%span sinvariant47 = "../../../creusot-contracts/src/invariant.rs" 24 8 24 18 + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + use prelude.prelude.Int32 + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Int + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) int32); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + predicate invariant'0 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x + = (invariant'0 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> true + end) + + use prelude.prelude.Snapshot + + use set.Fset + + let rec new'0 (_1:()) (return' (ret:t_UnionFind'0))= any + [ return' (result:t_UnionFind'0)-> {[%#sunion_find13] inv'0 result} + {[%#sunion_find14] Fset.is_empty (Snapshot.inner result.t_UnionFind__domain'0)} + (! return' {result}) ] + + + use prelude.prelude.Borrow + + predicate invariant'1 (self : borrowed (t_UnionFind'0)) = + [%#sinvariant46] inv'0 self.current /\ inv'0 self.final + + predicate inv'1 (_1 : borrowed (t_UnionFind'0)) + + axiom inv_axiom'1 [@rewrite] : forall x : borrowed (t_UnionFind'0) [inv'1 x] . inv'1 x = invariant'1 x + + predicate inv'2 (_1 : int32) + + axiom inv_axiom'2 [@rewrite] : forall x : int32 [inv'2 x] . inv'2 x = true + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset37] Fset.mem e self + + function deep_model'0 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find35] inv'0 self) + -> ([%#sunion_find36] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'0 e1 = deep_model'0 e2 -> e1 = e2) + + use set.Fset + + function insert'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) : Fset.fset (t_Element'0) = + [%#sfset38] Fset.add e self + + use map.Map + + function index_logic'0 (self : Map.map (t_Element'0) (t_Element'0)) (a : t_Element'0) : t_Element'0 = + [%#smapping43] Map.get self a + + function root_of'0 [#"union_find.rs" 147 8 147 63] (self : t_UnionFind'0) : Map.map (t_Element'0) (t_Element'0) + + axiom root_of'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find39] inv'0 self) + -> ([%#sunion_find40] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'0 (root_of'0 self) e = index_logic'0 (root_of'0 self) (index_logic'0 (root_of'0 self) e)) + + use map.Map + + use map.Map + + function index_logic'1 (self : Map.map (t_Element'0) int32) (a : t_Element'0) : int32 = + [%#smapping43] Map.get self a + + function values'0 [#"union_find.rs" 156 8 156 53] (self : t_UnionFind'0) : Map.map (t_Element'0) int32 + + axiom values'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find41] inv'0 self) + -> ([%#sunion_find42] forall e : t_Element'0 . contains'0 (Snapshot.inner self.t_UnionFind__domain'0) e + -> index_logic'1 (values'0 self) e = index_logic'1 (values'0 self) (index_logic'0 (root_of'0 self) e)) + + use map.Map + + let rec make'0 (self:borrowed (t_UnionFind'0)) (value:int32) (return' (ret:t_Element'0))= {[@expl:make 'self' type invariant] [%#sunion_find15] inv'1 self} + {[@expl:make 'value' type invariant] [%#sunion_find16] inv'2 value} + any + [ return' (result:t_Element'0)-> {[%#sunion_find17] not contains'0 (domain'0 self.current) result} + {[%#sunion_find18] domain'0 self.final = insert'0 (domain'0 self.current) result} + {[%#sunion_find19] root_of'0 self.final = Map.set (root_of'0 self.current) result result} + {[%#sunion_find20] values'0 self.final = Map.set (values'0 self.current) result value} + (! return' {result}) ] + + + predicate invariant'2 (self : t_UnionFind'0) = + [%#sinvariant47] inv'0 self + + predicate inv'3 (_1 : t_UnionFind'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_UnionFind'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate inv'4 (_1 : int32) + + axiom inv_axiom'4 [@rewrite] : forall x : int32 [inv'4 x] . inv'4 x = true + + let rec get'0 (self:t_UnionFind'0) (elem:t_Element'0) (return' (ret:int32))= {[@expl:get 'self' type invariant] [%#sunion_find21] inv'3 self} + {[@expl:get requires #0] [%#sunion_find22] contains'0 (domain'0 self) elem} + {[@expl:get requires #1] [%#sunion_find23] index_logic'0 (root_of'0 self) elem = elem} + any + [ return' (result:int32)-> {[%#sunion_find24] inv'4 result} + {[%#sunion_find25] result = index_logic'1 (values'0 self) elem} + (! return' {result}) ] + + + predicate equiv_log'0 [#"union_find.rs" 257 8 257 68] (self : t_UnionFind'0) (x : t_Element'0) (y : t_Element'0) = + [%#sunion_find44] index_logic'0 (root_of'0 self) x = index_logic'0 (root_of'0 self) y + + let rec union'0 (self:borrowed (t_UnionFind'0)) (x:t_Element'0) (y:t_Element'0) (return' (ret:()))= {[@expl:union 'self' type invariant] [%#sunion_find26] inv'1 self} + {[@expl:union requires #0] [%#sunion_find27] contains'0 (domain'0 self.current) x} + {[@expl:union requires #1] [%#sunion_find28] contains'0 (domain'0 self.current) y} + any + [ return' (result:())-> {[%#sunion_find29] domain'0 self.final = domain'0 self.current} + {[%#sunion_find30] exists r : t_Element'0 . (r = index_logic'0 (root_of'0 self.current) x + \/ r = index_logic'0 (root_of'0 self.current) y) + /\ (forall z : t_Element'0 . contains'0 (domain'0 self.current) z + -> index_logic'0 (root_of'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + r + else + index_logic'0 (root_of'0 self.current) z + ) + /\ index_logic'1 (values'0 self.final) z + = (if equiv_log'0 self.current z x \/ equiv_log'0 self.current z y then + index_logic'1 (values'0 self.final) r + else + index_logic'1 (values'0 self.current) z + ))} + (! return' {result}) ] + + + predicate unchanged'0 [#"union_find.rs" 163 8 163 43] (self : borrowed (t_UnionFind'0)) = + [%#sunion_find45] domain'0 self.current = domain'0 self.final + /\ root_of'0 self.current = root_of'0 self.final /\ values'0 self.current = values'0 self.final + + let rec find'0 (self:borrowed (t_UnionFind'0)) (elem:t_Element'0) (return' (ret:t_Element'0))= {[@expl:find 'self' type invariant] [%#sunion_find31] inv'1 self} + {[@expl:find requires] [%#sunion_find32] contains'0 (domain'0 self.current) elem} + any + [ return' (result:t_Element'0)-> {[%#sunion_find33] result = index_logic'0 (root_of'0 self.current) elem} + {[%#sunion_find34] unchanged'0 self} + (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + meta "compute_max_steps" 1000000 + + let rec example'0 (_1:()) (return' (ret:()))= (! bb0 + [ bb0 = s0 [ s0 = new'0 {[%#sunion_find0] ()} (fun (_ret':t_UnionFind'0) -> [ &uf <- _ret' ] s1) | s1 = bb1 ] + | bb1 = s0 + [ s0 = {inv'0 uf} + Borrow.borrow_mut {uf} + (fun (_ret':borrowed (t_UnionFind'0)) -> [ &_3 <- _ret' ] -{inv'0 _ret'.final}- [ &uf <- _ret'.final ] s1) + | s1 = make'0 {_3} {[%#sunion_find1] (1 : int32)} (fun (_ret':t_Element'0) -> [ &x <- _ret' ] s2) + | s2 = bb2 ] + + | bb2 = s0 + [ s0 = {inv'0 uf} + Borrow.borrow_mut {uf} + (fun (_ret':borrowed (t_UnionFind'0)) -> [ &_5 <- _ret' ] -{inv'0 _ret'.final}- [ &uf <- _ret'.final ] s1) + | s1 = make'0 {_5} {[%#sunion_find2] (2 : int32)} (fun (_ret':t_Element'0) -> [ &y <- _ret' ] s2) + | s2 = bb3 ] + + | bb3 = s0 + [ s0 = {inv'0 uf} + Borrow.borrow_mut {uf} + (fun (_ret':borrowed (t_UnionFind'0)) -> [ &_7 <- _ret' ] -{inv'0 _ret'.final}- [ &uf <- _ret'.final ] s1) + | s1 = make'0 {_7} {[%#sunion_find3] (3 : int32)} (fun (_ret':t_Element'0) -> [ &z <- _ret' ] s2) + | s2 = bb4 ] + + | bb4 = s0 [ s0 = get'0 {uf} {x} (fun (_ret':int32) -> [ &_11 <- _ret' ] s1) | s1 = bb5 ] + | bb5 = s0 + [ s0 = Int32.eq {_11} {[%#sunion_find4] (1 : int32)} (fun (_ret':bool) -> [ &_9 <- _ret' ] s1) + | s1 = any [ br0 -> {_9 = false} (! bb7) | br1 -> {_9} (! bb6) ] ] + + | bb6 = s0 [ s0 = get'0 {uf} {y} (fun (_ret':int32) -> [ &_18 <- _ret' ] s1) | s1 = bb8 ] + | bb8 = s0 + [ s0 = Int32.eq {_18} {[%#sunion_find5] (2 : int32)} (fun (_ret':bool) -> [ &_16 <- _ret' ] s1) + | s1 = any [ br0 -> {_16 = false} (! bb10) | br1 -> {_16} (! bb9) ] ] + + | bb9 = s0 [ s0 = get'0 {uf} {z} (fun (_ret':int32) -> [ &_25 <- _ret' ] s1) | s1 = bb11 ] + | bb11 = s0 + [ s0 = Int32.eq {_25} {[%#sunion_find6] (3 : int32)} (fun (_ret':bool) -> [ &_23 <- _ret' ] s1) + | s1 = any [ br0 -> {_23 = false} (! bb13) | br1 -> {_23} (! bb12) ] ] + + | bb12 = s0 + [ s0 = {inv'0 uf} + Borrow.borrow_mut {uf} + (fun (_ret':borrowed (t_UnionFind'0)) -> [ &_30 <- _ret' ] -{inv'0 _ret'.final}- [ &uf <- _ret'.final ] s1) + | s1 = union'0 {_30} {x} {y} (fun (_ret':()) -> [ &_29 <- _ret' ] s2) + | s2 = bb14 ] + + | bb14 = s0 + [ s0 = {inv'0 uf} + Borrow.borrow_mut {uf} + (fun (_ret':borrowed (t_UnionFind'0)) -> [ &_34 <- _ret' ] -{inv'0 _ret'.final}- [ &uf <- _ret'.final ] s1) + | s1 = find'0 {_34} {x} (fun (_ret':t_Element'0) -> [ &x1 <- _ret' ] s2) + | s2 = bb15 ] + + | bb15 = s0 + [ s0 = {inv'0 uf} + Borrow.borrow_mut {uf} + (fun (_ret':borrowed (t_UnionFind'0)) -> [ &_37 <- _ret' ] -{inv'0 _ret'.final}- [ &uf <- _ret'.final ] s1) + | s1 = find'0 {_37} {y} (fun (_ret':t_Element'0) -> [ &y1 <- _ret' ] s2) + | s2 = bb16 ] + + | bb16 = s0 [ s0 = get'0 {uf} {x1} (fun (_ret':int32) -> [ &_42 <- _ret' ] s1) | s1 = bb17 ] + | bb17 = s0 [ s0 = get'0 {uf} {y1} (fun (_ret':int32) -> [ &_46 <- _ret' ] s1) | s1 = bb18 ] + | bb18 = s0 + [ s0 = Int32.eq {_42} {_46} (fun (_ret':bool) -> [ &_40 <- _ret' ] s1) + | s1 = any [ br0 -> {_40 = false} (! bb20) | br1 -> {_40} (! bb19) ] ] + + | bb19 = s0 [ s0 = get'0 {uf} {z} (fun (_ret':int32) -> [ &_53 <- _ret' ] s1) | s1 = bb21 ] + | bb21 = s0 + [ s0 = Int32.eq {_53} {[%#sunion_find7] (3 : int32)} (fun (_ret':bool) -> [ &_51 <- _ret' ] s1) + | s1 = any [ br0 -> {_51 = false} (! bb23) | br1 -> {_51} (! bb22) ] ] + + | bb22 = bb24 + | bb24 = return' {_0} + | bb23 = {[%#sunion_find8] false} any + | bb20 = {[%#sunion_find9] false} any + | bb13 = {[%#sunion_find10] false} any + | bb10 = {[%#sunion_find11] false} any + | bb7 = {[%#sunion_find12] false} any ] + ) + [ & _0 : () = any_l () + | & uf : t_UnionFind'0 = any_l () + | & x : t_Element'0 = any_l () + | & _3 : borrowed (t_UnionFind'0) = any_l () + | & y : t_Element'0 = any_l () + | & _5 : borrowed (t_UnionFind'0) = any_l () + | & z : t_Element'0 = any_l () + | & _7 : borrowed (t_UnionFind'0) = any_l () + | & _9 : bool = any_l () + | & _11 : int32 = any_l () + | & _16 : bool = any_l () + | & _18 : int32 = any_l () + | & _23 : bool = any_l () + | & _25 : int32 = any_l () + | & _29 : () = any_l () + | & _30 : borrowed (t_UnionFind'0) = any_l () + | & x1 : t_Element'0 = any_l () + | & _34 : borrowed (t_UnionFind'0) = any_l () + | & y1 : t_Element'0 = any_l () + | & _37 : borrowed (t_UnionFind'0) = any_l () + | & _40 : bool = any_l () + | & _42 : int32 = any_l () + | & _46 : int32 = any_l () + | & _51 : bool = any_l () + | & _53 : int32 = any_l () ] + [ return' (result:())-> (! return' {result}) ] +end +module M_union_find__example_addrs_eq [#"union_find.rs" 419 0 419 77] + let%span sunion_find0 = "union_find.rs" 423 22 423 30 + let%span sunion_find1 = "union_find.rs" 419 27 419 29 + let%span sunion_find2 = "union_find.rs" 418 11 418 63 + let%span sunion_find3 = "union_find.rs" 14 18 14 69 + let%span sunion_find4 = "union_find.rs" 133 19 133 28 + let%span sunion_find5 = "union_find.rs" 134 18 134 150 + let%span sfset6 = "../../../creusot-contracts/src/logic/fset.rs" 46 8 46 26 + let%span smodel7 = "../../../creusot-contracts/src/model.rs" 83 8 83 28 + let%span sinvariant8 = "../../../creusot-contracts/src/invariant.rs" 24 8 24 18 + let%span sboxed9 = "../../../creusot-contracts/src/std/boxed.rs" 28 8 28 18 + let%span sfmap10 = "../../../creusot-contracts/src/logic/fmap.rs" 452 20 452 91 + let%span sfmap11 = "../../../creusot-contracts/src/logic/fmap.rs" 132 8 132 35 + let%span sfmap12 = "../../../creusot-contracts/src/logic/fmap.rs" 124 8 124 35 + let%span sfmap13 = "../../../creusot-contracts/src/logic/fmap.rs" 103 8 103 26 + let%span sutil14 = "../../../creusot-contracts/src/util.rs" 55 11 55 21 + let%span sutil15 = "../../../creusot-contracts/src/util.rs" 56 10 56 28 + let%span sfmap16 = "../../../creusot-contracts/src/logic/fmap.rs" 58 14 58 86 + let%span sptr_own17 = "../../../creusot-contracts/src/ptr_own.rs" 44 20 44 66 + let%span sptr18 = "../../../creusot-contracts/src/std/ptr.rs" 80 14 80 48 + let%span sptr19 = "../../../creusot-contracts/src/std/ptr.rs" 82 8 82 30 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + use prelude.prelude.Int + + function deep_model'1 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int + + function deep_model'0 (self : t_Element'0) : int = + [%#smodel7] deep_model'1 self + + let rec eq'0 (self:t_Element'0) (other:t_Element'0) (return' (ret:bool))= any + [ return' (result:bool)-> {[%#sunion_find3] result = (deep_model'0 self = deep_model'0 other)} + (! return' {result}) ] + + + use prelude.prelude.Intrinsic + + use set.Fset + + use prelude.prelude.Snapshot + + type t_FMap'0 + + type t_GhostBox'0 = + { t_GhostBox__0'0: t_FMap'0 } + + type t_T'0 + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use map.Map + + use prelude.prelude.Snapshot + + use prelude.prelude.Snapshot + + type t_UnionFind'0 = + { t_UnionFind__domain'0: Snapshot.snap_ty (Fset.fset (t_Element'0)); + t_UnionFind__map'0: t_GhostBox'0; + t_UnionFind__values'0: Snapshot.snap_ty (Map.map (t_Element'0) t_T'0); + t_UnionFind__distance'0: Snapshot.snap_ty (Map.map (t_Element'0) int); + t_UnionFind__root_of'0: Snapshot.snap_ty (Map.map (t_Element'0) (t_Element'0)); + t_UnionFind__max_depth'0: Snapshot.snap_ty int } + + predicate invariant'1 [@inline:trivial] [#"union_find.rs" 83 8 83 34] (self : t_UnionFind'0) + + type t_PtrOwn'0 + + type t_Option'0 = + | C_None'0 + | C_Some'0 (t_PtrOwn'0) + + use map.Map + + function view'0 (self : t_FMap'0) : Map.map (Snapshot.snap_ty int) (t_Option'0) + + axiom view'0_spec : forall self : t_FMap'0 . [%#sfmap16] forall m1 : t_FMap'0, m2 : t_FMap'0 . m1 <> m2 + -> view'0 m1 <> view'0 m2 + + use map.Map + + function get_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_Option'0 = + [%#sfmap13] Map.get (view'0 self) k + + function contains'1 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : bool = + [%#sfmap11] get_unsized'0 self k <> C_None'0 + + predicate inv'5 (_1 : Snapshot.snap_ty int) + + axiom inv_axiom'5 [@rewrite] : forall x : Snapshot.snap_ty int [inv'5 x] . inv'5 x = true + + function unwrap'0 (op : t_Option'0) : t_PtrOwn'0 + + axiom unwrap'0_spec : forall op : t_Option'0 . ([%#sutil14] op <> C_None'0) + -> ([%#sutil15] C_Some'0 (unwrap'0 op) = op) + + function lookup_unsized'0 [@inline:trivial] (self : t_FMap'0) (k : Snapshot.snap_ty int) : t_PtrOwn'0 = + [%#sfmap12] unwrap'0 (get_unsized'0 self k) + + function ptr'0 (self : t_PtrOwn'0) : opaque_ptr + + function addr_logic'0 (self : opaque_ptr) : int + + function is_null_logic'0 (self : opaque_ptr) : bool = + [%#sptr19] addr_logic'0 self = 0 + + axiom is_null_logic'0_spec : forall self : opaque_ptr . [%#sptr18] is_null_logic'0 self = (addr_logic'0 self = 0) + + use prelude.prelude.UIntSize + + type t_Content'0 = + | C_Root'0 usize t_T'0 + | C_Link'0 (t_Element'0) + + function val'0 (self : t_PtrOwn'0) : t_Content'0 + + predicate inv'10 (_1 : t_T'0) + + predicate inv'9 (_1 : t_Content'0) + + axiom inv_axiom'9 [@rewrite] : forall x : t_Content'0 [inv'9 x] . inv'9 x + = match x with + | C_Root'0 rank value -> inv'10 value + | C_Link'0 a_0 -> true + end + + predicate invariant'6 (self : t_Content'0) = + [%#sboxed9] inv'9 self + + predicate inv'8 (_1 : t_Content'0) + + axiom inv_axiom'8 [@rewrite] : forall x : t_Content'0 [inv'8 x] . inv'8 x = invariant'6 x + + predicate invariant'5 (self : t_PtrOwn'0) = + [%#sptr_own17] not is_null_logic'0 (ptr'0 self) /\ inv'8 (val'0 self) + + predicate inv'7 (_1 : t_PtrOwn'0) + + axiom inv_axiom'7 [@rewrite] : forall x : t_PtrOwn'0 [inv'7 x] . inv'7 x = invariant'5 x + + predicate invariant'4 (self : t_PtrOwn'0) = + [%#sboxed9] inv'7 self + + predicate inv'6 (_1 : t_PtrOwn'0) + + axiom inv_axiom'6 [@rewrite] : forall x : t_PtrOwn'0 [inv'6 x] . inv'6 x = invariant'4 x + + predicate invariant'3 (self : t_FMap'0) = + [%#sfmap10] forall k : Snapshot.snap_ty int . contains'1 self k -> inv'5 k /\ inv'6 (lookup_unsized'0 self k) + + predicate inv'4 (_1 : t_FMap'0) + + axiom inv_axiom'4 [@rewrite] : forall x : t_FMap'0 [inv'4 x] . inv'4 x = invariant'3 x + + predicate invariant'2 (self : t_FMap'0) = + [%#sboxed9] inv'4 self + + predicate inv'3 (_1 : t_FMap'0) + + axiom inv_axiom'3 [@rewrite] : forall x : t_FMap'0 [inv'3 x] . inv'3 x = invariant'2 x + + predicate inv'2 (_1 : t_GhostBox'0) + + axiom inv_axiom'2 [@rewrite] : forall x : t_GhostBox'0 [inv'2 x] . inv'2 x + = match x with + | {t_GhostBox__0'0 = a_0} -> inv'3 a_0 + end + + predicate inv'1 (_1 : t_UnionFind'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_UnionFind'0 [inv'1 x] . inv'1 x + = (invariant'1 x + /\ match x with + | {t_UnionFind__domain'0 = domain ; t_UnionFind__map'0 = map ; t_UnionFind__values'0 = values ; t_UnionFind__distance'0 = distance ; t_UnionFind__root_of'0 = root_of ; t_UnionFind__max_depth'0 = max_depth} -> inv'2 map + end) + + predicate invariant'0 (self : t_UnionFind'0) = + [%#sinvariant8] inv'1 self + + predicate inv'0 (_1 : t_UnionFind'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_UnionFind'0 [inv'0 x] . inv'0 x = invariant'0 x + + use set.Fset + + predicate contains'0 [@inline:trivial] (self : Fset.fset (t_Element'0)) (e : t_Element'0) = + [%#sfset6] Fset.mem e self + + function domain'0 [#"union_find.rs" 135 8 135 47] (self : t_UnionFind'0) : Fset.fset (t_Element'0) + + axiom domain'0_spec : forall self : t_UnionFind'0 . ([%#sunion_find4] inv'1 self) + -> ([%#sunion_find5] forall e1 : t_Element'0, e2 : t_Element'0 . contains'0 (domain'0 self) e1 + /\ contains'0 (domain'0 self) e2 /\ deep_model'1 e1 = deep_model'1 e2 -> e1 = e2) + + meta "compute_max_steps" 1000000 + + let rec example_addrs_eq'0 (uf:t_UnionFind'0) (e1:t_Element'0) (e2:t_Element'0) (return' (ret:()))= {[@expl:example_addrs_eq 'uf' type invariant] [%#sunion_find1] inv'0 uf} + {[@expl:example_addrs_eq requires] [%#sunion_find2] contains'0 (domain'0 uf) e1 /\ contains'0 (domain'0 uf) e2} + (! bb0 + [ bb0 = s0 [ s0 = eq'0 {e1} {e2} (fun (_ret':bool) -> [ &_5 <- _ret' ] s1) | s1 = bb1 ] + | bb1 = any [ br0 -> {_5 = false} (! bb3) | br1 -> {_5} (! bb2) ] + | bb2 = s0 [ s0 = {[@expl:assertion] [%#sunion_find0] e1 = e2} s1 | s1 = bb4 ] + | bb3 = bb4 + | bb4 = return' {_0} ] + ) [ & _0 : () = any_l () | & e1 : t_Element'0 = e1 | & e2 : t_Element'0 = e2 | & _5 : bool = any_l () ] + [ return' (result:())-> (! return' {result}) ] + +end +module M_union_find__implementation__qyi5509895616124734008__eq__refines [#"union_find.rs" 15 8 15 42] (* as creusot_contracts::PartialEq> *) + let%span sunion_find0 = "union_find.rs" 15 8 15 42 + let%span smodel1 = "../../../creusot-contracts/src/model.rs" 83 8 83 28 + let%span sunion_find2 = "union_find.rs" 21 8 21 16 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + predicate inv'0 (_1 : t_Element'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_Element'0 [inv'0 x] . inv'0 x = true + + use prelude.prelude.Int + + function addr_logic'0 (self : opaque_ptr) : int + + function deep_model'1 [#"union_find.rs" 23 8 23 34] (self : t_Element'0) : int = + [%#sunion_find2] addr_logic'0 self.t_Element__0'0 + + function deep_model'0 (self : t_Element'0) : int = + [%#smodel1] deep_model'1 self + + goal refines : [%#sunion_find0] forall self : t_Element'0 . forall other : t_Element'0 . inv'0 other /\ inv'0 self + -> (forall result : bool . result = (deep_model'0 self = deep_model'0 other) + -> result = (deep_model'0 self = deep_model'0 other)) +end +module M_union_find__implementation__qyi6778176538984101299__clone__refines [#"union_find.rs" 44 8 44 31] (* as creusot_contracts::Clone> *) + let%span sunion_find0 = "union_find.rs" 44 8 44 31 + + use prelude.prelude.Borrow + + use prelude.prelude.Opaque + + type t_Element'0 = + { t_Element__0'0: opaque_ptr } + + predicate inv'0 (_1 : t_Element'0) + + axiom inv_axiom'0 [@rewrite] : forall x : t_Element'0 [inv'0 x] . inv'0 x = true + + predicate inv'1 (_1 : t_Element'0) + + axiom inv_axiom'1 [@rewrite] : forall x : t_Element'0 [inv'1 x] . inv'1 x = true + + goal refines : [%#sunion_find0] forall self : t_Element'0 . inv'0 self + -> (forall result : t_Element'0 . self = result -> result = self /\ inv'1 result) +end diff --git a/creusot/tests/should_succeed/union_find.rs b/creusot/tests/should_succeed/union_find.rs new file mode 100644 index 000000000..a457162ad --- /dev/null +++ b/creusot/tests/should_succeed/union_find.rs @@ -0,0 +1,425 @@ +extern crate creusot_contracts; + +// This proof is largely adapted from the one in Vocal (see https://github.com/ocaml-gospel/vocal/blob/main/proofs/why3/UnionFind_impl.mlw) +mod implementation { + use creusot_contracts::{ + logic::{FMap, FSet, Mapping}, + ptr_own::PtrOwn, + Clone, *, + }; + + pub struct Element(*const Content); + + impl PartialEq for Element { + #[ensures(result == (self.deep_model() == other.deep_model()))] + fn eq(&self, other: &Self) -> bool { + std::ptr::addr_eq(self.0, other.0) + } + } + impl DeepModel for Element { + type DeepModelTy = Int; + #[logic] + #[open(self)] + fn deep_model(self) -> Int { + self.0.addr_logic() + } + } + + impl Element { + #[pure] + #[ensures(*result == self.deep_model())] + fn addr(self) -> Snapshot { + snapshot!(self.deep_model()) + } + } + + enum Content { + Root { rank: usize, value: T }, + Link(Element), + } + + impl Clone for Element { + #[ensures(*self == result)] + #[pure] + fn clone(&self) -> Self { + Self(self.0) + } + } + impl Copy for Element {} + + type LogicAddr = Snapshot; + + /// Handle to the union-find data structure. + /// + /// This is a purely logical construct, that must be used so Creusot knows how to interpret + /// the values of [`Element`]s. + pub struct UnionFind { + /// which "pointers" are involved + domain: Snapshot>>, + /// Maps an element to its logical content (represented by the permission to access it). + map: GhostBox>>>, + /// Map each element in [`Self::domain`] to its value. + // `img` in the why3 proof + values: Snapshot, T>>, + /// Maps each element to its distance to its root. + distance: Snapshot, Int>>, + // `rep` in the why3 proof + root_of: Snapshot, Element>>, + max_depth: Snapshot, + } + + // Ignore overflows for now + #[trusted] + #[requires(true)] + #[ensures(result@ == x@ + y@)] + fn add_no_overflow(x: usize, y: usize) -> usize { + x + y + } + + impl Invariant for UnionFind { + #[predicate] + #[open(self)] + #[why3::attr = "inline:trivial"] + fn invariant(self) -> bool { + let domain = self.domain; + pearlite! { + // this invariant was not in the why3 proof: it is here because of the specifics of `DeepModel` and equality in Creusot + (forall domain.contains(e1) && domain.contains(e2) && e1.deep_model() == e2.deep_model() ==> e1 == e2) && + // this invariant was not in the why3 proof: it ensures that the keys and the values of `map` agree + (forall domain.contains(e) ==> self.map.contains(Snapshot::new(e.deep_model()))) && + (forall domain.contains(e) ==> e.0 == self.get_perm(e).ptr()) && + (forall domain.contains(e) ==> self.values[e] == self.values[self.root_of[e]]) && + (forall domain.contains(e) ==> self.root_of[self.root_of[e]] == self.root_of[e]) && + (forall domain.contains(e) ==> domain.contains(self.root_of[e])) && + (forall domain.contains(e) ==> match *self.get_perm(e).val() { + Content::Link(e2) => e != e2 && domain.contains(e2) && self.root_of[e] == self.root_of[e2], + Content::Root { rank: _, value: v } => self.values[e] == v && self.root_of[e] == e, + }) && + (forall domain.contains(e) ==> match *self.get_perm(e).val() { + Content::Link(e2) => self.distance[e] < self.distance[e2], + Content::Root { .. } => true, + }) && + *self.max_depth >= 0 && + (forall domain.contains(e) ==> 0 <= self.distance[e] && self.distance[e] <= *self.max_depth) && + (forall domain.contains(e) ==> match *self.get_perm(self.root_of[e]).val() { + Content::Root { .. } => true, + Content::Link { .. } => false, + }) + } + } + } + + impl UnionFind { + #[ensures(result.domain.is_empty())] + pub fn new() -> Self { + Self { + domain: snapshot!(FSet::EMPTY), + map: FMap::new(), + values: snapshot!(such_that(|_| true)), + distance: snapshot!(such_that(|_| true)), + root_of: snapshot!(such_that(|_| true)), + max_depth: snapshot!(0), + } + } + + #[logic] + fn get_perm(self, e: Element) -> PtrOwn> { + self.map[Snapshot::new(e.deep_model())] + } + + /// Returns all the element that are handled by this union-find structure. + #[logic] + #[open(self)] + #[requires(inv(self))] + #[ensures(forall, e2: Element> result.contains(e1) && result.contains(e2) && e1.deep_model() == e2.deep_model() ==> e1 == e2)] + pub fn domain(self) -> FSet> { + *self.domain + } + + /// Returns the map of roots of the union find. + /// + /// For each element, this describes the unique root element of the associated set. + /// The root element of a root is itself. + #[logic] + #[open(self)] + #[requires(inv(self))] + #[ensures(forall> self.domain.contains(e) ==> result[e] == result[result[e]])] + pub fn root_of(self) -> Mapping, Element> { + *self.root_of + } + + /// Returns the values associated with each element. + #[logic] + #[open(self)] + #[requires(inv(self))] + #[ensures(forall> self.domain.contains(e) ==> result[e] == result[self.root_of()[e]])] + pub fn values(self) -> Mapping, T> { + *self.values + } + + /// The internals of the union-find may have changed, but the API did not + #[predicate(prophetic)] + #[open] + pub fn unchanged(&mut self) -> bool { + pearlite! { + (*self).domain() == (^self).domain() && + (*self).root_of() == (^self).root_of() && + (*self).values() == (^self).values() + } + } + + #[ensures(!(*self).domain().contains(result))] + #[ensures((^self).domain() == (*self).domain().insert(result))] + #[ensures((^self).root_of() == (*self).root_of().set(result, result))] + #[ensures((^self).values() == (*self).values().set(result, value))] + pub fn make(&mut self, value: T) -> Element { + let (ptr, perm) = PtrOwn::new(Content::Root { rank: 0, value }); + let element = Element(ptr); + let mut map = self.map.borrow_mut(); + ghost! { + let perm = perm.into_inner(); + match map.get_mut_ghost(&element.addr()) { + None => {}, + Some(other_perm) => PtrOwn::disjoint_lemma(other_perm, &perm), + } + map.insert_ghost(element.addr(), perm); + }; + self.domain = snapshot!(self.domain.insert(element)); + self.values = snapshot!(self.values.set(element, value)); + self.distance = snapshot!(self.distance.set(element, 0)); + self.root_of = snapshot!(self.root_of.set(element, element)); + element + } + + /// Inner function, to hide specifications that only concern the distance. + #[requires(self.domain().contains(elem))] + #[ensures(result == self.root_of()[elem])] + #[ensures(self.unchanged())] + // internal + #[ensures((^self).distance == (*self).distance)] + #[ensures(self.distance[result] >= self.distance[elem])] + fn find_inner(&mut self, elem: Element) -> Element { + let map = self.map.borrow(); + let perm = ghost!(map.get_ghost(&elem.addr()).unwrap()); + let value = PtrOwn::as_ref(elem.0, perm); + match value { + Content::Root { .. } => elem, + Content::Link(e) => { + let root = self.find_inner(*e); + // path compression + let mut map = self.map.borrow_mut(); + let mut_perm = ghost!(map.get_mut_ghost(&elem.addr()).unwrap()); + *PtrOwn::as_mut(elem.0, mut_perm) = Content::Link(root); + root + } + } + } + + /// Find the representative element of `elem`. + #[requires(self.domain().contains(elem))] + #[ensures(result == self.root_of()[elem])] + #[ensures(self.unchanged())] + pub fn find(&mut self, elem: Element) -> Element { + self.find_inner(elem) + } + + /// Get the value of `elem`, provided it is a root. + /// + /// To guarantee that `elem` is a root, call [`Self::find`] before. + #[requires(self.domain().contains(elem))] + #[requires(self.root_of()[elem] == elem)] + #[ensures(*result == self.values()[elem])] + pub fn get(&self, elem: Element) -> &T { + let map = self.map.borrow(); + let perm = ghost!(map.get_ghost(&elem.addr()).unwrap()); + match PtrOwn::as_ref(elem.0, perm) { + Content::Root { value, .. } => value, + _ => loop {}, + } + } + + /// Returns `true` if `x` and `y` are in the same class. + #[requires((*self).domain().contains(e1))] + #[requires((*self).domain().contains(e2))] + #[ensures(result == (self.root_of()[e1] == self.root_of()[e2]))] + #[ensures(self.unchanged())] + pub fn equiv(&mut self, e1: Element, e2: Element) -> bool { + let r1 = self.find(e1); + let r2 = self.find(e2); + std::ptr::addr_eq(r1.0, r2.0) + } + + /// Returns `true` if `x` and `y` are in the same class. + /// + /// This is the logical version of [`Self::equiv`] + #[predicate] + #[open] + pub fn equiv_log(self, x: Element, y: Element) -> bool { + self.root_of()[x] == self.root_of()[y] + } + + /// If `x` and `y` are two roots, try to link them together. + #[requires(self.domain().contains(x))] + #[requires(self.root_of()[x] == x)] + #[requires(self.domain().contains(y))] + #[requires(self.root_of()[y] == y)] + #[ensures((^self).domain() == (*self).domain())] + #[ensures(result == (*self).root_of()[x] || result == (*self).root_of()[y])] + #[ensures(result == (^self).root_of()[result])] + #[ensures(forall> self.domain().contains(z) ==> (^self).root_of()[z] + == if (*self).equiv_log(z, x) || (*self).equiv_log(z, y) { + result + } else { + (*self).root_of()[z] + } + )] + #[ensures(forall> self.domain().contains(z) ==> (^self).values()[z] + == if (*self).equiv_log(z, x) || (*self).equiv_log(z, y) { + (^self).values()[result] + } else { + (*self).values()[z] + } + )] + fn link(&mut self, x: Element, y: Element) -> Element { + if x == y { + return x; + } + let mut map = self.map.borrow_mut(); + let perm_x = ghost!(map.get_ghost(&x.addr()).unwrap()); + let perm_y = ghost!(map.get_ghost(&y.addr()).unwrap()); + let Content::Root { rank: rx, value: ref vx } = *PtrOwn::as_ref(x.0, perm_x) else { + unreachable!() + }; + let Content::Root { rank: ry, value: ref vy } = *PtrOwn::as_ref(y.0, perm_y) else { + unreachable!() + }; + if rx < ry { + let perm_mut_x = ghost!(map.get_mut_ghost(&x.addr()).unwrap()); + *PtrOwn::as_mut(x.0, perm_mut_x) = Content::Link(y); + self.root_of = snapshot!(|z| { + if self.root_of[z] == x { + y + } else { + self.root_of[z] + } + }); + self.values = snapshot!(|z| { + if self.root_of[z] == y { + *vy + } else { + self.values[z] + } + }); + self.max_depth = snapshot!(*self.max_depth + 1); + self.distance = + snapshot!(self.distance.set(y, 1 + self.distance[x].max(self.distance[y]))); + y + } else { + let perm_mut_y = ghost!(map.get_mut_ghost(&y.addr()).unwrap()); + *PtrOwn::as_mut(y.0, perm_mut_y) = Content::Link(x); + if rx == ry { + let perm_mut_x = ghost!(map.get_mut_ghost(&x.addr()).unwrap()); + match PtrOwn::as_mut(x.0, perm_mut_x) { + Content::Root { rank, value: _ } => *rank = add_no_overflow(rx, 1), + _ => {} + } + } + self.root_of = snapshot!(|z| { + if self.root_of[z] == y { + x + } else { + self.root_of[z] + } + }); + self.values = snapshot!(|z| { + if self.root_of[z] == x { + *vx + } else { + self.values[z] + } + }); + self.max_depth = snapshot!(*self.max_depth + 1); + self.distance = + snapshot!(self.distance.set(x, 1 + self.distance[x].max(self.distance[y]))); + x + } + } + + /// Link `x` and `y` together (put them in the same class). + #[requires(self.domain().contains(x))] + #[requires(self.domain().contains(y))] + #[ensures((^self).domain() == (*self).domain())] + #[ensures(result == (*self).root_of()[x] || result == (*self).root_of()[y])] + #[ensures(forall> self.domain().contains(z) ==> (^self).root_of()[z] + == if (*self).equiv_log(z, x) || (*self).equiv_log(z, y) { + result + } else { + (*self).root_of()[z] + } + )] + #[ensures(forall> self.domain().contains(z) ==> (^self).values()[z] + == if (*self).equiv_log(z, x) || (*self).equiv_log(z, y) { + (^self).values()[result] + } else { + (*self).values()[z] + } + )] + fn union_aux(&mut self, x: Element, y: Element) -> Element { + let rx = self.find(x); + let ry = self.find(y); + self.link(rx, ry) + } + + /// Fuse the classes of `x` and `y`. + #[requires(self.domain().contains(x))] + #[requires(self.domain().contains(y))] + #[ensures((^self).domain() == (*self).domain())] + #[ensures(exists> (r == (*self).root_of()[x] || r == (*self).root_of()[y]) && { + forall self.domain().contains(z) ==> { + ((^self).root_of()[z] == if (*self).equiv_log(z, x) || (*self).equiv_log(z, y) { + r + } else { + (*self).root_of()[z] + }) && ((^self).values()[z] == if (*self).equiv_log(z, x) || (*self).equiv_log(z, y) { + (^self).values()[r] + } else { + (*self).values()[z] + }) + } + })] + pub fn union(&mut self, x: Element, y: Element) { + let _ = self.union_aux(x, y); + } + } +} + +use creusot_contracts::*; +use implementation::{Element, UnionFind}; + +pub fn example() { + let mut uf = UnionFind::::new(); + + let x = uf.make(1); + let y = uf.make(2); + let z = uf.make(3); + + assert!(*uf.get(x) == 1); + assert!(*uf.get(y) == 2); + assert!(*uf.get(z) == 3); + + uf.union(x, y); + let x = uf.find(x); + let y = uf.find(y); + + assert!(*uf.get(x) == *uf.get(y)); + assert!(*uf.get(z) == 3); +} + +#[requires(uf.domain().contains(e1) && uf.domain().contains(e2))] +pub fn example_addrs_eq(uf: &UnionFind, e1: Element, e2: Element) { + // the runtime test ensures equality of the adresses + if e1 == e2 { + // we get logical equality of e1 and e2 thanks to the postcondition of `domain` + proof_assert!(e1 == e2); + } +} diff --git a/creusot/tests/should_succeed/union_find/why3session.xml b/creusot/tests/should_succeed/union_find/why3session.xml new file mode 100644 index 000000000..b898f1241 --- /dev/null +++ b/creusot/tests/should_succeed/union_find/why3session.xml @@ -0,0 +1,1372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/creusot/tests/should_succeed/union_find/why3shapes.gz b/creusot/tests/should_succeed/union_find/why3shapes.gz new file mode 100644 index 0000000000000000000000000000000000000000..5cca82b7be5f22b635b5919e52f56c8d463bb8b2 GIT binary patch literal 22652 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 literal 0 HcmV?d00001