123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684(* This file is free software, part of dolmen. See file "LICENSE" for more information. *)typelocation=Loc.ttypebuiltin=|Wildcard|Ttype|Unit|Void|Prop|Bool|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 *)|Real(* Arithmetic type for reals *)|Minus(* arithmetic unary minus *)|Add|Sub|Mult(* arithmetic operators *)|Div|Mod(* arithmetic division *)|Int_pow|Real_pow(* arithmetic power (it's over 9000!) *)|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) *)|Pi|Sigma(* Higher-order constant to encode forall and exists quantifiers *)|Not(* Propositional negation *)|And|Or(* Conjunction and disjunction *)|Nand|Xor|Nor(* Advanced propositional connectives *)|Imply|Implied(* Implication and left implication *)|Equiv(* Equivalence *)|Bitvofint(* Bitvector type (with given length) *)|Bitv_extractofint*int(* Bitvector extraction *)|Bitv_concat(* Bitvector concatenation *)|Array_get|Array_set(* array operations *)|Adt_check|Adt_project(* adt operations *)|Record|Record_with|Record_access(* record operations *)|Maps_to|In_intervalofbool*bool|Check|Cut(* alt-ergo builtins *)|Sexpr(* smtlib builtin for s-exprs *)typebinder=|All|Ex|Pi|Arrow|Let_seq(* sequential let-binding *)|Let_par(* parrallel let-binding *)|Fun(* function parameter binding *)|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:location;}(* Printing info *)letinfix_builtin=function|Add|Sub|Lt|Leq|Gt|Geq|Eq|And|Or|Nand|Xor|Nor|Imply|Implied|Equiv|Product|Union|Sequent|Subtype|Adt_check|Adt_project|Record_access->true|Distinct->true|_->falseletbuiltin_to_string=function|Wildcard->"_"|Ttype->"Ttype"|Unit->"unit"|Void->"()"|Prop->"Prop"|Bool->"Bool"|True->"⊤"|False->"⊥"|Eq->"=="|Distinct->"!="|Ite->"ite"|Sequent->"⊢"|Int->"ℤ"|Real->"ℝ"|Minus->"-"|Add->"+"|Sub->"-"|Mult->"×"|Div->"÷"|Mod->"mod"|Int_pow->"**"|Real_pow->"**."|Lt->"<"|Leq->"≤"|Gt->">"|Geq->"≥"|Subtype->"⊂"|Product->"*"|Union->"∪"|Pi->"Π"|Sigma->"Σ"|Not->"¬"|And->"∧"|Or->"∨"|Nand->"⊼"|Xor->"⊻"|Nor->"V"|Imply->"⇒"|Implied->"⇐"|Equiv->"⇔"|Bitvi->Printf.sprintf"bitv(%d)"i|Bitv_extract(i,j)->Printf.sprintf"bitv_extract(%d;%d)"ij|Bitv_concat->"bitv_concat"|Array_get->"get"|Array_set->"set"|Adt_check->"?"|Adt_project->"#"|Record->"record"|Record_with->"record_with"|Record_access->"."|Maps_to->"↦"|In_interval(b,b')->letbracket=functiontrue->"]"|false->"["inPrintf.sprintf"in_interval%s%s"(bracketb)(bracket(notb'))|Check->"check"|Cut->"cut"|Sexpr->"sexpr"letbinder_to_string=function|All->"∀"|Ex->"∃"|Pi->"Π"|Arrow->""|Let_seq|Let_par->"let"|Fun->"λ"|Choice->"ε"|Description->"@"letbinder_sep_string=function|All|Ex|Pi|Let_seq|Fun|Choice|Description->""|Let_par->" and"|Arrow->" →"letbinder_end_string=function|All|Ex|Pi|Choice|Description->"."|Fun->"=>"|Let_seq|Let_par->"in"|Arrow->"→"(*
(* Debug printing *)
let pp_builtin b builtin =
Printf.bprintf b "%s" (builtin_to_string builtin)
let pp_binder b binder =
Printf.bprintf b "%s" (binder_to_string binder)
let rec pp_descr b = function
| Symbol id -> Id.pp b id
| Builtin s -> pp_builtin b s
| Colon (u, v) -> Printf.bprintf b "%a : %a" pp u pp v
| App ({ term = Builtin sep ; _ }, l) when infix_builtin sep ->
Misc.pp_list ~pp_sep:pp_builtin ~sep ~pp b l
| App (f, l) ->
Printf.bprintf b "%a(%a)" pp f
(Misc.pp_list ~pp_sep:Buffer.add_string ~sep:"," ~pp) l
| Binder (q, l, e) ->
let sep = binder_sep_string q ^ " " in
Printf.bprintf b "%a %a %s %a" pp_binder q
(Misc.pp_list ~pp_sep:Buffer.add_string ~sep ~pp) l
(binder_end_string q) pp e
| Match (t, l) ->
Printf.bprintf b "match %a with %a"
pp t (Misc.pp_list ~pp_sep:Buffer.add_string ~sep:" | " ~pp:pp_match_case) l
and pp_match_case b (pattern, branch) =
Printf.bprintf b "%a => %a" pp pattern pp branch
and pp b = function
| { term = (Symbol _) as d; _ }
| { term = (Builtin _) as d; _ } -> pp_descr b d
| e -> Printf.bprintf b "(%a)" pp_descr e.term
*)(* Pretty-printing *)letprint_locs=falseletprint_locfmtloc=ifprint_locsthenFormat.fprintffmt"[%a]"Loc.print_compactlocletprint_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=Builtinb;_},l)wheninfix_builtinb->letpp_sepfmt()=Format.fprintffmt" %a@ "print_builtinbinFormat.pp_print_list~pp_sepprintfmtl|App(f,[])->Format.fprintffmt"%a"printf|App(f,l)->letpp_sep=Format.pp_print_spaceinFormat.fprintffmt"%a@ %a"printf(Format.pp_print_list~pp_sepprint)l|Binder(q,l,e)->letpp_sepfmt()=Format.fprintffmt"%s@ "(binder_sep_stringq)inFormat.fprintffmt"%a@ %a@ %s@ %a"print_binderq(Format.pp_print_list~pp_sepprint)l(binder_end_stringq)printe|Match(t,l)->letpp_sepfmt()=Format.fprintffmt" | "inFormat.fprintffmt"match %a with %a"printt(Format.pp_print_list~pp_sepprint_match_case)landprint_match_casefmt(pattern,branch)=Format.fprintffmt"%a => %a"printpatternprintbranchandprint_attrfmt=function|[]->()|a::r->Format.fprintffmt"{%a}@,%a"printaprint_attrrandprintfmt=function|{term=(Symbol_)asd;attr;loc;}|{term=(Builtin_)asd;attr;loc;}->Format.fprintffmt"@[<hov 2>%a@,%a@,%a@]"print_descrdprint_loclocprint_attrattr|e->Format.fprintffmt"@[<hov 2>(%a)@,%a@,%a@]"print_descre.termprint_loce.locprint_attre.attr(* 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'->Stdlib.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')->beginmatchStdlib.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 *)let[@inlinealways]add_attrat={twithattr=a::t.attr}let[@inlinealways]add_attrslt={twithattr=l@t.attr}let[@inlinealways]set_attrslt=assert(t.attr=[]);{twithattr=l}(* Make a term from its description *)let[@inlinealways]make?(loc=Loc.no_loc)?(attr=[])term={term;attr;loc;}let[@inlinealways]builtinb?loc()=make?loc(Builtinb)(* Internal shortcut to make a formula with bound variables. *)let[@inlinealways]mk_bindbinder?locvarst=make?loc(Binder(binder,vars,t))(* Attach an attribute list to a term *)letannot?(loc=Loc.no_loc)tl={twithattr=t.attr@l;loc}(* Create a constant and/or variable, that is a leaf
of the term AST. *)let[@inlinealways]const?locid=make?loc(Symbolid)(* Apply a term to a list of terms. *)let[@inlinealways]apply?locfargs=make?loc(App(f,args))let[@inlinealways]match_?loctl=make?loc(Match(t,l))(* Juxtapose two terms, usually a term and its type.
Used mainly for typed variables, or type annotations. *)let[@inlinealways]colon?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=builtinImpliedletpi_t=builtinPiletsigma_t=builtinSigmaletvoid=builtinVoidlettrue_=builtinTrueletfalse_=builtinFalseletwildcard=builtinWildcardletite_t=builtinIteletsequent_t=builtinSequentletunion_t=builtinUnionletproduct_t=builtinProductletsubtype_t=builtinSubtypelettType=builtinTtypeletprop=builtinPropletbool=builtinBoolletdata_t?loc()=const?locId.(mkAttr"$data")letty_unit=builtinUnitletty_int=builtinIntletty_real=builtinRealletuminus_t=builtinMinusletadd_t=builtinAddletsub_t=builtinSubletmult_t=builtinMultletdiv_t=builtinDivletmod_t=builtinModletint_pow_t=builtinInt_powletreal_pow_t=builtinReal_powletlt_t=builtinLtletleq_t=builtinLeqletgt_t=builtinGtletgeq_t=builtinGeqletarray_get_t=builtinArray_getletarray_set_t=builtinArray_setletbitv_ti=builtin(Bitvi)letbitv_concat_t=builtinBitv_concatletbitv_extract_tij=builtin(Bitv_extract(i,j))letadt_check_t=builtinAdt_checkletadt_project_t=builtinAdt_projectletrecord_t=builtinRecordletrecord_with_t=builtinRecord_withletrecord_access_t=builtinRecord_accessletsexpr_t=builtinSexprletnaryt=(fun?locl->apply?loc(t?loc())l)letunaryt=(fun?locx->apply?loc(t?loc())[x])letbinaryt=(fun?locxy->apply?loc(t?loc())[x;y])lettertiaryt=(fun?locxyz->apply?loc(t?loc())[x;y;z])(* {2 Usual functions} *)leteq=binaryeq_tletneq=naryneq_t(* {2 Logical connectives} *)letnot_=unarynot_tletor_=naryor_tletand_=naryand_tletxor=binaryxor_tletimply=binaryimplies_tletequiv=binaryequiv_t(** {2 Arithmetic} *)letuminus=unaryuminus_tletadd=binaryadd_tletsub=binarysub_tletmult=binarymult_tletdiv=binarydiv_tletmod_=binarymod_tletint_pow=binaryint_pow_tletreal_pow=binaryreal_pow_tletlt=binarylt_tletleq=binaryleq_tletgt=binarygt_tletgeq=binarygeq_t(* {2 Arrays} *)letarray_get=binaryarray_get_tletarray_set=tertiaryarray_set_t(* {2 Bitvectors} *)letty_bitv?loci=apply?loc(bitv_ti?loc())[]letbitv_extract?loctij=apply?loc(bitv_extract_tij?loc())[t]letbitv_concat=binarybitv_concat_t(* {2 ADTs} *)letadt_check?loctid=letx=const?locidinapply?loc(adt_check_t?loc())[t;x]letadt_project?loctid=letx=const?locidinapply?loc(adt_project_t?loc())[t;x](** {2 Records} *)letrecord=naryrecord_tletrecord_with?loctl=naryrecord_with_t?loc(t::l)letrecord_access?loctid=letx=const?locidinbinaryrecord_access_t?loctx(* {2 Binders} *)letpi=mk_bindPiletletin=mk_bindLet_seqletletand=mk_bindLet_parletexists=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=Namespace.VarthenS.addiaccelseacc|App(t,l)->List.fold_leftfree_vars(free_varsacct)l|Binder(Arrow,l,t)->List.fold_leftfree_vars(free_varsacct)l|Binder(_,l,t)->lets=free_varsS.emptytinletbound,free=List.fold_leftfree_vars_bound(S.empty,S.empty)linlets'=S.filter(funx->not(S.memxbound))sinS.unionacc(S.unions'free)|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_varsacctandfree_vars_bound(bound,free)t=matcht.termwith|Colon(v,ty)->free_varsboundv,free_varsfreety|_->free_varsboundt,freeletfvt=S.elements(free_varsS.emptyt)(* {2 Wrappers for alt-ergo} *)letbitv?locs=const?locId.(mk(ValueBitvector)s)letcut=unary(builtinCut)letcheck=unary(builtinCheck)lettrigger=and_lettriggers_t=Id.(mkAttr"triggers")lettriggers?loct=function|[]->t|l->leta=apply?loc(const?loctriggers_t)linannot?loct[a]letfilters_t=Id.(mkAttr"filters")letfilters?loct=function|[]->t|l->leta=apply?loc(const?locfilters_t)linannot?loct[a]lettracked?locidt=leta=const?locidinannot?loct[a]letmaps_to?locidt=leta=const?locidinbinary(builtinMaps_to)?locatletin_interval?loct(lb,ls)(rb,rs)=tertiary(builtin(In_interval(ls,rs)))?loctlbrb(* {2 Wrappers for dimacs} *)letatom?loci=lets=Printf.sprintf"#%d"(absi)inifi>=0thenconst?locId.(mkTerms)elsenot_?loc(const?locId.(mkTerms))(* {2 Wrappers for smtlib} *)letstr?locs=const?locId.(mk(ValueString)s)letint?locs=const?locId.(mk(ValueInteger)s)letreal?locs=const?locId.(mk(ValueReal)s)lethexa?locs=const?locId.(mk(ValueHexadecimal)s)letbinary?locs=const?locId.(mk(ValueBinary)s)letsexpr?locl=apply?loc(sexpr_t?loc())lletpar?locvarst=letvars=List.map(funv->colon?locv(tType?loc()))varsinforall?locvarst(* {2 Wrappers for tptp} *)letrat?locs=const?locId.(mk(ValueRational)s)letdistinct=constletvar?locid=const?loc{idwithId.ns=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?loc(Id.mkAttrname)(* {2 Term traversal} *)type'amapper={symbol:'amapper->attr:tlist->loc:location->Id.t->'a;builtin:'amapper->attr:tlist->loc:location->builtin->'a;colon:'amapper->attr:tlist->loc:location->t->t->'a;app:'amapper->attr:tlist->loc:location->t->tlist->'a;binder:'amapper->attr:tlist->loc:location->binder->tlist->t->'a;pmatch:'amapper->attr:tlist->loc:location->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~locb(List.map(mapm)vars)(mapmbody));pmatch=(funm~attr~locel->set_attrs(List.map(mapm)attr)@@match_~loc(mapme)(List.map(fun(pat,body)->(mapmpat,mapmbody))l));}letunit_mapper={symbol=(funm~attr~loc:__->List.iter(mapm)attr);builtin=(funm~attr~loc:__->List.iter(mapm)attr);colon=(funm~attr~loc:_uv->List.iter(mapm)attr;mapmu;mapmv);app=(funm~attr~loc:_fargs->List.iter(mapm)attr;mapmf;List.iter(mapm)args);binder=(funm~attr~loc:__varsbody->List.iter(mapm)attr;List.iter(mapm)vars;mapmbody);pmatch=(funm~attr~loc:_el->List.iter(mapm)attr;mapme;List.iter(fun(pat,body)->mapmpat;mapmbody)l);}