Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file Cut_form.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266(* This file is free software, part of Zipperposition. See file "license" for more details. *)(** {1 Universally Quantified Conjunction of Clauses} *)openLogtkmoduleFmt=CCFormatmoduleT=Termtypevar=Term.vartypeterm=Term.ttypeclause=Literals.ttypeform=clauselisttypet={vars:T.VarSet.t;cs:form;}typecut_form=tlettrivial={cs=[];vars=T.VarSet.empty}letmakecs=ifcs=[]thentrivialelse(letvars=Iter.of_listcs|>Iter.flat_mapLiterals.Seq.vars|>T.VarSet.of_iterandcs=CCList.sort_uniq~cmp:Literals.comparecsin{cs;vars;})letvarst=t.varsletcst=t.cslethash(f:t):int=Hash.listLiterals.hashf.csletequalf1f2:bool=CCList.equalLiterals.equalf1.csf2.csletcomparef1f2=CCList.compareLiterals.comparef1.csf2.csletppout(f:t):unit=letpp_c=Literals.ppinletpp_bodyout()=matchf.cswith|[c]->pp_coutc|_->Fmt.fprintfout"@<1>∧{@[<hv>%a@]}"(Util.pp_list~sep:","pp_c)f.csinifT.VarSet.is_emptyf.varsthen(pp_bodyout())else(Fmt.fprintfout"(@[<2>forall %a.@ %a@])"(Util.pp_list~sep:" "Type.pp_typed_var)(T.VarSet.to_listf.vars)pp_body())letto_string=Fmt.to_stringppletpp_tstpout(f:t):unit=letpp_c=Fmt.within"("")"Literals.pp_tstpinletpp_bodyout()=matchf.cswith|[c]->pp_coutc|_->Fmt.fprintfout"(@[%a@])"(Util.pp_list~sep:" & "pp_c)f.csinifT.VarSet.is_emptyf.varsthen(pp_bodyout())else(Fmt.fprintfout"(@[<2>![%a]:@ (%a)@])"(Util.pp_listType.TPTP.pp_typed_var)(T.VarSet.to_listf.vars)pp_body())letpp_zfout(f:t):unit=letpp_c=Fmt.within"("")"Literals.pp_zfinletpp_bodyout()=matchf.cswith|[c]->pp_coutc|_->Fmt.fprintfout"(@[%a@])"(Util.pp_list~sep:" && "pp_c)f.csinifT.VarSet.is_emptyf.varsthen(pp_bodyout())else(Fmt.fprintfout"(@[<2>forall %a.@ (%a)@])"(Util.pp_listType.ZF.pp_typed_var)(T.VarSet.to_listf.vars)pp_body())letind_varst=varst|>T.VarSet.to_list|>List.filter(funv->letty=HVar.tyvin(* only do induction on variables of infinite types *)beginmatchInd_ty.as_inductive_typetywith|Some(ity,_)->Ind_ty.is_recursiveity|None->falseend)letapply_substrenamingsubst(f,sc):t=letcs=List.map(funlits->Literals.apply_substrenamingsubst(lits,sc))f.csinmakecsletsubst1(v:var)(t:term)(f:t):t=letrenaming=Subst.Renaming.create()inletsubst=Subst.FO.bindSubst.empty((v:var:>InnerTerm.tHVar.t),0)(t,1)inapply_substrenamingsubst(f,0)(* find substitutions making [f1] and [f2] variants, if possible *)letvariant_~subst(f1,sc1)(f2,sc2):_Iter.t=Unif.unif_list_com~size:`Samesubst~op:(funsubstc1c2k->Literals.variant~substc1c2(fun(subst,_tags)->ksubst))(f1.cs,sc1)(f2.cs,sc2)letare_variantf1f2:bool=not@@Iter.is_empty@@variant_~subst:Subst.empty(f1,1)(f2,0)letnormalize_form(f:form):form=letmoduleRW=Rewriteinletrecsimplifyc=letlit_abs=CCArray.find_idxLiteral.is_absurdcinbeginmatchlit_abswith|None->c|Some(i,_)->letnew_c=CCArray.except_idxci|>Array.of_listinsimplifynew_cendin(* fixpoint of rewriting *)letrecnormalize_up_tofuel(c:clause):clauseIter.t=assert(fuel>=0);iffuel=0thenIter.returncelsenormalize_step(fuel-1)candnormalize_stepfuelc=letprogress=reffalsein(* how to normalize a term/lit (with restricted resources) *)letrw_termt=lett',rules=RW.Term.normalize_term~max_steps:10tinifnot(RW.Term.Rule_inst_set.is_emptyrules)thenprogress:=true;t'inletrw_termsc=Literals.maprw_termcandrw_clausec=matchRW.Lit.normalize_clausecwith|None->[c]|Some(cs,_,_,_,_,_)->progress:=true;csandrm_trivial=List.filter(func->not(Literals.is_trivialc))inletcs=c|>rw_terms|>rw_clause|>rm_trivialinif!progressthennormalize_formfuelcs(* normalize each result recursively *)else((* done, just simplify *)Iter.of_listcs|>Iter.mapsimplify)andnormalize_formfuel(f:form):clauseIter.t=Iter.of_listf|>Iter.flat_map(normalize_up_tofuel)innormalize_form3f|>Iter.to_rev_listletnormalize(f:t):t=csf|>normalize_form|>makeletto_s_form(f:t)=letmoduleF=TypedSTerm.Formin(* convert all clauses with the same variable bindings *)letctx=Term.Conv.create()inletl=List.map(Literals.Conv.to_s_form~ctx)(csf)inF.and_l|>F.close_forallmodulePos=structmoduleP=Positionletbad_posfp=Util.invalid_argf"invalid pos `%a`@ in %a"P.pppppfletclause_atfp=matchpwith|P.Stop->bad_posfp|P.Arg(n,p')->letcs=csfinifn<0||n>=List.lengthcsthenbad_posfp;List.nthcsn,p'|_->bad_posfpletlit_atfp=letc,p=clause_atfpinLiterals.Pos.lit_atcpletatfp:term=letlit,p=lit_atfpinLiteral.Pos.atlitpletreplace_manyfm:t=letl=csfinP.Map.fold(funpbyl->letn,p_c=matchpwithP.Arg(n,p')->n,p'|_->assertfalseinletc=List.nthlninletc'=Array.copycinLiterals.Pos.replacec'~at:p_c~by;CCList.set_at_idxnc'l)ml|>makeletreplacef~at~by=replace_manyf(P.Map.singletonatby)endmoduleSeq=structlettermsf=csf|>Iter.of_list|>Iter.flat_mapLiterals.Seq.termsletterms_with_pos?(subterms=true)f=csf|>Iter.of_list|>Util.seq_zipi|>Iter.flat_map(fun(i,c)->Iter.of_array_ic|>Iter.map(fun(j,lit)->i,j,lit))|>Iter.flat_map(fun(i,j,lit)->letposition=Position.(argi@@argj@@stop)inLiteral.fold_termslit~position~ord:Ordering.none~which:`All~vars:true~subterms)endmoduleFV_tbl(X:Map.OrderedType)=structtypevalue=X.t(* approximation here, we represent it as a clause, losing the
boolean structure. monotonicity w.r.t features should still apply *)letto_lits(f:cut_form)=csf|>Iter.of_list|>Iter.flat_map_lLiterals.to_form(* index for lemmas, to ensure α-equivalent lemmas have the same lit *)moduleFV=FV_tree.Make(structtypet=cut_form*X.tletcompare(l1,v1)(l2,v2)=letopenCCOrd.Infixincomparel1l2<?>(X.compare,v1,v2)letto_lits(l,_)=to_litslletlabels_=Util.Int_set.emptyend)typet={mutablefv:FV.t;}letcreate()={fv=FV.empty()}letaddtkv=t.fv<-FV.addt.fv(k,v)letgettk=FV.retrieve_alpha_equivt.fv(to_litsk)Util.Int_set.empty|>Iter.find_map(fun(k',v)->ifare_variantkk'thenSomevelseNone)letmemtk=gettk|>CCOpt.is_someletto_itert=FV.itert.fvend