1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283moduleB=Kernel.BasicmoduleL=Common.LogicmoduleO=Common.OraclemoduleU=Common.UniversesmoduleZ=Z3typet=Z.Expr.exprtypesmt_model=Z.Model.modeltypectx=Z.contextletlogic=`Qfuf(* Z3 type for universes *)letsortctx=Z.Sort.mk_uninterpreted_sctx"Sort"(** [var_of_name name] returns a variable string for Z3. *)letmk_namecst=B.string_of_mident(B.mdcst)^B.string_of_ident(B.idcst)letmk_enumctxi=Z.Expr.mk_const_sctx("Enum"^string_of_inti)(sortctx)letmk_varctxs=Z.Expr.mk_const_sctxs(sortctx)letmk_sinfctx=Z.Expr.mk_const_sctx"Sinf"(sortctx)(** [mk_univ ctx u] construct a Z3 expression from a universe. *)letmk_univctx=function|U.Sinf->mk_sinfctx|U.Varx->mk_varctx(mk_namex)|U.Enumi->mk_enumctxiletbool_sortctx=Z.Boolean.mk_sortctx(** [mk_axiom s s'] construct the Z3 predicate associated to the Axiom Predicate *)letmk_axiomctxss'=letsort=sortctxinletbool_sort=bool_sortctxinletaxiom=Z.FuncDecl.mk_func_decl_sctx"A"[sort;sort]bool_sortinZ.Expr.mk_appctxaxiom[s;s'](** [mk_cumul s s'] construct the Z3 predicate associated to the Cumul Predicate *)letmk_cumulctxss'=letsort=sortctxinletbool_sort=bool_sortctxinletcumul=Z.FuncDecl.mk_func_decl_sctx"C"[sort;sort]bool_sortinZ.Expr.mk_appctxcumul[s;s'](** [mk_rule s s' s''] construct the Z3 predicate associated to the Rule Predicate *)letmk_rulectxss's''=letsort=sortctxinletbool_sort=bool_sortctxinletcumul=Z.FuncDecl.mk_func_decl_sctx"R"[sort;sort;sort]bool_sortinZ.Expr.mk_appctxcumul[s;s';s''](** [register_vars vars i] give bound for each variable [var] between [0] and [i] *)letmk_boundsctxvari=letunivs=O.enumerateiinletor_eqs=List.map(funu->Z.Boolean.mk_eqctx(mk_varctxvar)(mk_univctxu))univsinZ.Boolean.mk_orctxor_eqs(** [solution_of_var univs model var] looks for the concrete universe associated to [var]
in the [model]. Such universe satisfy that model(univ) = model(var). *)letsolution_of_varctximodelvar=letunivs=O.enumerateiinletexceptionFoundofU.univinletfind_univeu=matchZ.Model.get_const_interp_emodel(mk_univctxu)with|None->assertfalse|Someu'->ife=u'thenraise(Foundu)else()inmatchZ.Model.get_const_interp_emodel(mk_varctxvar)with|None->assertfalse|Somee->(tryList.iter(find_unive)univs;failwith"Variable was not found in the model, this error should be reported"withFoundu->u)