123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118moduletypeSPEC=sigmoduleLeft:Zset.SmoduleRight:Zset.SmoduleOut:Zset.Stypekeyvalcompare_key:key->key->intvalkey_left:Left.elt->keyvalkey_right:Right.elt->keyvalcombine:Left.elt->Right.elt->Out.eltendmoduleMake(S:SPEC)=structmoduleKMap=Map.Make(structtypet=S.keyletcompare=S.compare_keyend)typet={mutableil:S.Left.tKMap.t(* integrated left input, indexed by join key *);mutableir:S.Right.tKMap.t(* integrated right input, indexed by join key *);mutableout:S.Out.t(* materialized join output *)}letcreate()={il=KMap.empty;ir=KMap.empty;out=S.Out.zero}letlookup_lidxk=matchKMap.find_optkidxwith|Somez->z|None->S.Left.zero;;letlookup_ridxk=matchKMap.find_optkidxwith|Somez->z|None->S.Right.zero;;(* Bucket a left delta into per-key Z-sets. *)letindex_left(d:S.Left.t):S.Left.tKMap.t=S.Left.fold(funewacc->letk=S.key_lefteinKMap.addk(S.Left.add(lookup_lacck)(S.Left.singletonew))acc)dKMap.empty;;letindex_right(d:S.Right.t):S.Right.tKMap.t=S.Right.fold(funewacc->letk=S.key_righteinKMap.addk(S.Right.add(lookup_racck)(S.Right.singletonew))acc)dKMap.empty;;(* [dl] joined against the right side reachable through [right_of]: each matched
pair contributes [combine l r] with the product of weights. *)letjoin_left_with(dl:S.Left.t)(right_of:S.key->S.Right.t):S.Out.t=S.Left.fold(funlwlacc->S.Right.fold(funrwracc2->S.Out.addacc2(S.Out.singleton(S.combinelr)(wl*wr)))(right_of(S.key_leftl))acc)dlS.Out.zero;;letjoin_right_with(dr:S.Right.t)(left_of:S.key->S.Left.t):S.Out.t=S.Right.fold(funrwracc->S.Left.fold(funlwlacc2->S.Out.addacc2(S.Out.singleton(S.combinelr)(wl*wr)))(left_of(S.key_rightr))acc)drS.Out.zero;;(* Fold an indexed left delta into the integrated left index, per key, dropping
keys whose bucket cancels to empty. *)letmerge_leftintodelta=KMap.fold(funkzacc->letmerged=S.Left.add(lookup_lacck)zinifS.Left.is_zeromergedthenKMap.removekaccelseKMap.addkmergedacc)deltainto;;letmerge_rightintodelta=KMap.fold(funkzacc->letmerged=S.Right.add(lookup_racck)zinifS.Right.is_zeromergedthenKMap.removekaccelseKMap.addkmergedacc)deltainto;;letstept~left~right=letdr_idx=index_rightrightin(* Δ(L ⋈ R) = ΔL ⋈ IR + IL ⋈ ΔR + ΔL ⋈ ΔR, all against the OLD integrals. *)letterm1=join_left_withleft(lookup_rt.ir)inletterm2=join_right_withright(lookup_lt.il)inletterm3=join_left_withleft(lookup_rdr_idx)inletdelta=S.Out.add(S.Out.addterm1term2)term3int.il<-merge_leftt.il(index_leftleft);t.ir<-merge_rightt.irdr_idx;t.out<-S.Out.addt.outdelta;delta;;letoutputt=t.outend