123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152openBatteriesopenConstrSysopenSolverTypes(** Translate a [DemandConstrSys] into a [EqConstrSys] *)moduleEqConstrSysFromDemandConstrSys(S:DemandEqConstrSys):EqConstrSyswithtypev=S.vandtyped=S.dandmoduleVar=S.VarandmoduleDom=S.Dom=structtypev=S.vtyped=S.dmoduleVar=S.VarmoduleDom=S.Domletsystem(x:v)=matchS.systemxwith|None->None|Somef->letf'getset=fgetset(ignore%get)inSomef'letsys_change=S.sys_changeletpostmortem=S.postmortemend(** Translate a [DemandGlobConstrSys] into a [DemandEqConstrSys] *)moduleEqConstrSysFromGlobConstrSys(S:DemandGlobConstrSys):DemandEqConstrSyswithtypev=Var2(S.LVar)(S.GVar).tandtyped=Lattice.Lift2(S.G)(S.D).tandmoduleVar=Var2(S.LVar)(S.GVar)andmoduleDom=Lattice.Lift2(S.G)(S.D)=structmoduleVar=Var2(S.LVar)(S.GVar)moduleDom=structincludeLattice.Lift2(S.G)(S.D)letprintXmlf=function|`Lifted1a->S.G.printXmlfa|`Lifted2a->S.D.printXmlfa|(`Bot|`Top)asx->printXmlfxendtypev=Var.ttyped=Dom.tletgetG=function|`Lifted1x->x|`Bot->S.G.bot()|`Top->failwith"EqConstrSysFromGlobConstrSys.getG: global variable has top value"|`Lifted2_->failwith"EqConstrSysFromGlobConstrSys.getG: global variable has local value"letgetL=function|`Lifted2x->x|`Bot->S.D.bot()|`Top->failwith"EqConstrSysFromGlobConstrSys.getL: local variable has top value"|`Lifted1_->failwith"EqConstrSysFromGlobConstrSys.getL: local variable has global value"letl,g=(funx->`Lx),(funx->`Gx)letlD,gD=(funx->`Lifted2x),(funx->`Lifted1x)letconvfgetsetdemand=f(getL%get%l)(funxv->set(lx)(lDv))(funx->demand@@lx)(getG%get%g)(funxv->set(gx)(gDv))|>lDletsystem=function|`G_->None|`Lx->Option.mapconv(S.systemx)letsys_changeget=S.sys_change(getL%get%l)(getG%get%g)letpostmortem=function|`Lg->List.map(funx->`Lx)@@S.postmortemg|_->[]end(** Splits a [EqConstrSys] solution into a [GlobConstrSys] solution with given [Hashtbl.S] for the [EqConstrSys]. *)moduleGlobConstrSolFromEqConstrSolBase(S:DemandGlobConstrSys)(LH:Hashtbl.Swithtypekey=S.LVar.t)(GH:Hashtbl.Swithtypekey=S.GVar.t)(VH:Hashtbl.Swithtypekey=Var2(S.LVar)(S.GVar).t)=structletsplit_solutionhm=letl'=LH.create113inletg'=GH.create113inletsplit_varsxd=matchxwith|`Lx->beginmatchdwith|`Lifted2d->LH.replacel'xd(* | `Bot -> () *)(* Since Verify2 is broken and only checks existing keys, add it with local bottom value.
This works around some cases, where Verify2 would not detect a problem due to completely missing variable. *)|`Bot->LH.replacel'x(S.D.bot())|`Top->failwith"GlobConstrSolFromEqConstrSolBase.split_vars: local variable has top value"|`Lifted1_->failwith"GlobConstrSolFromEqConstrSolBase.split_vars: local variable has global value"end|`Gx->beginmatchdwith|`Lifted1d->GH.replaceg'xd|`Bot->()|`Top->failwith"GlobConstrSolFromEqConstrSolBase.split_vars: global variable has top value"|`Lifted2_->failwith"GlobConstrSolFromEqConstrSolBase.split_vars: global variable has local value"endinVH.itersplit_varshm;(l',g')end(** Splits a [EqConstrSys] solution into a [GlobConstrSys] solution. *)moduleGlobConstrSolFromEqConstrSol(S:DemandGlobConstrSys)(LH:Hashtbl.Swithtypekey=S.LVar.t)(GH:Hashtbl.Swithtypekey=S.GVar.t)=structmoduleS2=EqConstrSysFromGlobConstrSys(S)moduleVH=Hashtbl.Make(S2.Var)includeGlobConstrSolFromEqConstrSolBase(S)(LH)(GH)(VH)endmoduleDemandEqIncrSolverFromGenericEqIncrSolver(Sol:GenericEqIncrSolver):DemandEqIncrSolver=functor(Arg:IncrSolverArg)->functor(S:DemandEqConstrSys)->functor(H:Hashtbl.Swithtypekey=S.v)->Sol(Arg)(EqConstrSysFromDemandConstrSys(S))(H)(** Transforms a [DemandEqIncrSolver] into a [DemandGlobIncrSolver]. *)moduleGlobSolverFromEqSolver(Sol:DemandEqIncrSolverBase)=functor(S:DemandGlobConstrSys)->functor(LH:Hashtbl.Swithtypekey=S.LVar.t)->functor(GH:Hashtbl.Swithtypekey=S.GVar.t)->structmoduleEqSys=EqConstrSysFromGlobConstrSys(S)moduleVH:Hashtbl.Swithtypekey=EqSys.v=Hashtbl.Make(EqSys.Var)moduleSol'=Sol(EqSys)(VH)moduleSplitter=GlobConstrSolFromEqConstrSolBase(S)(LH)(GH)(VH)(* reuse EqSys and VH *)typemarshal=Sol'.marshalletcopy_marshal=Sol'.copy_marshalletrelift_marshal=Sol'.relift_marshalletsolvelsgslold_data=letvs=List.map(fun(x,v)->`Lx,`Lifted2v)ls@List.map(fun(x,v)->`Gx,`Lifted1v)gsinletsv=List.map(funx->`Lx)linlethm,solver_data=Sol'.solvevssvold_datainSplitter.split_solutionhm,solver_dataend