123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772(* This file is free software, part of Logtk. See file "license" for more details. *)(** {1 Builtin Objects} *)let_t_bigger_false=reffalse;moduleFmt=CCFormattypet=|Not|And|Or|Imply|Equiv|Xor|Eq|Neq|HasType|True|False|Arrow|Wildcard|Multiset(* type of multisets *)|TType(* type of types *)|Prop|Term|ForallConst(** constant for simulating forall *)|ExistsConst(** constant for simulating exists *)|Grounding(** used for inst-gen *)|TyInt|TyRat|TyReal|IntofZ.t|RatofQ.t|Realofstring|Floor|Ceiling|Truncate|Round|Prec|Succ|Sum|Difference|Uminus|Product|Quotient|Quotient_e|Quotient_t|Quotient_f|Remainder_e|Remainder_t|Remainder_f|Is_int|Is_rat|To_int|To_rat|Less|Lesseq|Greater|Greatereq|Box_opaque(** hint not to open this formula *)|Pseudo_de_bruijnofint(** magic to embed De Bruijn indices in normal terms *)|BComb|CComb|IComb|KComb|SComb|Distincttypet_=tletto_int_=function(* True > false for the completeness of (HO case) FOOL paramodulation: C[b] ⟹ b ∨ C[false]. The opposite way required b=false would simplify b≠true (aka ¬b) which doesn't rewrite. *)|True->if!_t_bigger_falsethen1else0|False->if!_t_bigger_falsethen0else1|Not->2|And->3|Or->4|Imply->5|Equiv->6|Xor->7|Eq->8|Neq->9|HasType->10|Arrow->12|Wildcard->13|Multiset->14|TType->15|Int_->16|Rat_->17|Prop->18|Term->19|TyRat->20|TyInt->21|Floor->22|Ceiling->23|Truncate->24|Round->25|Prec->26|Succ->27|Sum->28|Difference->29|Uminus->30|Product->31|Quotient->32|Quotient_e->33|Quotient_t->34|Quotient_f->35|Remainder_e->36|Remainder_t->37|Remainder_f->38|Is_int->39|Is_rat->40|To_int->41|To_rat->42|Less->43|Lesseq->44|Greater->45|Greatereq->46|ForallConst->47|ExistsConst->48|Grounding->50|Box_opaque->60|TyReal->70|Real_->71|BComb->80|CComb->81|IComb->82|KComb->83|SComb->84|Pseudo_de_bruijn_->100|Distinct->110letas_int=to_int_letcompareab=matcha,bwith|Inti,Intj->Z.compareij|Rati,Ratj->Q.compareij|_->to_int_a-to_int_bletequalab=compareab=0lethashs=matchswith|Inti->Hash.combine21(Z.hashi)|Ratr->Hash.combine22(Hash.string(Q.to_stringr))|c->Hash.combine23(Hashtbl.hashc)moduleMap=Iter.Map.Make(structtypet=t_letcompare=compareend)moduleSet=Iter.Set.Make(structtypet=t_letcompare=compareend)moduleTbl=Hashtbl.Make(structtypet=t_letequal=equallethash=hashend)letis_int=functionInt_->true|_->falseletis_rat=functionRat_->true|_->falseletis_numeric=functionInt_|Rat_->true|_->falseletis_not_numericx=not(is_numericx)letis_logical_op=function|And|Or|Not|Imply|Equiv|Xor|ForallConst|ExistsConst->true|_->falseletis_logical_binop=function|And|Or|Imply|Xor|Equiv->true|_->falseletis_flattened_logical=function|And|Or->true|_->falseletis_quantifier=function|ForallConst|ExistsConst->true|_->falseletis_arith=function|Int_|Rat_|Floor|Ceiling|Truncate|Round|Prec|Succ|Sum|Difference|Uminus|Product|Quotient|Quotient_e|Quotient_t|Quotient_f|Remainder_e|Remainder_t|Remainder_f|Is_int|Is_rat|To_int|To_rat|Less|Lesseq|Greater|Greatereq->true|_->falseletto_strings=matchswith|Intn->Z.to_stringn|Ratn->Q.to_stringn|Realr->r|Not->"¬"|And->"∧"|Or->"∨"|Imply->"⇒"|Equiv->"≡"|Xor->"<~>"|Eq->"="|Neq->"≠"|HasType->":"|True->"true"|False->"false"|Arrow->"→"|Wildcard->"_"|Multiset->"Ms"|TType->"type"|Prop->"prop"|Term->"ι"|ForallConst->"·∀"|ExistsConst->"·∃"|Grounding->"★"|TyInt->"int"|TyRat->"rat"|TyReal->"real"|Floor->"floor"|Ceiling->"ceiling"|Truncate->"truncate"|Round->"round"|Prec->"prec"|Succ->"succ"|Sum->"+"|Difference->"-"|Uminus->"uminus"|Product->"×"|Quotient->"/"|Quotient_e->"quotient_e"|Quotient_t->"quotient_t"|Quotient_f->"quotient_f"|Remainder_e->"remainder_e"|Remainder_t->"remainder_t"|Remainder_f->"remainder_f"|Is_int->"is_int"|Is_rat->"is_rat"|To_int->"to_int"|To_rat->"to_rat"|Less->"<"|Lesseq->"≤"|Greater->">"|Greatereq->"≥"|Box_opaque->"<box>"|BComb->"B"|CComb->"C"|IComb->"I"|KComb->"K"|SComb->"S"|Pseudo_de_bruijni->Printf.sprintf"db_%d"i|Distinct->"distinct"letppouts=Format.pp_print_stringout(to_strings)typefixity=|Infix_binary|Infix_nary|Prefixletfixity=function|And|Or->Infix_nary|Imply|Equiv|Xor|Eq|Neq|HasType|Sum|Difference|Product|Quotient|Quotient_e|Quotient_f|Quotient_t|Remainder_e|Remainder_t|Remainder_f|Less|Lesseq|Greater|Greatereq->Infix_binary|_->Prefixletis_prefixo=fixityo=Prefixletis_infixo=matchfixityowithInfix_nary|Infix_binary->true|Prefix->falseletis_combinator=function|BComb|CComb|IComb|KComb|SComb->true|_->falseletty=function|Int_->`Int|Rat_->`Rat|_->`Otherletmk_ints=Intsletof_inti=Int(Z.of_inti)letint_of_strings=Int(Z.of_strings)letmk_rats=Ratsletof_ratij=Rat(Q.of_intsij)letrat_of_strings=Rat(Q.of_strings)lettrue_=Trueletfalse_=Falseletwildcard=Wildcardletand_=Andletor_=Orletimply=Implyletequiv=Equivletxor=Xorletnot_=Notleteq=Eqletneq=Neqletarrow=Arrowlethas_type=HasTypelettType=TTypeletmultiset=Multisetletprop=Propletterm=Termletty_int=TyIntletty_rat=TyRatletty_real=TyRealletgrounding=GroundingmoduleTag=structtypet=|T_lia(** integer arith *)|T_lra(** rational arith *)|T_ho(** higher order *)|T_live_cnf(** live cnf *)|T_ho_norm(** higher-order normalization *)|T_dont_increase_depth(** an inference rule that makes a clause more first-order and should not be counted in the proof depth. *)|T_ext(** extensionality *)|T_ind(** induction *)|T_data(** datatypes *)|T_distinct(** distinct constants *)|T_acofID.t(** AC symbols *)|T_cannot_orphanletcompare=Pervasives.compareletppout=function|T_lia->Fmt.stringout"lia"|T_lra->Fmt.stringout"lra"|T_ho->Fmt.stringout"ho"|T_live_cnf->Fmt.stringout"live_cnf"|T_ho_norm->Fmt.stringout"ho_norm"|T_dont_increase_depth->Fmt.stringout"dont_increase_depth"|T_ext->Fmt.stringout"extensionality"|T_ind->Fmt.stringout"ind"|T_data->Fmt.stringout"data"|T_distinct->Fmt.stringout"distinct_constants"|T_acid->Fmt.fprintfout"(ac %a)"ID.pp_fullid|T_cannot_orphan->Fmt.fprintfout"cannot orphan"endmoduleArith=structletfloor=Floorletceiling=Ceilinglettruncate=Truncateletround=Roundletprec=Precletsucc=Succletsum=Sumletdifference=Differenceletuminus=Uminusletproduct=Productletquotient=Quotientletquotient_e=Quotient_eletquotient_t=Quotient_tletquotient_f=Quotient_fletremainder_e=Remainder_eletremainder_t=Remainder_tletremainder_f=Remainder_fletis_int=Is_intletis_rat=Is_ratletto_int=To_intletto_rat=To_ratletless=Lessletlesseq=Lesseqletgreater=Greaterletgreatereq=GreatereqendmoduleTPTP=structletto_string=function|Eq->"="|Neq->"!="|And->"&"|Or->"|"|Not->"~"|Imply->"=>"|Equiv->"<=>"|Xor->"<~>"|HasType->":"|True->"$true"|False->"$false"|Arrow->">"|Wildcard->"$_"|TType->"$tType"|Term->"$i"|Prop->"$o"|Multiset->failwith"cannot print this symbol in TPTP"|ForallConst->"!!"|ExistsConst->"??"|Grounding->"$$ground"|TyInt->"$int"|TyRat->"$rat"|TyReal->"$real"|Intx->Z.to_stringx|Ratx->Q.to_stringx|Realr->r|Floor->"$floor"|Ceiling->"$ceiling"|Truncate->"$truncate"|Round->"$round"|Prec->"$prec"|Succ->"$succ"|Sum->"$sum"|Difference->"$diff"|Uminus->"$uminus"|Product->"$product"|Quotient->"$quotient"|Quotient_e->"$quotient_e"|Quotient_t->"$quotient_t"|Quotient_f->"$quotient_f"|Remainder_e->"$remainder_e"|Remainder_t->"$remainder_t"|Remainder_f->"$remainder_f"|Is_int->"$is_int"|Is_rat->"$is_rat"|To_int->"$to_int"|To_rat->"$to_rat"|Less->"$less"|Lesseq->"$lesseq"|Greater->"$greater"|Greatereq->"$greatereq"|BComb->"'#B'"|CComb->"'#C'"|IComb->"'#I'"|KComb->"'#K'"|SComb->"'#S'"|Box_opaque->"$$box"|Pseudo_de_bruijni->Printf.sprintf"$$db_%d"i|Distinct->"$distinct"letppoutb=CCFormat.stringout(to_stringb)exceptionNotABuiltinletof_string_exn=function|"$true"->True|"$false"->False|"$_"->Wildcard|"$tType"->TType|"$i"->Term|"$o"->Prop|"!!"->ForallConst|"??"->ExistsConst|"$int"->TyInt|"$rat"->TyRat|"$floor"->Floor|"$ceiling"->Ceiling|"$truncate"->Truncate|"$round"->Round|"$prec"->Prec|"$succ"->Succ|"$sum"->Sum|"$difference"->Difference|"$uminus"->Uminus|"$product"->Product|"$quotient"->Quotient|"$quotient_e"->Quotient_e|"$quotient_t"->Quotient_t|"$quotient_f"->Quotient_f|"$remainder_e"->Remainder_e|"$remainder_t"->Remainder_t|"$remainder_f"->Remainder_f|"$is_int"->Is_int|"$is_rat"->Is_rat|"$to_int"->To_int|"$to_rat"->To_rat|"$less"->Less|"$lesseq"->Lesseq|"$greater"->Greater|"$greatereq"->Greatereq|"#B"->BComb|"#S"->SComb|"#C"->CComb|"#K"->KComb|"#I"->IComb|"$distinct"->Distinct|_->raiseNotABuiltinletfixity=function|And|Or->Infix_nary|Imply|Equiv|Xor|Eq|Neq|HasType->Infix_binary|_->Prefixletis_prefixo=fixityo=Prefixletis_infixo=matchfixityowithInfix_nary|Infix_binary->true|Prefix->falseletof_stringb=trySome(of_string_exnb)withNotABuiltin->None(* TODO add the other ones *)letconnectives=Set.of_iter(Iter.of_list[and_;or_;equiv;imply;])letis_connective=function|Int_|Rat_->false|_->trueendmoduleArithOp=structexceptionTypeMismatchofstring(** This exception is raised when Arith functions are called
on non-numeric values (Cst). *)(* helper to raise errors *)let_ty_mismatchfmt=CCFormat.ksprintf~f:(funmsg->raise(TypeMismatchmsg))fmtletsign=function|Intn->Z.signn|Ratn->Q.signn|s->_ty_mismatch"cannot compute sign of symbol %a"ppstypearith_view=[`IntofZ.t|`RatofQ.t|`Otheroft]letview=function|Inti->`Inti|Ratn->`Ratn|s->`Othersletparse_nums=ifString.containss'/'thenmk_rat(Q.of_strings)elsemk_int(Z.of_strings)letone_i=mk_intZ.oneletzero_i=mk_intZ.zeroletone_rat=mk_ratQ.oneletzero_rat=mk_ratQ.zeroletzero_of_ty=function|`Rat->zero_rat|`Int->zero_iletone_of_ty=function|`Rat->one_rat|`Int->one_iletis_zero=function|Intn->Z.signn=0|Ratn->Q.signn=0|s->_ty_mismatch"not a number: %a"ppsletis_one=function|Intn->Z.equalnZ.one|Ratn->Q.equalnQ.one|s->_ty_mismatch"not a number: %a"ppsletis_minus_one=function|Intn->Z.equalnZ.minus_one|Ratn->Q.equalnQ.minus_one|s->_ty_mismatch"not a number: %a"ppsletfloors=matchswith|Int_->s|Ratn->mk_int(Q.to_bigintn)|s->_ty_mismatch"not a numeric constant: %a"ppsletceilings=matchswith|Int_->s|Rat_->failwith"Q.ceiling: not implemented"(* TODO *)|s->_ty_mismatch"not a numeric constant: %a"ppslettruncates=matchswith|Int_->s|RatnwhenQ.signn>=0->mk_int(Q.to_bigintn)|Rat_->failwith"Q.truncate: not implemented"(* TODO *)|s->_ty_mismatch"not a numeric constant: %a"ppsletrounds=matchswith|Int_->s|Rat_->failwith"Q.round: not implemented"(* TODO *)|s->_ty_mismatch"not a numeric constant: %a"ppsletprecs=matchswith|Intn->mk_intZ.(n-one)|Ratn->mk_ratQ.(n-one)|s->_ty_mismatch"not a numeric constant: %a"ppsletsuccs=matchswith|Intn->mk_intZ.(n+one)|Ratn->mk_ratQ.(n+one)|s->_ty_mismatch"not a numeric constant: %a"ppsleterr2_s1s2=matchs1,s2with|Int_,Rat_|Rat_,Int_->_ty_mismatch"incompatible numeric types: %a and %a"pps1pps2|_->_ty_mismatch"not numeric constants: %a, %a"pps1pps2letsums1s2=matchs1,s2with|Intn1,Intn2->mk_intZ.(n1+n2)|Ratn1,Ratn2->mk_ratQ.(n1+n2)|_->err2_s1s2letdifferences1s2=matchs1,s2with|Intn1,Intn2->mk_intZ.(n1-n2)|Ratn1,Ratn2->mk_ratQ.(n1-n2)|_->err2_s1s2letuminuss=matchswith|Intn->mk_int(Z.negn)|Ratn->mk_rat(Q.negn)|s->_ty_mismatch"not a numeric constant: %a"ppsletproducts1s2=matchs1,s2with|Intn1,Intn2->mk_intZ.(n1*n2)|Ratn1,Ratn2->mk_ratQ.(n1*n2)|_->err2_s1s2letquotients1s2=matchs1,s2with|Intn1,Intn2->letq,r=Z.div_remn1n2inifZ.signr=0thenmk_intqelse_ty_mismatch"non-exact integral division: %a / %a"pps1pps2|Ratn1,Ratn2->ifQ.signn2=0thenraiseDivision_by_zeroelsemk_rat(Q.divn1n2)|_->err2_s1s2letquotient_es1s2=matchs1,s2with|Intn1,Intn2->mk_int(Z.divn1n2)|_->ifsigns2>0thenfloor(quotients1s2)elseceiling(quotients1s2)letquotient_ts1s2=matchs1,s2with|Intn1,Intn2->mk_int(Z.divn1n2)|_->truncate(quotients1s2)letquotient_fs1s2=matchs1,s2with|Intn1,Intn2->mk_int(Z.divn1n2)|_->floor(quotients1s2)letremainder_es1s2=matchs1,s2with|Intn1,Intn2->mk_int(Z.remn1n2)|_->differences1(product(quotient_es1s2)s2)letremainder_ts1s2=matchs1,s2with|Intn1,Intn2->mk_int(Z.remn1n2)|_->differences1(product(quotient_ts1s2)s2)letremainder_fs1s2=matchs1,s2with|Intn1,Intn2->mk_int(Z.remn1n2)|_->differences1(product(quotient_fs1s2)s2)letto_ints=matchswith|Int_->s|_->floorsletto_rats=matchswith|Intn->mk_rat(Q.of_bigintn)|Rat_->s|_->_ty_mismatch"not a numeric constant: %a"ppsletabss=matchswith|Intn->mk_int(Z.absn)|Ratn->mk_rat(Q.absn)|_->_ty_mismatch"not a numeric constant: %a"ppsletdividesab=matcha,bwith|Rati,Rat_->Q.signi<>0|Inta,Intb->Z.signa<>0&&Z.sign(Z.remba)=0|_->_ty_mismatch"divides: expected two numerical types"letgcdab=matcha,bwith|Rat_,Rat_->one_rat|Inta,Intb->mk_int(Z.gcdab)|_->_ty_mismatch"gcd: expected two numerical types"letlcmab=matcha,bwith|Rat_,Rat_->one_rat|Inta,Intb->mk_int(Z.lcmab)|_->_ty_mismatch"gcd: expected two numerical types"letlesss1s2=matchs1,s2with|Intn1,Intn2->Z.ltn1n2|Ratn1,Ratn2->Q.ltn1n2|_->err2_s1s2letlesseqs1s2=matchs1,s2with|Intn1,Intn2->Z.leqn1n2|Ratn1,Ratn2->Q.leqn1n2|_->err2_s1s2letgreaters1s2=lesss2s1letgreatereqs1s2=lesseqs2s1(* factorize [n] into a product of prime numbers. [n] must be positive *)letdivisorsn=if(Z.leqnZ.zero)thenraise(Invalid_argument"prime_factors: expected number > 0")elsetryletn=Z.to_intninletl=ref[]infori=2ton/2doifi<n&&nmodi=0thenl:=i::!ldone;List.rev_mapZ.of_int!lwithZ.Overflow->[](* too big *)endmoduleZF=structletto_string=function|Eq->"="|Neq->"!="|And->"&&"|Or->"||"|Not->"~"|Imply->"=>"|Equiv->"<=>"|HasType->":"|True->"true"|False->"false"|Arrow->">"|Wildcard->"_"|TType->"type"|Prop->"prop"|Term->"term"(* XXX needs to be declared! *)|Xor|Multiset->failwith"cannot print this symbol in ZF"|ForallConst->"!!"|ExistsConst->"??"|Grounding->"$$grounding"|TyInt->"int"|TyRat->"rat"|TyReal->"real"|Intx->Z.to_stringx|Ratx->Q.to_stringx|Realx->x(* FIXME: update *)|Floor->"$floor"|Ceiling->"$ceiling"|Truncate->"$truncate"|Round->"$round"|Prec->"$prec"|Succ->"$succ"|Sum->"+"|Difference->"-"|Uminus->"-"|Product->"*"|Quotient->"$quotient"|Quotient_e->"/"|Quotient_t->"$quotient_t"|Quotient_f->"$quotient_f"|Remainder_e->"mod"|Remainder_t->"$remainder_t"|Remainder_f->"$remainder_f"|Is_int->"$is_int"|Is_rat->"$is_rat"|To_int->"$to_int"|To_rat->"$to_rat"|Less->"<"|Lesseq->"<="|Greater->">"|Greatereq->">="|BComb->"B"|CComb->"C"|IComb->"I"|KComb->"K"|SComb->"S"|Box_opaque->"<box>"|Pseudo_de_bruijni->Printf.sprintf"<db %d>"i|Distinct->"distinct"letppoutb=CCFormat.stringout(to_stringb)end