12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273openCoreopen!ImportopenTypes.KindmoduleBind=Types.BindmoduleNode=Types.NodemoduleScope=Types.Scopetype('a,'b)t=('a,'b)Bind.t={main:'bNode.t;(* [f] is the user-supplied function that we run each time [t.lhs] changes. It is
mutable only so we can clear it when [t] is invalidated. *)mutablef:'a->'bNode.t;lhs:'aNode.t;lhs_change:unitNode.t;(* [rhs] is initially [none], and after that is [some] of the result of the most recent
call to [f]. *)mutablerhs:'bNode.tUopt.t;(* [rhs_scope] is the scope in which [t.f] is run, i.e. it is [Scope.Bind t]. It is
[mutable] only to avoid a [let rec] during creation. *)mutablerhs_scope:Scope.t;(* [all_nodes_created_on_rhs] is the head of the singly-linked list of nodes created on
the right-hand side of [t], i.e. in [t.rhs_scope]. *)mutableall_nodes_created_on_rhs:Node.Packed.tUopt.t}[@@derivingfields~iterators:iter,sexp_of]letsame(t1:(_,_)t)(t2:(_,_)t)=phys_samet1t2letis_validt=matcht.main.kindwith|Invalid->false|_->true;;letiter_nodes_created_on_rhst~(f:Node.Packed.t->unit)=letr=reft.all_nodes_created_on_rhsinwhileUopt.is_some!rdolet(Tnode_on_rhs)=Uopt.unsafe_value!rinr:=node_on_rhs.next_node_in_same_scope;f(Tnode_on_rhs)done;;letinvariant_invariant_a_invariant_bt=Invariant.invariant[%here]t[%sexp_of:(_,_)t](fun()->letcheckf=Invariant.check_fieldtfinFields.iter~main:(check(fun(main:_Node.t)->matchmain.kindwith|Invalid->()|Bind_maint'->assert(samett')|_->assertfalse))~f:ignore~lhs:ignore~lhs_change:(check(fun(lhs_change:_Node.t)->assert(phys_equallhs_change.created_int.main.created_in);matchlhs_change.kindwith|Invalid->()|Bind_lhs_changet'->assert(samett')|_->assertfalse))~rhs:ignore~rhs_scope:(check(function|Scope.Top->assertfalse|Bindt'->assert(samett')))~all_nodes_created_on_rhs:(check(fun_->iter_nodes_created_on_rhst~f:(fun(Tnode)->assert(phys_equalnode.created_int.rhs_scope);ifNode.is_necessarynodethenassert(t.lhs_change.height<node.height)))));;