123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357(** Pretty-printing the parser-level AST.
This module defines functions that allow printing elements of syntax found
in the parser-level abstract syntax. This is used, for example, to print a
file in the Lambdapi syntax, given the AST obtained when parsing a file in
the Dedukti syntax. *)openLplibopenBaseopenCommonopenPosopenSyntaxopenFormatopenCore(** Keywords table. *)letkeyword_table=Hashtbl.create59letis_keyword:string->bool=Hashtbl.memkeyword_tablelet_=letopenLpLexerinList.iter(fun(s,k)->Hashtbl.addkeyword_tablesk)["abort",ABORT;"admit",ADMIT;"admitted",ADMITTED;"apply",APPLY;"as",AS;"assert",ASSERTfalse;"assertnot",ASSERTtrue;"associative",ASSOCIATIVE;"assume",ASSUME;"begin",BEGIN;"builtin",BUILTIN;"commutative",COMMUTATIVE;"compute",COMPUTE;"constant",CONSTANT;"debug",DEBUG;"end",END;"fail",FAIL;"flag",FLAG;"generalize",GENERALIZE;"have",HAVE;"in",IN;"induction",INDUCTION;"inductive",INDUCTIVE;"infix",INFIX;"injective",INJECTIVE;"left",SIDE(Pratter.Left);"let",LET;"off",SWITCH(false);"on",SWITCH(true);"opaque",OPAQUE;"open",OPEN;"postfix",POSTFIX;"prefix",PREFIX;"print",PRINT;"private",PRIVATE;"proofterm",PROOFTERM;"protected",PROTECTED;"prover",PROVER;"prover_timeout",PROVER_TIMEOUT;"quantifier",QUANTIFIER;"refine",REFINE;"reflexivity",REFLEXIVITY;"require",REQUIRE;"rewrite",REWRITE;"right",SIDE(Pratter.Right);"rule",RULE;"sequential",SEQUENTIAL;"simplify",SIMPLIFY;"solve",SOLVE;"symbol",SYMBOL;"symmetry",SYMMETRY;"type",TYPE_QUERY;"TYPE",TYPE_TERM;"unif_rule",UNIF_RULE;"verbose",VERBOSE;"why3",WHY3;"with",WITH]letraw_ident:stringpp=funppfs->ifis_keywordsthenoutppf"{|%s|}"selsestringppfsletident:p_identpp=funppf{elt;_}->raw_identppfeltletmeta_ident:p_meta_identpp=funppf{elt;_}->outppf"%d"eltletparam_id:p_identoptionpp=funppfidopt->matchidoptwith|Some(id)->outppf"%a"identid|None->outppf"_"letparam_ids:p_identoptionlistpp=List.ppparam_id" "letraw_path:Path.tpp=List.ppraw_ident"."letpath:p_pathpp=funppf{elt;_}->raw_pathppfeltletqident:p_qidentpp=funppf{elt=(mp,s);_}->matchmpwith|[]->raw_identppfs|_::_->outppf"%a.%a"raw_pathmpraw_idents(* ends with a space *)letmodifier:p_modifierpp=funppf{elt;_}->matcheltwith|P_expo(e)->Print.expoppfe|P_mstrat(s)->Print.match_stratppfs|P_prop(p)->Print.propppfp|P_opaq->outppf"opaque "(* ends with a space if the list is not empty *)letmodifiers:p_modifierlistpp=List.ppmodifier""(** The possible priority levels are [`Func] (top level, including abstraction
and product), [`Appl] (application) and [`Atom] (smallest priority). *)typepriority=[`Func|`Appl|`Atom]letrecterm:p_termpp=funppft->letempty_context=reftrueinletrecatomppft=pp`Atomppftandapplppft=pp`Applppftandfuncppft=pp`Funcppftandpppriorityppft=letenvppfts=matchtswith|None->()|Some[||]when!empty_context->()|Somets->outppf".[%a]"(Array.ppfunc"; ")tsinmatch(t.elt,priority)with|(P_Type,_)->outppf"TYPE"|(P_Iden(qid,false),_)->outppf"%a"qidentqid|(P_Iden(qid,true),_)->outppf"@@%a"qidentqid|(P_Wild,_)->outppf"_"|(P_Meta(mid,ts),_)->outppf"?%a%a"meta_identmidenv(Somets)|(P_Patt(idopt,ts),_)->outppf"$%a%a"param_ididoptenvts|(P_Appl(t,u),`Appl)|(P_Appl(t,u),`Func)->outppf"@[%a@ %a@]"appltatomu|(P_Arro(a,b),`Func)->outppf"@[%a@ → %a@]"applafuncb|(P_Abst(xs,t),`Func)->letfn(ids,_,_)=List.for_all((=)None)idsinletec=!empty_contextinempty_context:=ec&&List.for_allfnxs;outppf"@[<2>λ%a,@ %a@]"params_listxsfunct;empty_context:=ec|(P_Prod(xs,b),`Func)->outppf"@[<2>Π%a,@ %a@]"params_listxsfuncb|(P_LLet(x,xs,a,t,u),`Func)->outppf"@[@[<hv2>let @[<2>%a%a%a@] ≔@ %a@ @]in@ %a@]"identxparams_listxstypafunctfuncu|(P_NLit(i),_)->outppf"%i"i|(P_Wrap(t),_)->outppf"(@[<hv2>%a@])"funct|(P_Expl(t),_)->outppf"[@[<hv2>%a@]]"funct|(_,_)->outppf"(@[<hv2>%a@])"functinletrectoplevelppft=matcht.eltwith|P_Abst(xs,t)->outppf"@[<2>λ%a,@ %a@]"params_listxstoplevelt|P_Prod(xs,b)->outppf"@[<2>Π%a,@ %a@]"params_listxstoplevelb|P_Arro(a,b)->outppf"@[%a@ → %a@]"applatoplevelb|P_LLet(x,xs,a,t,u)->outppf"@[@[<hv2>let @[<2>%a%a%a@] ≔@ %a@ @]in@ %a@]"identxparams_listxstypatoplevelttoplevelu|_->funcppftintoplevelppftandparams:p_paramspp=funppf(ids,t,b)->ifbthenoutppf"@[[@,@[<2>%a%a@]@,]@]"param_idsidstyptelsematchtwith|Somet->outppf"@[(@,@[<2>%a : %a@]@,)@]"param_idsidstermt|None->outppf"@[@,@[<2>%a@]@,@]"param_idsids(* starts with a space if the list is not empty *)andparams_list:p_paramslistpp=funppf->List.iter(outppf"@ %a"params)(* starts with a space if <> None *)andtyp:p_termoptionpp=funppft->Option.iter(outppf"@ : %a"term)tletrule:string->p_rulepp=funkwppf{elt=(l,r);_}->outppf"%s %a ↪ %a"kwtermltermrletinductive:string->p_inductivepp=letconsppf(id,a)=outppf"@,| %a : %a"identidtermainfunkwppf{elt=(id,a,cs);_}->outppf"@[<v>%s %a : %a ≔%a@]"kwidentidterma(List.ppcons"")csletequiv:(p_term*p_term)pp=funppf(l,r)->outppf"%a ≡ %a"termltermr(** [unpack eqs] transforms a p_term of the form [LpLexer.cons
(LpLexer.equiv t u) (LpLexer.cons (LpLexer.equiv v w) ...)] into a
list [[(t,u); (v,w); ...]]. See unif_rule.ml. *)letrecunpack:p_term->(p_term*p_term)list=funeqs->letis(p,s)id=p=Unif_rule.path&&s=id.Term.sym_nameinmatchSyntax.p_get_argseqswith|({elt=P_Iden({elt;_},_);_},[v;w])->ifiseltUnif_rule.consthenmatchSyntax.p_get_argsvwith|({elt=P_Iden({elt;_},_);_},[t;u])wheniseltUnif_rule.equiv->(t,u)::unpackw|_->assertfalseelseifiseltUnif_rule.equivthen[(v,w)]elseassertfalse|_->assertfalseletunif_rule:p_rulepp=funppf{elt=(l,r);_}->letlhs=matchSyntax.p_get_argslwith|(_,[t;u])->(t,u)|_->assertfalseinoutppf"%a ↪ [%a]"equivlhs(List.ppequiv"; ")(unpackr)letproof_end:p_proof_endpp=funppfpe->outppf(matchpe.eltwith|P_proof_end->"end"|P_proof_admitted->"admitted"|P_proof_abort->"abort")letrw_patt:p_rw_pattpp=funppfp->matchp.eltwith|Rw_Term(t)->termppft|Rw_InTerm(t)->outppf"in %a"termt|Rw_InIdInTerm(x,t)->outppf"in %a in %a"identxtermt|Rw_IdInTerm(x,t)->outppf"%a in %a"identxtermt|Rw_TermInIdInTerm(u,(x,t))->outppf"%a in %a in %a"termuidentxtermt|Rw_TermAsIdInTerm(u,(x,t))->outppf"%a as %a in %a"termuidentxtermtletassertion:p_assertionpp=funppfa->matchawith|P_assert_typing(t,a)->outppf"@[%a@ : %a@]"termtterma|P_assert_conv(t,u)->outppf"@[%a@ ≡ %a@]"termttermuletquery:p_querypp=funppf{elt;_}->matcheltwith|P_query_assert(true,a)->outppf"assertnot ⊢ %a"assertiona|P_query_assert(false,a)->outppf"assert ⊢ %a"assertiona|P_query_debug(true,s)->outppf"debug +%s"s|P_query_debug(false,s)->outppf"debug -%s"s|P_query_flag(s,b)->outppf"flag \"%s\" %s"s(ifbthen"on"else"off")|P_query_infer(t,_)->outppf"type %a"termt|P_query_normalize(t,_)->outppf"compute %a"termt|P_query_provers->outppf"prover \"%s\""s|P_query_prover_timeoutn->outppf"prover_timeout %d"n|P_query_printNone->outppf"print"|P_query_print(Someqid)->outppf"print %a"qidentqid|P_query_proofterm->outppf"proofterm"|P_query_verbosei->outppf"verbose %i"ilettactic:p_tacticpp=funppf{elt;_}->beginmatcheltwith|P_tac_admit->outppf"admit"|P_tac_applyt->outppf"apply %a"termt|P_tac_assumeids->outppf"assume%a"(List.pp(unit" "|+param_id)"")ids|P_tac_fail->outppf"fail"|P_tac_generalizeid->outppf"generalize %a"identid|P_tac_have(id,t)->outppf"have %a: %a"identidtermt|P_tac_induction->outppf"induction"|P_tac_queryq->queryppfq|P_tac_refinet->outppf"refine %a"termt|P_tac_refl->outppf"reflexivity"|P_tac_rewrite(b,p,t)->letdirppfb=ifnotbthenoutppf" left"inletpatppfp=outppf" .[%a]"rw_pattpinoutppf"rewrite%a%a %a"dirb(Option.pppat)ptermt|P_tac_simplNone->outppf"simplify"|P_tac_simpl(Someqid)->outppf"simplify %a"qidentqid|P_tac_solve->outppf"solve"|P_tac_sym->outppf"symmetry"|P_tac_why3p->letproverppfs=outppf" \"%s\""sinoutppf"why3%a"(Option.ppprover)pend(* starts with a space if distinct from [Pratter.Neither] *)letside:Pratter.associativitypp=funppfa->outppf(matchawith|Pratter.Neither->""|Pratter.Left->" left"|Pratter.Right->" right")letnotation:Sign.notationpp=funppf->function|Infix(a,p)->outppf"infix%a %f"sideap|Prefixp->outppf"prefix %f"p|Postfixp->outppf"postfix %f"p|Quant->outppf"quantifier"|Zero|Succ->()letrecsubproof:p_subproofpp=funppfsp->outppf"{@[<hv2>@ %a@ @]}"proofstepsspandsubproofs:p_subprooflistpp=funppfspl->outppf"@[<hv>%a@]"(pp_print_list~pp_sep:pp_print_spacesubproof)splandproofsteps:p_proofsteplistpp=funppfpsl->pp_print_list~pp_sep:pp_print_spaceproofstepppfpslandproofstep:p_proofsteppp=funppf(Tactic(t,spl))->outppf"@[<hv2>%a@,%a;@]"tactictsubproofssplletproof:(p_proof*p_proof_end)pp=funppf(p,pe)->outppf"begin@ @[<hv2>%a@]@ %a"(funppf->function|[block]->proofstepsppfblock(* No braces for a single toplevel block *)|blocks->subproofsppfblocks)pproof_endpeletcommand:p_commandpp=funppf{elt;_}->beginmatcheltwith|P_builtin(s,qid)->outppf"@[builtin \"%s\"@ ≔ %a@]"sqidentqid|P_inductive(_,_,[])->assertfalse(* not possible *)|P_inductive(ms,xs,i::il)->letwith_indppfi=outppf"@,%a"(inductive"with")iinoutppf"@[<v>@[%a%a@]%a%a@]"modifiersms(List.ppparams" ")xs(inductive"inductive")i(List.ppwith_ind"")il|P_notation(qid,n)->outppf"notation %a %a"qidentqidnotationn|P_openps->outppf"open %a"(List.pppath" ")ps|P_queryq->queryppfq|P_require(b,ps)->outppf"require%a %a"(pp_ifb(unit" open"))()(List.pppath" ")ps|P_require_as(p,i)->outppf"@[require %a@ as %a@]"pathpidenti|P_rules[]->assertfalse(* not possible *)|P_rules(r::rs)->letwith_ruleppfr=outppf"@.%a"(rule"with")rinrule"rule"ppfr;List.iter(with_ruleppf)rs|P_symbol{p_sym_mod;p_sym_nam;p_sym_arg;p_sym_typ;p_sym_trm;p_sym_prf;p_sym_def}->beginoutppf"@[<v>@[<2>%asymbol %a%a%a%a%a@]%a@]"modifiersp_sym_modidentp_sym_namparams_listp_sym_argtypp_sym_typ(pp_ifp_sym_def(unit"@ ≔"))()(Option.pp(sep" "|+term))p_sym_trm(Option.pp(unit"@,"|+proof))p_sym_prfend|P_unif_ruleur->outppf"unif_rule %a"unif_ruleurend;outppf";"letast:astpp=funppf->Stream.iter((command+|unit"@.")ppf)