123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449(* This file is free software, part of dolmen. See file "LICENSE" for more information. *)typelocation=ParseLocation.ttypebuiltin=|Wildcard|Ttype|Prop|True|False|Eq|Distinct(* Should all args be pairwise distinct or equal ? *)|Ite(* Condional *)|Sequent(* Is the given sequent provable ? *)|Int(* Arithmetic type for integers *)|Minus(* arithmetic unary minus *)|Add|Sub|Mult(* arithmetic operators *)|Lt|Leq(* arithmetic comparisons *)|Gt|Geq(* arithmetic comparisons *)|Subtype(* Function type constructor and subtyping relation *)|Product|Union(* Product and union of types (not set theory) *)|Not(* Propositional negation *)|And|Or(* Conjunction and disjunction *)|Nand|Xor|Nor(* Advanced propositional connectives *)|Imply|Implied(* Implication and left implication *)|Equiv(* Equivalence *)typebinder=|All|Ex|Pi|Arrow|Let|Fun(* Standard binders *)|Choice(* Indefinite description, or epsilon terms *)|Description(* Definite description *)typedescr=|SymbolofId.t|Builtinofbuiltin|Colonoft*t|Appoft*tlist|Binderofbinder*tlist*t|Matchoft*(t*t)listandt={term:descr;attr:tlist;loc:locationoption;}(* Printing info *)letinfix_builtinn=function|Add|Sub|Lt|Leq|Gt|Geq|Eq|And|Or|Nand|Xor|Nor|Imply|Implied|Equiv|Product|Union|Sequent|Subtype->true|Distinctwhenn=2->true|_->falseletbuiltin_to_string=function|Wildcard->"_"|Ttype->"$tType"|Prop->"$o"|True->"⊤"|False->"⊥"|Eq->"=="|Distinct->"!="|Ite->"#ite"|Sequent->"⊢"|Int->"$int"|Minus->"-"|Add->"+"|Sub->"-"|Mult->"×"|Lt->"<"|Leq->"≤"|Gt->">"|Geq->"≥"|Subtype->"⊂"|Product->"*"|Union->"∪"|Not->"¬"|And->"∧"|Or->"∨"|Nand->"⊼"|Xor->"⊻"|Nor->"V"|Imply->"⇒"|Implied->"⇐"|Equiv->"⇔"letbinder_to_string=function|All->"∀"|Ex->"∃"|Pi->"Π"|Arrow->"→"|Let->"let"|Fun->"λ"|Choice->"ε"|Description->"@"(* Debug printing *)letpp_builtinbbuiltin=Printf.bprintfb"%s"(builtin_to_stringbuiltin)letpp_binderbbinder=Printf.bprintfb"%s"(binder_to_stringbinder)letrecpp_descrb=function|Symbolid->Id.ppbid|Builtins->pp_builtinbs|Colon(u,v)->Printf.bprintfb"%a : %a"ppuppv|App({term=Builtinsep;_},l)wheninfix_builtin(List.lengthl)sep->Misc.pp_list~pp_sep:pp_builtin~sep~ppbl|App(f,l)->Printf.bprintfb"%a(%a)"ppf(Misc.pp_list~pp_sep:Buffer.add_string~sep:","~pp)l|Binder(Arrowasq,l,e)->Printf.bprintfb"%a %a %a"(Misc.pp_list~pp_sep:Buffer.add_string~sep:" → "~pp)lpp_binderqppe|Binder(q,l,e)->Printf.bprintfb"%a %a. %a"pp_binderq(Misc.pp_list~pp_sep:Buffer.add_string~sep:","~pp)lppe|Match(t,l)->Printf.bprintfb"match %a with %a"ppt(Misc.pp_list~pp_sep:Buffer.add_string~sep:" | "~pp:pp_match_case)landpp_match_caseb(pattern,branch)=Printf.bprintfb"%a => %a"pppatternppbranchandppb=function|{term=(Symbol_)asd;_}|{term=(Builtin_)asd;_}->pp_descrbd|e->Printf.bprintfb"(%a)"pp_descre.term(* Pretty-printing *)letprint_builtinfmtbuiltin=Format.fprintffmt"%s"(builtin_to_stringbuiltin)letprint_binderfmtbinder=Format.fprintffmt"%s"(binder_to_stringbinder)letrecprint_descrfmt=function|Symbolid->Id.printfmtid|Builtins->print_builtinfmts|Colon(u,v)->Format.fprintffmt"%a :@ %a"printuprintv|App({term=Builtinsep;_},l)wheninfix_builtin(List.lengthl)sep->Misc.print_list~print_sep:print_builtin~sep~printfmtl|App(f,[])->Format.fprintffmt"%a"printf|App(f,l)->Format.fprintffmt"%a@ %a"printf(Misc.print_list~print_sep:Format.fprintf~sep:"@ "~print)l|Binder(Arrowasq,l,e)->Format.fprintffmt"%a %a@ %a"(Misc.print_list~print_sep:Format.fprintf~sep:"→@ "~print)lprint_binderqprinte|Binder(q,l,e)->Format.fprintffmt"%a@ %a.@ %a"print_binderq(Misc.print_list~print_sep:Format.fprintf~sep:"@ "~print)lprinte|Match(t,l)->Format.fprintffmt"match %a with %a"printt(Misc.print_list~print_sep:Format.fprintf~sep:" | "~print:print_match_case)landprint_match_casefmt(pattern,branch)=Format.fprintffmt"%a => %a"printpatternprintbranchandprintfmt=function|{term=(Symbol_)asd;_}|{term=(Builtin_)asd;_}->print_descrfmtd|e->Format.fprintffmt"@[<hov 2>(%a)@]"print_descre.term(* Comparison *)let_descr=function|Symbol_->1|Builtin_->2|Colon_->3|App_->4|Binder_->5|Match_->6letreccompare_listcmpll'=matchl,l'with|[],[]->0|_::_,[]->1|[],_::_->-1|t::r,t'::r'->beginmatchcmptt'with|0->compare_listcmprr'|x->xendletreccomparett'=matcht.term,t'.termwith|Symbols,Symbols'->Id.comparess'|Builtinb,Builtinb'->Pervasives.comparebb'|Colon(t1,t2),Colon(t1',t2')->compare_listcompare[t1;t2][t1';t2']|App(f,l),App(f',l')->compare_listcompare(f::l)(f'::l')|Binder(b,vars,t),Binder(b',vars',t')->beginmatchPervasives.comparebb'with|0->beginmatchcompare_listcomparevarsvars'with|0->comparett'|x->xend|x->xend|Match(t,l),Match(t',l')->beginmatchcomparett'with|0->compare_listcompare_pairll'|x->xend|u,v->(_descru)-(_descrv)andcompare_pair(a,b)(c,d)=matchcompareacwith|0->comparebd|x->xletequaltt'=comparett'=0(* Add an attribute *)letadd_attrat={twithattr=a::t.attr}letadd_attrslt={twithattr=l@t.attr}letset_attrslt=assert(t.attr=[]);{twithattr=l}(* Make a term from its description *)letmake?loc?(attr=[])term={term;attr;loc;}letbuiltinb?loc()=make?loc(Builtinb)(* Internal shortcut to make a formula with bound variables. *)letmk_bindbinder?locvarst=make?loc(Binder(binder,vars,t))(* Attach an attribute list to a term *)letannot?loctl={twithattr=t.attr@l;loc}(* Create a constant and/or variable, that is a leaf
of the term AST. *)letconst?locid=make?loc(Symbolid)(* Apply a term to a list of terms. *)letapply?locfargs=make?loc(App(f,args))letmatch_?loctl=make?loc(Match(t,l))(* Juxtapose two terms, usually a term and its type.
Used mainly for typed variables, or type annotations. *)letcolon?loctt'=make?loc(Colon(t,t'))leteq_t=builtinEqletneq_t=builtinDistinctletnot_t=builtinNotletor_t=builtinOrletand_t=builtinAndletxor_t=builtinXorletnor_t=builtinNorletnand_t=builtinNandletequiv_t=builtinEquivletimplies_t=builtinImplyletimplied_t=builtinImpliedlettrue_=builtinTrueletfalse_=builtinFalseletwildcard=builtinWildcardletite_t=builtinIteletsequent_t=builtinSequentletunion_t=builtinUnionletproduct_t=builtinProductletsubtype_t=builtinSubtypelettType=builtinTtypeletprop=builtinPropletdata_t?loc()=const?locId.(mkAttr"$data")letty_int=builtinIntletuminus_t=builtinMinusletadd_t=builtinAddletsub_t=builtinSubletmult_t=builtinMultletlt_t=builtinLtletleq_t=builtinLeqletgt_t=builtinGtletgeq_t=builtinGeqletnaryt=(fun?locl->apply?loctl)letunaryt=(fun?locx->apply?loct[x])letbinaryt=(fun?locxy->apply?loct[x;y])(* {2 Usual functions} *)leteq=binary(eq_t())(* {2 Logical connectives} *)letnot_=unary(not_t())letor_=nary(or_t())letand_=nary(and_t())letimply=binary(implies_t())letequiv=binary(equiv_t())(** {2 Arithmetic} *)letuminus=unary(uminus_t())letadd=binary(add_t())letsub=binary(sub_t())letmult=binary(mult_t())letlt=binary(lt_t())letleq=binary(leq_t())letgt=binary(gt_t())letgeq=binary(geq_t())(* {2 Binders} *)letpi=mk_bindPiletletin=mk_bindLetletexists=mk_bindExletforall=mk_bindAllletlambda=mk_bindFunletchoice=mk_bindChoiceletdescription=mk_bindDescriptionletfun_ty=mk_bindArrowletarrow?locargret=fun_ty?loc[arg]ret(* {2 Free variables} *)moduleS=Set.Make(Id)letrecfree_varsacct=matcht.termwith|Builtin_->acc|Colon(t,t')->free_vars(free_varsacct)t'|Symboli->ifi.Id.ns=Id.VarthenS.addiaccelseacc|App(t,l)->List.fold_leftfree_vars(free_varsacct)l|Binder(_,l,t)->lets=free_varsS.emptytinletbound=List.fold_leftfree_varsS.emptylinlets'=S.filter(funx->not(S.memxbound))sinS.unionaccs'|Match(t,l)->letacc=List.fold_left(funacc(pattern,branch)->lets=free_varsS.emptybranchinletbound=free_varsS.emptypatterninlets'=S.filter(funx->not(S.memxbound))sinS.unions'acc)acclinfree_varsacctletfvt=S.elements(free_varsS.emptyt)(* {2 Wrappers for dimacs} *)letatom?loci=lets=Printf.sprintf"#%d"(absi)inifi>=0thenconst?locId.(mkTerms)elsenot_?loc(const?locId.(mkTerms))(* {2 Wrappers for smtlib} *)letint?locs=const?locId.(mkTerms)letreal=intlethexa=intletbinary=intletsexpr?locl=apply?loc(constId.(mkAttr"$data"))l(* {2 Wrappers for tptp} *)letrat=intletdistinct=constletvar?locid=const?loc{idwithId.ns=Id.Var}letite?locabc=apply?loc(ite_t?loc())[a;b;c]letsequent?lochypsgoals=lethyps_t=apply?loc(or_t?loc())hypsinletgoals_t=apply?loc(and_t?loc())goalsinapply?loc(sequent_t?loc())[hyps_t;goals_t]letunion?locab=apply?loc(union_t?loc())[a;b]letproduct?locab=apply?loc(product_t?loc())[a;b]letsubtype?locab=apply?loc(subtype_t?loc())[a;b](* {2 Wrappers for Zf} *)letquoted?locname=const?locId.({name;ns=Attr})(* {2 Term traversal} *)type'amapper={symbol:'amapper->attr:tlist->loc:locationoption->Id.t->'a;builtin:'amapper->attr:tlist->loc:locationoption->builtin->'a;colon:'amapper->attr:tlist->loc:locationoption->t->t->'a;app:'amapper->attr:tlist->loc:locationoption->t->tlist->'a;binder:'amapper->attr:tlist->loc:locationoption->binder->tlist->t->'a;pmatch:'amapper->attr:tlist->loc:locationoption->t->(t*t)list->'a;}letmapmappert=letwrapf=fmapper~attr:t.attr~loc:t.locinmatcht.termwith|Symbolid->wrapmapper.symbolid|Builtinb->wrapmapper.builtinb|Colon(u,v)->wrapmapper.colonuv|App(f,args)->wrapmapper.appfargs|Binder(b,vars,body)->wrapmapper.binderbvarsbody|Match(e,l)->wrapmapper.pmatchelletid_mapper={symbol=(funm~attr~locid->set_attrs(List.map(mapm)attr)@@const?locid);builtin=(funm~attr~locb->set_attrs(List.map(mapm)attr)@@builtin?locb());colon=(funm~attr~locuv->set_attrs(List.map(mapm)attr)@@colon?loc(mapmu)(mapmv));app=(funm~attr~locfargs->set_attrs(List.map(mapm)attr)@@apply?loc(mapmf)(List.map(mapm)args));binder=(funm~attr~locbvarsbody->set_attrs(List.map(mapm)attr)@@mk_bind?locbvars(mapmbody));pmatch=(funm~attr~locel->set_attrs(List.map(mapm)attr)@@match_?loc(mapme)(List.map(fun(pat,body)->(mapmpat,mapmbody))l));}