123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128(* 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."|_->CCFormat.printf"@[%a@]@."(SLiteral.ppTST.pp)lhs;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_cstleteliminate_long_implications?(is_goal=false)f=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_impsfletsine_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_listformulasinletsymset_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_formulasformulasinletaxioms=iftake_only_defsthendefselsedefs@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~section3"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~section1"conj_syms:@[%a@]"(funk->k(ID.Set.ppID.pp)conj_syms);lettriggered_1=triggered_by_syms~triggersconj_symsinID.Tbl.iter(funidset->Util.debugf~section1"@[%a/%d@] > @[%a@]"(funk->kID.ppid(ID.idid)(CCList.ppCCString.pp)(List.mapname(InpStmSet.elementsset))))triggers;Util.debugf~section2"layer 0"CCFun.id;Util.debugf~section2"symbols: @[%a@]"(funk->k(ID.Set.ppID.pp)conj_syms);Util.debugf~section2"axs: @[%a@]"(funk->k(CCList.ppCCString.pp)(List.mapnametriggered_1));letrectake_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~triggersunprocessedinUtil.debugf~section2"layer @[%d@]"(func->ck);Util.debugf~section2"symbols: @[%a@]"(funk->k(ID.Set.ppID.pp)unprocessed);Util.debugf~section2"axs: @[%a@]"(funk->k(CCList.ppCCString.pp)(List.mapnamek_p_1_triggered_ax));taken@(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~section1"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