1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Statement} *)moduleOptionSet=Set.Make(structletcomparexy=Pervasives.comparexytypet=intoptionend)moduleIdMap=ID.MapmoduleUS=Unif_substmoduleTST=TypedSTermletsection=Util.Section.make"stm"(** A datatype declaration *)type'tydata={data_id:ID.t;(** Name of the type *)data_args:'tyVar.tlist;(** type parameters *)data_ty:'ty;(** type of Id, that is, [type -> type -> ... -> type] *)data_cstors:(ID.t*'ty*('ty*(ID.t*'ty))list)list;(** Each constructor is [id, ty, args].
[ty] must be of the form [ty1 -> ty2 -> ... -> id args].
[args] has the form [(ty1, p1), (ty2,p2), …] where each [p]
is a projector. *)}typeattr=|A_AC|A_infixofstring|A_prefixofstring|A_sos(** set of support *)typeattrs=attrlisttype'tyskolem=ID.t*'ty(** polarity for rewrite rules *)typepolarity=[`Equiv|`Imply]type('f,'t,'ty)def_rule=|Def_termof{vars:'tyVar.tlist;id:ID.t;ty:'ty;args:'tlist;rhs:'t;as_form:'f;}(** [forall vars, id args = rhs] *)|Def_formof{vars:'tyVar.tlist;lhs:'tSLiteral.t;rhs:'flist;polarity:polarity;as_form:'flist;}(** [forall vars, lhs op bigand rhs] where [op] depends on
[polarity] (in [{=>, <=>, <=}]) *)type('f,'t,'ty)def={def_id:ID.t;def_ty:'ty;(* def_ty = def_vars -> def_ty_ret *)def_rules:('f,'t,'ty)def_rulelist;def_rewrite:bool;(* rewrite rule or mere assertion? *)}type('f,'t,'ty)view=|TyDeclofID.t*'ty(** id: ty *)|Dataof'tydatalist|Defof('f,'t,'ty)deflist|Rewriteof('f,'t,'ty)def_rule|Assertof'f(** assert form *)|Lemmaof'flist(** lemma to prove and use, using Avatar cut *)|Goalof'f(** goal to prove *)|NegatedGoalof'tyskolemlist*'flist(** goal after negation, with skolems *)typelit=Term.tSLiteral.ttypeformula=TypedSTerm.ttypeinput_def=(TypedSTerm.t,TypedSTerm.t,TypedSTerm.t)deftypeclause=litlisttype('f,'t,'ty)t={id:int;view:('f,'t,'ty)view;attrs:attrs;proof:proof;mutablename:stringoption;}andproof=Proof.Step.tandinput_t=(TypedSTerm.t,TypedSTerm.t,TypedSTerm.t)tandclause_t=(clause,Term.t,Type.t)tletcompareab=CCInt.comparea.idb.idletviewt=t.viewletattrst=t.attrsletproof_stept=t.proofletmk_dataid~argstycstors={data_id=id;data_args=args;data_ty=ty;data_cstors=cstors;}letmk_def?(rewrite=false)idtyrules={def_id=id;def_ty=ty;def_rules=rules;def_rewrite=rewrite;}letid_n_=ref0letmk_?(attrs=[])~proofview:(_,_,_)t={id=CCRef.incr_then_getid_n_;proof;view;attrs;name=None}letty_decl?attrs~proofidty=mk_?attrs~proof(TyDecl(id,ty))letdef?attrs~proofl=mk_?attrs~proof(Defl)letrewrite?attrs~proofd=mk_?attrs~proof(Rewrited)letdata?attrs~proofl=mk_?attrs~proof(Datal)letassert_?attrs~proofc=mk_?attrs~proof(Assertc)letlemma?attrs~proofl=mk_?attrs~proof(Lemmal)letgoal?attrs~proofc=mk_?attrs~proof(Goalc)letneg_goal?attrs~proof~skolemsl=mk_?attrs~proof(NegatedGoal(skolems,l))letmap_data~ty:ftyd={dwithdata_args=List.map(Var.update_ty~f:fty)d.data_args;data_ty=ftyd.data_ty;data_cstors=List.map(fun(id,ty,args)->id,ftyty,List.map(fun(ty,(p_id,p_ty))->ftyty,(p_id,ftyp_ty))args)d.data_cstors;}letmap_def_rule~form:fform~term:fterm~ty:ftyd=matchdwith|Def_term{vars;id;ty;args;rhs;as_form}->letvars=List.map(Var.update_ty~f:fty)varsinDef_term{vars;id;ty=ftyty;args=List.mapftermargs;rhs=ftermrhs;as_form=fformas_form}|Def_form{vars;lhs;rhs;polarity;as_form}->letvars=List.map(Var.update_ty~f:fty)varsinDef_form{vars;lhs=SLiteral.map~f:ftermlhs;rhs=List.mapfformrhs;polarity;as_form=List.mapfformas_form}letmap_def~form:fform~term:fterm~ty:ftyd={dwithdef_ty=ftyd.def_ty;def_rules=List.map(map_def_rule~form:fform~term:fterm~ty:fty)d.def_rules;}letmap~form~term~tyst=letmap_view~form~term~ty:fty=function|Defl->letl=List.map(map_def~form~term~ty)linDefl|Rewrited->letd=map_def_rule~form~term~tydinRewrited|Datal->letl=List.map(map_data~ty:fty)linDatal|Lemmal->Lemma(List.mapforml)|Goalf->Goal(formf)|NegatedGoal(sk,l)->letsk=List.map(fun(i,ty)->i,ftyty)skinNegatedGoal(sk,List.mapforml)|Assertf->Assert(formf)|TyDecl(id,ty)->TyDecl(id,ftyty)in{stwithview=map_view~form~term~tyst.view;}(** {2 Defined Constants} *)typedefinition=Rewrite.rule_setletas_defined_cstid=ID.payload_findid~f:(function|Rewrite.Payload_defined_cstc->Some(Rewrite.Defined_cst.levelc,Rewrite.Defined_cst.rulesc)|_->None)letas_defined_cst_levelid=CCOpt.mapfst@@as_defined_cstidletis_defined_cstid=as_defined_cstid<>Noneletdeclare_defined_cstid~level(rules:definition):unit=let_=Rewrite.Defined_cst.declare~levelidrulesin()letconv_rule~proof(r:_def_rule):Rewrite.rule=matchrwith|Def_term{id;ty;args;rhs;_}->letrhs=Lambda.snfrhsinRewrite.T_rule(Rewrite.Term.Rule.makeidtyargsrhs~proof)|Def_form{lhs;rhs;_}->(* returns either a term or a lit rule (depending on whether RHS is atomic) *)letlhs=Literal.Conv.of_formlhsinletrhs=List.map(List.mapLiteral.Conv.of_form)rhsinRewrite.Rule.make_litlhsrhs~proofletconv_rule_i~proof(r:_def_rule)=matchrwith|Def_term{id;ty;args;rhs;_}->letctx=Type.Conv.create()inletty=Type.Conv.of_simple_term_exnctxtyinletargs=List.map(Term.Conv.of_simple_term_exnctx)argsinletrhs=Lambda.snf(Term.Conv.of_simple_term_exnctxrhs)inletrhs_rewritten,rw_rules=Rewrite.Term.normalize_termrhsinletproof_parents=Proof.Parent.fromproof::Rewrite.Rule.set_as_proof_parentsrw_rulesinletform=Proof.Result.to_form(Proof.S.resultproof)inletproof=Proof.S.mk_f(Proof.Step.simp~rule:(Proof.Rule.mk"simplify_rw_rule")proof_parents)forminletrule=Rewrite.Term.Rule.makeidtyargs(rhs)~proofinRewrite.T_rulerule|Def_form{lhs;rhs;_}->letctx=Type.Conv.create()inmatchlhswith|SLiteral.Atom(lhs,true)->letlhs=Term.Conv.of_simple_term_exnctxlhsinlethd,args=Term.as_applhsinletty=Term.tyhdinifList.lengthrhs=1then(letrhs=Term.Conv.of_simple_term_exnctx(List.hdrhs)inletrule=Rewrite.Term.Rule.make(Term.as_const_exnhd)tyargsrhs~proofinRewrite.T_rulerule)elseinvalid_arg"rhs must be a singleton list."|_->invalid_arg"only positive polarity is supported."(* convert rules *)letconv_rules(l:_def_rulelist)proof:definition=assert(l<>[]);List.map(conv_rule~proof)l|>Rewrite.Rule_set.of_listletterms_of_rule(d:_def_rule):_Iter.t=matchdwith|Def_term{args;rhs;_}->Iter.of_list(rhs::args)|Def_form{lhs;rhs;_}->Iter.conslhs(Iter.of_listrhs|>Iter.flat_mapIter.of_list)|>Iter.flat_mapSLiteral.to_iterletlevel_of_rule(d:_def_rule):int=terms_of_ruled|>Iter.flat_mapTerm.Seq.symbols|>Iter.filter_mapas_defined_cst_level|>Iter.max|>CCOpt.get_or~default:0(** {2 Inductive Types} *)(* add rewrite rules for functions associated
with this datatype (projectors, etc.) *)letdecl_data_functionsityproof:unit=letone_cstor=List.lengthity.Ind_ty.ty_constructors=1inList.iter(funcstor->(* projectors *)List.iter(fun(_,proj)->Rewrite.Defined_cst.declare_proj~proofproj)cstor.Ind_ty.cstor_args;(* if there is exactly one cstor, add [cstor (proj_1 x)…(proj_n x) --> x] *)ifone_cstorthen(Rewrite.Defined_cst.declare_cstor~proofcstor);)ity.Ind_ty.ty_constructorsletget_formulas_from_defsst=letget_from_rulerule=matchrulewith|Def_term{vars;id;ty;args;rhs;as_form}->ignore(vars,id,ty,args,rhs);[as_form]|Def_form{vars;lhs;rhs;polarity;as_form}->ignore(vars,lhs,polarity,rhs);as_forminmatchviewstwith|Defdefs->CCList.flat_map(fund->CCList.flat_mapget_from_ruled.def_rules)defs|Rewritedef_rule->get_from_ruledef_rule|_->[](** {2 Iterators} *)moduleSeq=structletmk_termt=`Termtletmk_formf=`Formfletseq_of_rule(d:_def_rule):_Iter.t=funk->matchdwith|Def_term{vars;ty;args;rhs;_}->k(`Tyty);List.iter(funv->k(`Ty(Var.tyv)))vars;List.iter(funt->k(`Termt))(rhs::args);|Def_form{vars;lhs;rhs;_}->List.iter(funv->k(`Ty(Var.tyv)))vars;SLiteral.to_iterlhs|>Iter.mapmk_term|>Iter.iterk;Iter.of_listrhs|>Iter.mapmk_form|>Iter.iterkletto_iterstk=letdeclidty=k(`IDid);k(`Tyty)inbeginmatchviewstwith|TyDecl(id,ty)->declidty;|Defl->List.iter(fun{def_id;def_ty;def_rules;_}->decldef_iddef_ty;Iter.of_listdef_rules|>Iter.flat_mapseq_of_rule|>Iter.iterk)l|Rewrited->beginmatchdwith|Def_term{ty;args;rhs;_}->k(`Tyty);List.iter(funt->k(`Termt))args;k(`Termrhs)|Def_form{lhs;rhs;_}->SLiteral.iter~f:(funt->k(`Termt))lhs;List.iter(funf->k(`Formf))rhsend|Datal->letdecl_cstor(id,ty,args)=declidty;List.iter(fun(_,(p_id,p_ty))->declp_idp_ty)args;inList.iter(fund->decld.data_idd.data_ty;List.iterdecl_cstord.data_cstors)l|Lemmal->List.iter(funf->k(`Formf))l|Assertf|Goalf->k(`Formf)|NegatedGoal(_,l)->List.iter(funf->k(`Formf))lendletty_declsstk=matchviewstwith|Defl->List.iter(fun{def_id;def_ty;_}->k(def_id,def_ty))l|TyDecl(id,ty)->k(id,ty)|Datal->letdecl_cstor(id,ty,args)=k(id,ty);List.iter(fun(_,p)->kp)args;inList.iter(fund->k(d.data_id,d.data_ty);List.iterdecl_cstord.data_cstors)l|Rewrite_|Lemma_|Goal_|NegatedGoal_|Assert_->()letformsst=letforms_def=function|Def_term{as_form;_}->[as_form]|Def_form{as_form;_}->as_forminbeginmatchviewstwith|Rewrited->Iter.of_list(forms_defd)|Defl->Iter.of_listl|>Iter.flat_map_l(fund->d.def_rules)|>Iter.flat_map_lforms_def|_->to_iterst|>Iter.filter_map(function`Formf->Somef|_->None)endletlitsst=formsst|>Iter.flat_mapIter.of_listlettermsst=to_iterst|>Iter.flat_map(function|`Formf->Iter.of_listf|>Iter.flat_mapSLiteral.to_iter|`Termt->Iter.returnt|_->Iter.empty)letsymbolsst=to_iterst|>Iter.flat_map(function|`IDid->Iter.returnid|`Formf->Iter.of_listf|>Iter.flat_mapSLiteral.to_iter|>Iter.flat_mapTerm.Seq.symbols|`Termt->Term.Seq.symbolst|`Tyty->Type.Seq.symbolsty)endletsignature?(init=Signature.empty)?(conj_syms=Iter.empty)seq=letsigntr=seq|>Iter.flat_mapSeq.ty_decls|>Iter.fold(funsigma(id,ty)->Signature.declaresigmaidty)initinconj_syms|>Iter.fold(funsigmasymb->Signature.set_sym_in_conjsymbsigma)signtrletconv_attrs=letmoduleA=UntypedASTinCCList.filter_map(function|A.A_app(("ac"|"AC"),[])->SomeA_AC|A.A_app(("sos"|"SOS"),[])->SomeA_sos|A.A_app("infix",[A.A_quoteds])->Some(A_infixs)|A.A_app("prefix",[A.A_quoteds])->Some(A_prefixs)|_->None)letattr_to_ua:attr->UntypedAST.attr=letopenUntypedAST.Ainfunction|A_AC->str"AC"|A_sos->str"sos"|A_prefixs->app"prefix"[quoteds]|A_infixs->app"infix"[quoteds](** {2 IO} *)letfpf=Format.fprintfletpp_attrouta=UntypedAST.pp_attrout(attr_to_uaa)letpp_attrsoutl=UntypedAST.pp_attrsout(List.mapattr_to_ual)letpp_typedvarpptyoutv=fpfout"(@[%a:%a@])"Var.ppvppty(Var.tyv)letpp_typedvar_lppty=Util.pp_list~sep:" "(pp_typedvarppty)letpp_def_ruleppfpptpptyoutd=letpp_arg=CCFormat.within"("")"pptinletpp_argsout=function|[]->()|l->fpfout"@ %a"(Util.pp_list~sep:" "pp_arg)landpp_varsout=function|[]->()|l->fpfout"forall %a.@ "(pp_typedvar_lppty)linbeginmatchdwith|Def_term{vars;id;args;rhs;_}->fpfout"@[<2>%a@[<2>%a%a@] =@ %a@]"pp_varsvarsID.ppidpp_argsargspptrhs|Def_form{vars;lhs;rhs;polarity=pol;_}->letop=matchpolwith`Equiv->"<=>"|`Imply->"=>"infpfout"@[<2>%a%a %s@ (@[<hv>%a@])@]"pp_varsvars(SLiteral.ppppt)lhsop(Util.pp_list~sep:" && "ppf)rhsendletpp_defppfpptpptyoutd=fpfout"@[<2>@[%a : %a@]@ where@ @[<hv>%a@]@]"ID.ppd.def_idpptyd.def_ty(Util.pp_list~sep:";"(pp_def_ruleppfpptppty))d.def_rulesletpp_input_def=pp_defTypedSTerm.ppTypedSTerm.ppTypedSTerm.ppletattrs_uast=letsrc_attrs=Proof.Step.to_attrsst.proofinList.rev_appendsrc_attrs(List.mapattr_to_uast.attrs)letppppfpptpptyoutst=letattrs=attrs_uastinletpp_attrs=UntypedAST.pp_attrsinbeginmatchst.viewwith|TyDecl(id,ty)->fpfout"@[<2>val%a %a :@ @[%a@]@]."pp_attrsattrsID.ppidpptyty|Defl->fpfout"@[<2>def%a@ %a@]."pp_attrsattrs(Util.pp_list~sep:" and "(pp_defppfpptppty))l|Rewrited->beginmatchdwith|Def_term{id;args;rhs;_}->fpfout"@[<2>rewrite%a@ @[%a %a@]@ = @[%a@]@]."pp_attrsattrsID.ppid(Util.pp_list~sep:" "ppt)argspptrhs|Def_form{lhs;rhs;polarity=pol;_}->letop=matchpolwith`Equiv->"<=>"|`Imply->"=>"infpfout"@[<2>rewrite%a@ @[%a@]@ %s @[%a@]@]."pp_attrsattrs(SLiteral.ppppt)lhsop(Util.pp_list~sep:" && "ppf)rhsend|Datal->letpp_cstorout(id,ty,_)=fpfout"@[<2>| %a :@ @[%a@]@]"ID.ppidpptytyinletpp_dataoutd=fpfout"@[<hv2>@[%a : %a@] :=@ %a@]"ID.ppd.data_idpptyd.data_ty(Util.pp_list~sep:""pp_cstor)d.data_cstorsinfpfout"@[<hv2>data%a@ %a@]."pp_attrsattrs(Util.pp_list~sep:" and "pp_data)l|Assertf->fpfout"@[<2>assert%a@ @[%a@]@]."pp_attrsattrsppff|Lemmal->fpfout"@[<2>lemma%a@ @[%a@]@]."pp_attrsattrs(Util.pp_list~sep:" && "ppf)l|Goalf->fpfout"@[<2>goal%a@ @[%a@]@]."pp_attrsattrsppff|NegatedGoal(sk,l)->letpp_skout(id,ty)=fpfout"(%a:%a)"ID.ppidpptytyinfpfout"@[<hv2>negated_goal%a@ @[<hv>%a@]@ # skolems: [@[<hv>%a@]]@]."pp_attrsattrs(Util.pp_list~sep:", "(CCFormat.hovboxppf))l(Util.pp_listpp_sk)skendletto_stringppfpptppty=CCFormat.to_string(ppppfpptppty)letpp_clause=pp(Util.pp_list~sep:" ∨ "(SLiteral.ppTerm.pp))Term.ppType.ppletpp_input=ppTypedSTerm.ppTypedSTerm.ppTypedSTerm.ppletname_gen_=letn=ref0infun()->Printf.sprintf"zf_stmt_%d"(CCRef.get_then_incrn)letname(st:(_,_,_)t):string=letfrom_src=matchProof.Step.srcst.proofwith|Some{Proof.src_view=Proof.From_file(f,_);_}->Proof.Src.namef|_->Noneinbeginmatchst.name,from_srcwith|Somes,_->s|None,Somes->s|None,None->lets=name_gen_()inst.name<-Somes;sendmoduleAsKey=structtypet=input_tletequalab=compareab=0lethasha=a.idletcompare=compareendmoduleInpStmSet=Set.Make(AsKey)moduleRW=RewritemoduleDC=RW.Defined_cstletsine_axiom_selector?(ignore_k_most_common_symbols=None)?(take_conj_defs=true)?(take_only_defs=false)?(trim_implications=false)?(depth_start=1)?(depth_end=3)?(tolerance=2.0)formulas=letformulas=Iter.to_listformulasinleteliminate_long_implications~is_goalf=let_elim_long_impsf=letrecauxf=matchTST.Form.viewfwith|TST.Form.Imply(lhs,rhs)->letis_formt=matchTST.Form.viewtwith|Atom_->false|_->trueinifnot(is_formlhs)then(letpremises,concl=auxrhsinlhs::premises,concl)else([],f)|_->([],f)inletpremises,concl=auxfinifCCList.lengthpremises>5then(Util.debugf~section2"trimmed @[%a@] into @[%a@]@."(funk->kTST.ppfTST.ppconcl);concl)elsefinifnotis_goalthenfelse_elim_long_impsfinletsymset_of_ax~trim_implications?(is_goal=false)ax=Seq.formsax|>Iter.map(iftrim_implicationstheneliminate_long_implications~is_goalelseCCFun.id)|>Iter.flat_mapTST.Seq.symbols|>ID.Set.of_iterinletsymset_of_axs~trim_implications?(is_goal=false)axs=List.fold_left(funaccc->ID.Set.unionacc(symset_of_ax~trim_implications~is_goalc))ID.Set.emptyaxsinlettriggered_by_syms~triggerssyms=ID.Set.fold(funidacc->letaxs=ID.Tbl.get_ortriggersid~default:InpStmSet.emptyin(InpStmSet.elementsaxs)@acc)syms[]inletcount_occ~tblax=symset_of_ax~trim_implications:falseax|>ID.Set.iter(funk->ID.Tbl.updatetbl~f:(fun_vopt->matchvoptwith|Somev->Some(v+1)|None->Some1)~k)inletcreate_trigger_map~trim_implications~tblaxioms=letmap=ID.Tbl.create(Iter.length@@ID.Tbl.keystbl)inCCList.iter(funax->letsymset=ID.Set.to_iter@@symset_of_ax~trim_implications:falseaxinletmin_occ=ref(max_int)inIter.iter(funid->letcnt=ID.Tbl.get_ortblid~default:max_intinifcnt<!min_occ&&(nottrim_implications||cnt!=1)thenmin_occ:=cnt;)symset;(* now we calculate trigger map based on the min_occ *)letthreshold=int_of_float@@tolerance*.(float_of_int!min_occ)inIter.iter(funid->letcnt=ID.Tbl.get_ortblid~default:max_intinifcnt<=thresholdthen(ID.Tbl.update~f:(funkvopt->matchvoptwith|Someax_set->Some(InpStmSet.addaxax_set)|None->Some(InpStmSet.singletonax))~k:idmap))symset)axioms;mapinletids_to_defs_computedefs=letrecauxmapd=letupdate_mapmapidstm=letprev=ID.Map.get_or~default:InpStmSet.emptyidmapinID.Map.addid(InpStmSet.addstmprev)mapinmatchviewdwith|Defl->List.fold_left(funmap{def_id;_}->update_mapmapdef_idd)mapl;|Rewriter->beginmatchrwith|Def_term{id;_}->update_mapmapidd|Def_form{lhs;rhs;polarity=pol;_}->beginmatchlhswith|Atom(t,_)->beginmatchTST.headtwith|Somehd->update_mapmaphdd|None->mapend|_->mapendend|_->mapinList.fold_left(funmapd->auxmapd)ID.Map.emptydefsinletcategorize_formulasforms=letrecdo_categorize(defs,helpers,axioms,conjs)f=matchviewfwith|Def_|Rewrite_->(f::defs,helpers,axioms,conjs)|Assert_->(defs,helpers,f::axioms,conjs)|Goal_|NegatedGoal_->(defs,helpers,axioms,f::conjs)|_->(defs,f::helpers,axioms,conjs)inletrecauxacc=function|[]->acc|x::xs->aux(do_categorizeaccx)xsinaux([],[],[],[])formsinletdefs,helper_axioms,axioms,goals=categorize_formulasformulasiniftake_only_defsthen(letres=helper_axioms@defs@goalsinUtil.debugf~section2"taken %d/%d axioms:@[%a@]@."(funk->k(List.lengthres)(List.lengthaxioms)(CCList.ppCCString.pp)(List.mapnameres));Iter.of_listres)else(letaxioms=defs@axiomsinletids_to_defs=ids_to_defs_computedefsinlettbl=ID.Tbl.create1024inList.iter(count_occ~tbl)axioms;letmost_commmon_syms=matchignore_k_most_common_symbolswith|None->ID.Set.empty|Somek->ID.Tbl.to_listtbl|>CCList.sort(fun(s1,occ1)(s2,occ2)->CCInt.compareocc2occ1)|>CCList.takek|>CCList.mapfst|>ID.Set.of_listinUtil.debugf~section1"most common symbols are: @[%a@]@."(funk->k(ID.Set.ppID.pp)most_commmon_syms);(* now tbl contains occurrences of all symbols *)lettriggers=create_trigger_map~trim_implications~tbl(axioms)inletsyms_in_conj=symset_of_axs~trim_implications~is_goal:truegoalsinletconj_syms=ID.Set.diffsyms_in_conjmost_commmon_symsinUtil.debugf~section2"conj_syms:@[%a@]"(funk->k(ID.Set.ppID.pp)conj_syms);lettriggered_1=triggered_by_syms~triggersconj_symsinletrectake_axskprocessed_symsk_triggered_axs=ifk>=depth_endthen[]else(lettaken=ifk>=depth_startthenk_triggered_axselse[]inletnew_syms=symset_of_axs~trim_implications:falsek_triggered_axsinletunprocessed=ID.Set.diffnew_symsprocessed_symsinletk_p_1_triggered_ax=triggered_by_syms~triggersunprocessedintaken@(take_axs(k+1)(ID.Set.unionprocessed_symsunprocessed)k_p_1_triggered_ax))inletconj_defined_syms=iftake_conj_defsthen(ID.Set.fold(funs_idconj_defs->InpStmSet.unionconj_defs(ID.Map.get_or~default:InpStmSet.emptys_idids_to_defs))conj_syms(InpStmSet.empty))elseInpStmSet.emptyinlettaken_axs=CCList.sort_uniq~cmp:compare((InpStmSet.elementsconj_defined_syms)@(take_axs1conj_symstriggered_1))inUtil.debugf~section2"taken %d/%d axioms:@ @[%a@]@."(funk->k(List.lengthtaken_axs)(List.lengthaxioms)(CCList.ppCCString.pp)(List.mapnametaken_axs));Util.debugf~section2"take_conj_defs:%b@."(funk->ktake_conj_defs);letres=helper_axioms@taken_axs@goalsinIter.of_list(res))moduleZF=structmoduleUA=UntypedAST.Aletppppfpptpptyoutst=letpp_varoutv=Format.fprintfout"(%a:%a)"Var.ppvppty(Var.tyv)inletpp_varsout=function|[]->()|vars->Format.fprintfout"forall %a.@ "(Util.pp_list~sep:" "pp_var)varsinletattrs=attrs_uastinletpp_attrs=UntypedAST.pp_attrs_zfinmatchst.viewwith|TyDecl(id,ty)->fpfout"@[<2>val%a %a :@ @[%a@]@]."pp_attrsattrsID.pp_zfidpptyty|Defl->fpfout"@[<2>def%a@ %a@]."pp_attrsattrs(Util.pp_list~sep:" and "(pp_defppfpptppty))l|Rewrited->beginmatchdwith|Def_term{vars;id;args;rhs;_}->fpfout"@[<2>rewrite%a@ @[<2>%a@[%a %a@]@ = @[%a@]@]@]."pp_attrsattrspp_varsvarsID.pp_zfid(Util.pp_list~sep:" "ppt)argspptrhs|Def_form{vars;lhs;rhs;polarity=pol;_}->letop=matchpolwith`Equiv->"<=>"|`Imply->"=>"infpfout"@[<2>rewrite%a@ @[<2>%a@[%a@]@ %s @[%a@]@]@]."pp_attrsattrspp_varsvars(SLiteral.ZF.ppppt)lhsop(Util.pp_list~sep:" && "ppf)rhsend|Datal->letpp_cstorout(id,ty,_)=fpfout"@[<2>| %a :@ @[%a@]@]"ID.pp_zfidpptytyinletpp_dataoutd=fpfout"@[<hv2>@[%a : %a@] :=@ %a@]"ID.pp_zfd.data_idpptyd.data_ty(Util.pp_list~sep:""pp_cstor)d.data_cstorsinfpfout"@[<hv2>data%a@ %a@]."pp_attrsattrs(Util.pp_list~sep:" and "pp_data)l|Assertf->fpfout"@[<2>assert%a@ @[%a@]@]."pp_attrsattrsppff|Lemmal->fpfout"@[<2>lemma%a@ @[%a@]@]."pp_attrsattrs(Util.pp_list~sep:" && "ppf)l|Goalf->fpfout"@[<2>goal%a@ @[%a@]@]."pp_attrsattrsppff|NegatedGoal(_,l)->fpfout"@[<hv2>goal%a@ ~(@[<hv>%a@])@]."pp_attrsattrs(Util.pp_list~sep:", "(CCFormat.hovboxppf))lletto_stringppfpptppty=CCFormat.to_string(ppppfpptppty)endmoduleTPTP=structletnamespace=Proof.S.Tbl.create8letppppfpptpptyoutst=letname=namestinletpp_declout(id,ty)=ifID.is_distinct_objectidthenfpfout"%% (omitted type declaration for distinct object %a.)"ID.pp_tstpidelsefpfout"thf(@[%s, type,@ %a :@ @[%a@]@])."nameID.pp_tstpidpptytyandpp_quant_varsout=function|[]->()|l->letpp_typedvaroutv=fpfout"%a:%a"Var.ppvppty(Var.tyv)infpfout"![@[%a@]]:@ "(Util.pp_listpp_typedvar)linletpp_name=Util.pp_str_tstpin(* print a single definition as an axiom *)letpp_def_axiomoutd=letpp_argsout=function|[]->()|l->fpfout"(@[%a@])"(Util.pp_list~sep:","ppt)linletpp_ruleout=function|Def_term{vars;id;args;rhs;_}->fpfout"%a (@[%a%a@] =@ %a)"pp_quant_varsvarsID.pp_tstpidpp_argsargspptrhs|Def_form{vars;lhs;rhs;polarity=pol;_}->letop=matchpolwith`Equiv->"="|`Imply->"=>"infpfout"%a(@[%a@] %s@ (@[<hv>%a@]))"pp_quant_varsvars(SLiteral.ppppt)lhsop(Util.pp_list~sep:" & "ppf)rhsinletpp_top_ruleoutr=fpfout"@[<2>thf(%s, axiom,@ (%a))@]."namepp_rulerinUtil.pp_list~sep:""pp_top_ruleoutd.def_rulesinmatchst.viewwith|TyDecl(id,ty)->pp_declout(id,ty)|Assertf->letrole="axiom"infpfout"@[<2>thf(%a, %s,@ (@[%a@]))@]."pp_namenameroleppff|Lemmal->letrole="lemma"infpfout"@[<2>thf(%a, %s,@ (@[%a@]))@]."pp_namenamerole(Util.pp_list~sep:" & "ppf)l|Goalf->letrole="conjecture"infpfout"@[<2>thf(%a, %s,@ (@[%a@]))@]."pp_namenameroleppff|NegatedGoal(_,l)->letrole="negated_conjecture"inletparents=List.map(funp->`Name(Proof.S.name~namespace@@Proof.Parent.proofp))(Proof.Step.parents@@st.proof)inList.iter(funf->fpfout"@[<2>thf(%a, %s,@ (@[%a@]),@ @[%a@])@]."pp_namenameroleppffProof.Kind.pp_tstp(Proof.Step.kind@@st.proof,parents))l|Defl->Format.fprintfout"@[<v>";(* declare *)List.iter(fun{def_id;def_ty;_}->Format.fprintfout"%a@,"pp_decl(def_id,def_ty))l;(* define *)Util.pp_list~sep:""pp_def_axiomoutl;Format.fprintfout"@]";|Rewrited->beginmatchdwith|Def_term{id;args;rhs;_}->fpfout"@[<2>thf(%a, axiom,((@ %a %s %a) =@ (@[%a@])))@]."pp_namenameID.pp_tstpid(ifCCList.is_emptyargsthen""else"@")(Util.pp_list~sep:"@ "ppt)argspptrhs|Def_form{lhs;rhs;polarity=pol;_}->letop=matchpolwith`Equiv->"="|`Imply->"=>"infpfout"@[<2>thf(%a, axiom,@ %a %s@ (@[%a@]))@]."pp_namename(SLiteral.TPTP.ppppt)lhsop(Util.pp_list~sep:" & "ppf)rhsend|Data_->failwith"cannot print `data` to TPTP"letto_stringppfpptppty=CCFormat.to_string(ppppfpptppty)endletpp_inpp_fpp_tpp_ty=function|Output_format.O_zf->ZF.pppp_fpp_tpp_ty|Output_format.O_tptp->TPTP.pppp_fpp_tpp_ty|Output_format.O_normal->pppp_fpp_tpp_ty|Output_format.O_none->CCFormat.silentletpp_clause_ino=letpp_t=Term.pp_inoinletpp_ty=Type.pp_inoinpp_in(Util.pp_list~sep:" | "(SLiteral.pp_inopp_t))pp_tpp_tyoletpp_input_ino=letpp_t=TypedSTerm.pp_inoinpp_inpp_tpp_tpp_to(** {2 Proofs} *)exceptionE_iofinput_texceptionE_cofclause_tletres_tc_i:input_tProof.result_tc=Proof.Result.make_tc~of_exn:(functionE_ic->Somec|_->None)~to_exn:(funi->E_ii)~compare:compare~pp_in:pp_input_in~is_stmt:true~name~to_form:(fun~ctx:_st->Seq.formsst|>Iter.to_list|>TypedSTerm.Form.and_)()letres_tc_c:clause_tProof.result_tc=Proof.Result.make_tc~of_exn:(functionE_cc->Somec|_->None)~to_exn:(funi->E_ci)~compare:compare~pp_in:pp_clause_in~is_stmt:true~name~to_form:(fun~ctxst->letmoduleF=TypedSTerm.Forminletconv_c(c:clause):formula=c|>List.rev_map(funlit->SLiteral.maplit~f:(Term.Conv.to_simple_termctx)|>SLiteral.to_form)|>F.or_|>F.close_forallinSeq.formsst|>Iter.mapconv_c|>Iter.to_list|>F.and_)()letas_proof_it=Proof.S.mkt.proof(Proof.Result.makeres_tc_it)letas_proof_ct=Proof.S.mkt.proof(Proof.Result.makeres_tc_ct)(** {2 Scanning} *)letdefine_rw_rule~proofr=ignore(proof);beginmatchrwith|Rewrite.T_ruler->letid=Rewrite.Term.Rule.head_idrinRewrite.Defined_cst.declare_or_addid(Rewrite.T_ruler)|Rewrite.L_rulelr->beginmatchRewrite.Lit.Rule.head_idlrwith|Someid->Rewrite.Defined_cst.declare_or_addidr|None->assert(Rewrite.Lit.Rule.is_equationallr);Rewrite.Defined_cst.add_eq_rulelrendendletscan_stmt_for_defined_cst(st:(clause,Term.t,Type.t)t):unit=matchviewstwith|Def[]->assertfalse|Defl->(* define all IDs at the same level (the max of those computed) *)letproof=as_proof_cstinletids_and_levels=l|>List.filter(fun{def_ty=ty;def_rewrite=b;_}->(* definitions require [b=true] or the LHS be a constant *)let_,args,_=Type.open_poly_funtyinb||CCList.is_emptyargs)|>List.map(fun{def_id;def_rules;_}->letlev=Iter.of_listdef_rules|>Iter.maplevel_of_rule|>Iter.max|>CCOpt.get_or~default:0anddef=conv_rulesdef_rulesproofindef_id,lev,def)inletlevel=Iter.of_listids_and_levels|>Iter.map(fun(_,l,_)->l)|>Iter.max|>CCOpt.map_or~default:0succinList.iter(fun(id,_,def)->let_=Rewrite.Defined_cst.declare~leveliddefin())ids_and_levels|Rewrited->letproof=as_proof_cstindefine_rw_rule~proof(conv_rule~proofd)|_->()letscan_tst_rewrite(st:(TypedSTerm.t,TypedSTerm.t,TypedSTerm.t)t):unit=matchviewstwith|Rewrited->letproof=as_proof_istindefine_rw_rule~proof(conv_rule_i~proofd)|_->()letscan_stmt_for_ind_tyst=matchviewstwith|Datal->letproof=as_proof_cstinList.iter(fund->letty_vars=List.mapi(funiv->HVar.make~ty:(Var.tyv)i)d.data_argsandcstors=List.map(fun(c,ty,args)->Ind_ty.mk_constructorctyargs)d.data_cstorsinletity=Ind_ty.declare_tyd.data_id~ty_varscstors~proofindecl_data_functionsityproof;())l|_->()letscan_simple_stmt_for_ind_tyst=matchviewstwith|Datal->letconv=Type.Conv.create()inletconv_ty=Type.Conv.of_simple_term_exnconvinletproof=as_proof_istinList.iter(fund->letty_vars=List.mapi(funiv->HVar.make~ty:(Var.tyv|>conv_ty)i)d.data_argsandcstors=List.map(fun(c,ty,args)->letargs=List.map(fun(ty,(p_id,p_ty))->conv_tyty,(p_id,conv_typ_ty))argsinInd_ty.mk_constructorc(conv_tyty)args)d.data_cstorsinletity=Ind_ty.declare_tyd.data_id~ty_varscstors~proofindecl_data_functionsityproof;())l|_->()(** TODO: Ask Simon how to hide this in the fun *)letdef_sym=refIdMap.empty;;letget_rw_rule?weight_incr:(w_i=1000000)c=letdistinct_free_varsl=l|>List.map(funt->Term.as_vart|>(funv->matchvwith|Somex->Some(HVar.idx)|None->None))|>OptionSet.of_list|>(funset->not(OptionSet.memNoneset)&&OptionSet.cardinalset=List.lengthl)inletmake_rwsymvarsrhs=letty_vars=List.filter(funv->Type.is_tType(Term.tyv))varsinletvars=List.filter(funv->not(Type.is_tType(Term.tyv)))varsinletn_new=List.lengthvarsinletvar_db_map=CCList.foldi(funacciv->Term.Map.addv(n_new-i-1)acc)Term.Map.emptyvarsinletvars_to_db=Term.DB.map_vars_shiftvar_db_maprhsinletabs_rhs=(Term.fun_l((CCList.mapTerm.tyvars))vars_to_db)inassert(Term.DB.is_closedabs_rhs);letr=Rewrite.Term.Rule.make~proof:(as_proof_cc)sym(Type.close_forall(Term.tyabs_rhs))ty_varsabs_rhsinletrule=Rewrite.T_rulerinUtil.debugf5"Defined %a with %a"(funk->kID.ppsymRewrite.Term.Rule.ppr);ruleinletbuild_from_headsymvarsrhs=letrhs=Lambda.eta_reduce@@Lambda.snf(fst(Rewrite.Term.normalize_termrhs))inletvars_lhs=Term.VarSet.of_iter(Iter.fold(funaccv->Iter.appendacc(Term.Seq.varsv))Iter.empty(Iter.of_listvars))inifnot(Term.symbolsrhs|>ID.Set.memsym)&&Term.VarSet.cardinal(Term.VarSet.diff(Term.varsrhs)vars_lhs)=0then(* Here I skipped proof object creation *)letres_rw=Some(sym,make_rwsymvarsrhs)in(def_sym:=IdMap.addsym(rhs,res_rw)!def_sym;res_rw)elseNoneinletconv_terms_rwt1t2=letreduced=Lambda.eta_reducet1inlett2'=Lambda.snf(fst(Rewrite.Term.normalize_termt2))inlethd,l=Term.as_appreducedinif(Term.is_consthd&&distinct_free_varsl&&Type.is_fun(Term.tyhd))then(letsym=(Term.as_const_exnhd)in(matchIdMap.find_optsym!def_symwith|Some(rhs,rw_rule)->(letrhs=Lambda.eta_reducerhsinifnot(Unif.FO.are_variantrhst2')then(None)elserw_rule)|_->build_from_headsymlt2))elseNoneinletall_lits=Seq.litscinifIter.lengthall_lits=1thenmatchIter.head_exnall_litswith|SLiteral.Eq(t1,t2)whennot(List.memt1[Term.true_;Term.false_])&¬(List.memt2[Term.true_;Term.false_])->assert(Type.equal(Term.tyt1)(Term.tyt2));letty=Term.tyt1inletfresh_vars=List.map(funty->Term.var(HVar.fresh~ty()))(Type.expected_argsty)inlett1,t2=Lambda.snf@@Term.appt1fresh_vars,Lambda.snf@@Term.appt2fresh_varsinif(Term.weightt2-Term.weightt1<=w_i)then(matchconv_terms_rwt1t2with|Somerhs->Somerhs|None->ifTerm.weightt1-Term.weightt2<=w_ithenconv_terms_rwt2t1elseNone)else(ifTerm.weightt1-Term.weightt2<=w_ithenconv_terms_rwt2t1elseNone)|_->NoneelseNone