12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394open!Coreopen!Importletunit_type_id=Type_equal.Id.create~name:"()"[%sexp_of:unit]letnothing_type_id=Type_equal.Id.create~name:"Nothing.t"[%sexp_of:Nothing.t]moduleModel=structtype'at={default:'a;equal:'a->'a->bool;type_id:'aType_equal.Id.t;sexp_of:'a->Sexp.t;of_sexp:Sexp.t->'a}letunit={type_id=unit_type_id;default=();equal=equal_unit;sexp_of=sexp_of_unit;of_sexp=unit_of_sexp};;letof_module(typet)(moduleM:Modelwithtypet=t)~default~name=lettype_id=Type_equal.Id.create~name:(sprintf"%s-model"name)M.sexp_of_tin{type_id;default;equal=M.equal;sexp_of=M.sexp_of_t;of_sexp=M.t_of_sexp};;letbothmodel1model2=letsexp_of=Tuple2.sexp_of_tmodel1.sexp_ofmodel2.sexp_ofinletof_sexp=Tuple2.t_of_sexpmodel1.of_sexpmodel2.of_sexpinlettype_id=Type_equal.Id.createsexp_of~name:(sprintf"(%s * %s)"(Type_equal.Id.namemodel1.type_id)(Type_equal.Id.namemodel2.type_id))inletdefault=model1.default,model2.defaultinletequal=Tuple2.equal~eq1:model1.equal~eq2:model2.equalin{type_id;default;equal;sexp_of;of_sexp};;letmap(typekcmp)(moduleM:Comparatorwithtypet=kandtypecomparator_witness=cmp)model=letsexp_of_model=model.sexp_ofinletmodel_of_sexp=model.of_sexpinletsexp_of_map_model=[%sexp_of:modelMap.M(M).t]inletmodel_map_type_id=Type_equal.Id.create~name:(sprintf"map to %s"(Type_equal.Id.namemodel.type_id))sexp_of_map_modelin{type_id=model_map_type_id;default=Map.empty(moduleM);equal=Map.equalmodel.equal;sexp_of=sexp_of_map_model;of_sexp=[%of_sexp:modelMap.M(M).t]};;endmoduleAction=structtype'at='aType_equal.Id.tletnothing=nothing_type_idletbothab=Type_equal.Id.create~name:(sprintf"(%s * %s)"(Type_equal.Id.namea)(Type_equal.Id.nameb))(Either.sexp_of_t(Type_equal.Id.to_sexpa)(Type_equal.Id.to_sexpb));;letof_module(typet)(moduleM:Actionwithtypet=t)~name=Type_equal.Id.create~name:(sprintf"%s-action"name)M.sexp_of_t;;letmap(typekcmp)(moduleM:Comparatorwithtypet=kandtypecomparator_witness=cmp)action=letsexp_of_action=Type_equal.Id.to_sexpactioninType_equal.Id.create~name:(sprintf"map to %s"(Type_equal.Id.nameaction))[%sexp_of:M.t*action];;end