Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file unordered_array_fold.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140openCore_kernelopenImportopenTypes.KindmoduleNode=Types.NodemoduleUpdate=structtype('a,'b)t=|F_inverseof('b->'a->'b)|Updateof('b->old_value:'a->new_value:'a->'b)[@@derivingsexp_of]letupdatet~f=matchtwith|Updateupdate->update|F_inversef_inverse->funfold_value~old_value~new_value->f(f_inversefold_valueold_value)new_value;;endtype('a,'acc)t=('a,'acc)Types.Unordered_array_fold.t={main:'accNode.t;init:'acc;f:'acc->'a->'acc;update:'acc->old_value:'a->new_value:'a->'acc;full_compute_every_n_changes:int;children:'aNode.tarray;mutablefold_value:'accUopt.t;mutablenum_changes_since_last_full_compute:int}[@@derivingfields,sexp_of]letsame(t1:(_,_)t)(t2:(_,_)t)=phys_samet1t2letinvariantinvariant_ainvariant_acct=Invariant.invariant[%here]t[%sexp_of:(_,_)t](fun()->letcheckf=Invariant.check_fieldtfinFields.iter~main:(check(fun(main:_Node.t)->matchmain.kindwith|Invalid->()|Unordered_array_foldt'->assert(samett')|_->assertfalse))~init:(checkinvariant_acc)~f:ignore~update:ignore~children:(check(funchildren->Array.iterchildren~f:(fun(child:_Node.t)->Uopt.invariantinvariant_achild.value_opt;ift.num_changes_since_last_full_compute<t.full_compute_every_n_changesthenassert(Uopt.is_somechild.value_opt))))~fold_value:(check(funfold_value->Uopt.invariantinvariant_accfold_value;[%test_result:bool](Uopt.is_somefold_value)~expect:(t.num_changes_since_last_full_compute<t.full_compute_every_n_changes)))~num_changes_since_last_full_compute:(check(funnum_changes_since_last_full_compute->assert(num_changes_since_last_full_compute>=0);assert(num_changes_since_last_full_compute<=t.full_compute_every_n_changes)))~full_compute_every_n_changes:(check(funfull_compute_every_n_changes->assert(full_compute_every_n_changes>0))));;letcreate~init~f~update~full_compute_every_n_changes~children~main={init;f;update=Update.updateupdate~f;full_compute_every_n_changes;children;main;fold_value=Uopt.none(* We make [num_changes_since_last_full_compute = full_compute_every_n_changes]
so that there will be a full computation the next time the node is computed. *);num_changes_since_last_full_compute=full_compute_every_n_changes};;letfull_compute{init;f;children;_}=letresult=refinitinfori=0toArray.lengthchildren-1doresult:=f!result(Uopt.value_exn(Array.unsafe_getchildreni).value_opt)done;!result;;letcomputet=ift.num_changes_since_last_full_compute=t.full_compute_every_n_changesthen(t.num_changes_since_last_full_compute<-0;t.fold_value<-Uopt.some(full_computet));Uopt.value_exnt.fold_value;;letforce_full_computet=t.fold_value<-Uopt.none;t.num_changes_since_last_full_compute<-t.full_compute_every_n_changes;;letchild_changed(typeab)(t:(a,_)t)~(child:bNode.t)~child_index~(old_value_opt:bUopt.t)~(new_value:b)=letchild_at_index=t.children.(child_index)inmatchNode.type_equal_if_phys_samechildchild_at_indexwith|None->raise_s[%message"[Unordered_array_fold.child_changed] mismatch"~unordered_array_fold:(t:(_,_)t)(child_index:int)(child:_Node.t)]|SomeT->ift.num_changes_since_last_full_compute<t.full_compute_every_n_changes-1then(t.num_changes_since_last_full_compute<-t.num_changes_since_last_full_compute+1;(* We only reach this case if we have already done a full compute, in which case
[Uopt.is_some t.fold_value] and [Uopt.is_some old_value_opt]. *)t.fold_value<-Uopt.some(t.update(Uopt.value_exnt.fold_value)~old_value:(Uopt.value_exnold_value_opt)~new_value))elseift.num_changes_since_last_full_compute<t.full_compute_every_n_changesthenforce_full_computet;;