1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openPpopenCErrorsopenUtilopenNamesopenConstropenContextopenEnvironopenEvdopenConstrexternopenPpconstropenDeclarationsmoduleRelDecl=Context.Rel.DeclarationmoduleNamedDecl=Context.Named.DeclarationmoduleCompactedDecl=Context.Compacted.Declaration(* This is set on by proofgeneral proof-tree mode. But may be used for
other purposes *)letprint_goal_tag_opt_name=["Printing";"Goal";"Tags"]let{Goptions.get=should_tag}=Goptions.declare_bool_option_and_ref~key:print_goal_tag_opt_name~value:false()let{Goptions.get=should_unfoc}=Goptions.declare_bool_option_and_ref~key:["Printing";"Unfocused"]~value:false()let{Goptions.get=should_gname}=Goptions.declare_bool_option_and_ref~key:["Printing";"Goal";"Names"]~value:false()letprint_goal_names=should_gname(* for export *)(**********************************************************************)(** Terms *)(* [goal_concl_style] means that all names of goal/section variables
and all names of rel variables (if any) in the given env and all short
names of global definitions of the current module must be avoided while
printing bound variables.
Otherwise, short names of global definitions are printed qualified
and only names of goal/section variables and rel names that do
_not_ occur in the scope of the binder to be printed are avoided. *)letpr_econstr_n_env?inctx?scopeenvsigmant=pr_constr_expr_nenvsigman(extern_constr?inctx?scopeenvsigmat)letpr_econstr_env?inctx?scopeenvsigmat=pr_constr_exprenvsigma(extern_constr?inctx?scopeenvsigmat)letpr_leconstr_env?inctx?scopeenvsigmat=Ppconstr.pr_lconstr_exprenvsigma(extern_constr?inctx?scopeenvsigmat)letpr_constr_n_env?inctx?scopeenvsigmanc=pr_econstr_n_env?inctx?scopeenvsigman(EConstr.of_constrc)letpr_constr_env?inctx?scopeenvsigmac=pr_econstr_env?inctx?scopeenvsigma(EConstr.of_constrc)letpr_lconstr_env?inctx?scopeenvsigmac=pr_leconstr_env?inctx?scopeenvsigma(EConstr.of_constrc)letpr_open_lconstr_env?inctx?scopeenvsigma(_,c)=pr_leconstr_env?inctx?scopeenvsigmacletpr_open_constr_env?inctx?scopeenvsigma(_,c)=pr_econstr_env?inctx?scopeenvsigmacletpr_constr_under_binders_env_genprenvsigma(ids,c)=(* Warning: clashes can occur with variables of same name in env but *)(* we also need to preserve the actual names of the patterns *)(* So what to do? *)letassums=List.map(funid->(make_annot(Nameid)Sorts.Relevant,(* dummy *)mkProp))idsinpr(Termops.push_rels_assumassumsenv)sigmacletpr_constr_under_binders_env=pr_constr_under_binders_env_genpr_econstr_envletpr_lconstr_under_binders_env=pr_constr_under_binders_env_genpr_leconstr_envletpr_etype_env?goal_concl_styleenvsigmat=pr_constr_exprenvsigma(extern_type?goal_concl_styleenvsigmat)letpr_letype_env?goal_concl_styleenvsigma?impargst=pr_lconstr_exprenvsigma(extern_type?goal_concl_styleenvsigma?impargst)letpr_type_env?goal_concl_styleenvsigmac=pr_etype_env?goal_concl_styleenvsigma(EConstr.of_constrc)letpr_ltype_env?goal_concl_styleenvsigma?impargsc=pr_letype_env?goal_concl_styleenvsigma?impargs(EConstr.of_constrc)letpr_ljudge_envenvsigmaj=(pr_leconstr_envenvsigmaj.uj_val,pr_leconstr_envenvsigmaj.uj_type)letpr_lglob_constr_envenvsigmac=pr_lconstr_exprenvsigma(extern_glob_constr(extern_envenvsigma)c)letpr_glob_constr_envenvsigmac=pr_constr_exprenvsigma(extern_glob_constr(extern_envenvsigma)c)letpr_closed_glob_n_env?goal_concl_style?inctx?scopeenvsigmanc=pr_constr_expr_nenvsigman(extern_closed_glob?goal_concl_style?inctx?scopeenvsigmac)letpr_closed_glob_env?goal_concl_style?inctx?scopeenvsigmac=pr_constr_exprenvsigma(extern_closed_glob?goal_concl_style?inctx?scopeenvsigmac)letpr_lconstr_pattern_envenvsigmac=pr_lconstr_pattern_exprenvsigma(extern_constr_pattern(Termops.names_of_rel_contextenv)sigmac)letpr_constr_pattern_envenvsigmac=pr_constr_pattern_exprenvsigma(extern_constr_pattern(Termops.names_of_rel_contextenv)sigmac)letpr_cases_patternt=pr_cases_pattern_expr(extern_cases_patternNames.Id.Set.emptyt)letpr_sortsigmas=pr_sort_expr(extern_sortsigmas)let()=Termops.Internal.set_print_constr(funenvsigmat->pr_lconstr_exprenvsigma(extern_constrenvsigmat))letpr_in_commentx=str"(* "++x++str" *)"(** Term printers resilient to [Nametab] errors *)(** When the nametab isn't up-to-date, the term printers above
could raise [Not_found] during [Nametab.shortest_qualid_of_global].
In this case, we build here a fully-qualified name based upon
the kernel modpath and label of constants, and the idents in
the [mutual_inductive_body] for the inductives and constructors
(needs an environment for this). *)letid_of_globalenv=letopenGlobRefinfunction|ConstRefkn->Label.to_id(Constant.labelkn)|IndRef(kn,0)->Label.to_id(MutInd.labelkn)|IndRef(kn,i)->(Environ.lookup_mindknenv).mind_packets.(i).mind_typename|ConstructRef((kn,i),j)->(Environ.lookup_mindknenv).mind_packets.(i).mind_consnames.(j-1)|VarRefv->vletrecdirpath_of_mp=function|MPfilesl->sl|MPbounduid->DirPath.make[MBId.to_iduid]|MPdot(mp,l)->Libnames.add_dirpath_suffix(dirpath_of_mpmp)(Label.to_idl)letdirpath_of_global=letopenGlobRefinfunction|ConstRefkn->dirpath_of_mp(Constant.modpathkn)|IndRef(kn,_)|ConstructRef((kn,_),_)->dirpath_of_mp(MutInd.modpathkn)|VarRef_->DirPath.emptyletqualid_of_global?locenvr=Libnames.make_qualid?loc(dirpath_of_globalr)(id_of_globalenvr)letsafe_genfenvsigmac=letorig_extern_ref=Constrextern.get_extern_reference()inletextern_ref?locvarsr=tryorig_extern_refvarsrwithewhenCErrors.noncriticale->qualid_of_global?locenvrinConstrextern.set_extern_referenceextern_ref;tryletp=fenvsigmacinConstrextern.set_extern_referenceorig_extern_ref;pwithewhenCErrors.noncriticale->Constrextern.set_extern_referenceorig_extern_ref;str"??"letsafe_pr_lconstr_env=safe_genpr_lconstr_envletsafe_pr_constr_env=safe_genpr_constr_envletq_ident=Id.of_string"α"letu_ident=Id.of_string"u"letuniverse_binders_with_opt_namesorignames=letopenUnivinletqorig,uorig=UVars.AbstractContext.namesoriginletqorig,uorigasorig=Array.to_listqorig,Array.to_listuoriginletqdecl,udecl=matchnameswith|None->orig|Some(qdecl,udecl)->tryletqs=List.map2(funorig{CAst.v=na}->matchnawith|Anonymous->orig|Nameid->Nameid)qorigqdeclinletus=List.map2(funorig{CAst.v=na}->matchnawith|Anonymous->orig|Nameid->Nameid)uorigudeclinqs,uswithInvalid_argument_->letopenUnivGeninraise(UniverseLengthMismatch{actual=List.lengthqorig,List.lengthuorig;expect=List.lengthqdecl,List.lengthudecl;})inletfold_qnamedi((qbind,ubind),(revqbind,revubind)aso)=function|Nameid->letui=Sorts.QVar.make_variin(Id.Map.addiduiqbind,ubind),(Sorts.QVar.Map.adduiidrevqbind,revubind)|Anonymous->oinletfold_unamedi((qbind,ubind),(revqbind,revubind)aso)=function|Nameid->letui=Level.variin(qbind,Id.Map.addiduiubind),(revqbind,Level.Map.adduiidrevubind)|Anonymous->oinletnames=List.fold_left_ifold_qnamed0UnivNames.(empty_binders,empty_rev_binders)qdeclinletnames=List.fold_left_ifold_unamed0namesudeclinletfold_qanonsi(u_ident,((qbind,ubind),(revqbind,revubind))aso)=function|Name_->o|Anonymous->letui=Sorts.QVar.make_variinletid=Namegen.next_ident_away_fromu_ident(funid->Id.Map.memidqbind)in(id,((Id.Map.addiduiqbind,ubind),(Sorts.QVar.Map.adduiidrevqbind,revubind)))inletfold_uanonsi(u_ident,((qbind,ubind),(revqbind,revubind))aso)=function|Name_->o|Anonymous->letui=Level.variinletid=Namegen.next_ident_away_fromu_ident(funid->Id.Map.memidubind)in(id,((qbind,Id.Map.addiduiubind),(revqbind,Level.Map.adduiidrevubind)))inlet(_,names)=List.fold_left_ifold_qanons0(q_ident,names)qdeclinlet(_,names)=List.fold_left_ifold_uanons0(u_ident,names)udeclinnamesletpr_universe_ctx_setsigmac=if!Detyping.print_universes&¬(Univ.ContextSet.is_emptyc)thenfnl()++pr_in_comment(v0(Univ.pr_universe_context_set(Termops.pr_evd_levelsigma)c))elsemt()letpr_universe_ctxsigma?variancec=if!Detyping.print_universes&¬(UVars.UContext.is_emptyc)thenfnl()++pr_in_comment(v0(UVars.pr_universe_context(Termops.pr_evd_qvarsigma)(Termops.pr_evd_levelsigma)?variancec))elsemt()letpr_abstract_universe_ctxsigma?variance?privc=letopenUnivinletpriv=Option.defaultUniv.ContextSet.emptyprivinlethas_priv=not(ContextSet.is_emptypriv)inif!Detyping.print_universes&&(not(UVars.AbstractContext.is_emptyc)||has_priv)thenletprqvaru=Termops.pr_evd_qvarsigmauinletprlevu=Termops.pr_evd_levelsigmauinletpub=(ifhas_privthenstr"Public universes:"++fnl()elsemt())++v0(UVars.pr_abstract_universe_contextprqvarprlev?variancec)inletpriv=ifhas_privthenfnl()++str"Private universes:"++fnl()++v0(Univ.pr_universe_context_setprlevpriv)elsemt()infnl()++pr_in_comment(pub++priv)elsemt()letpr_universessigma?variance?priv=function|Declarations.Monomorphic->mt()|Declarations.Polymorphicctx->pr_abstract_universe_ctxsigma?variance?privctx(**********************************************************************)(* Global references *)letpr_global_env=Nametab.pr_global_envletpr_global=pr_global_envId.Set.emptyletpr_universe_instance_constraintsevdinstcsts=letopenUnivinletprqvar=Termops.pr_evd_qvarevdinletprlev=Termops.pr_evd_levelevdinletpcsts=ifConstraints.is_emptycststhenmt()elsestr" |= "++prlist_with_sep(fun()->str","++spc())(fun(u,d,v)->hov0(prlevu++pr_constraint_typed++prlevv))(Constraints.elementscsts)instr"@{"++UVars.Instance.prprqvarprlevinst++pcsts++str"}"letpr_universe_instanceevdinst=pr_universe_instance_constraintsevdinstUniv.Constraints.emptyletpr_puniversesfenvsigma(c,u)=if!Constrextern.print_universesthenfenvc++pr_universe_instancesigmauelsefenvcletpr_existential_key=Termops.pr_existential_keyletpr_existentialenvsigmaev=pr_lconstr_envenvsigma(mkEvarev)letpr_constantenvcst=pr_global_env(Termops.vars_of_envenv)(GlobRef.ConstRefcst)letpr_inductiveenvind=pr_global_env(Termops.vars_of_envenv)(GlobRef.IndRefind)letpr_constructorenvcstr=pr_global_env(Termops.vars_of_envenv)(GlobRef.ConstructRefcstr)letpr_pconstant=pr_puniversespr_constantletpr_pinductive=pr_puniversespr_inductiveletpr_pconstructor=pr_puniversespr_constructorletpr_evaluable_referenceref=pr_global(Tacred.global_of_evaluable_referenceref)letpr_notation_interpretation_envenvsigmac=Constrextern.without_symbols(pr_glob_constr_envenvsigma)cletpr_notation_interpretationc=letenv=Global.env()inpr_notation_interpretation_envenv(Evd.from_envenv)c(*let pr_glob_constr t =
pr_lconstr (Constrextern.extern_glob_constr Id.Set.empty t)*)(*open Pattern
let pr_pattern t = pr_pattern_env (Global.env()) empty_names_context t*)(**********************************************************************)(* Contexts and declarations *)(* Flag for compact display of goals *)letget_compact_context,set_compact_context=letcompact_context=reffalsein(fun()->!compact_context),(funb->compact_context:=b)letpr_compacted_declenvsigmadecl=letids,pbody,typ=matchdeclwith|CompactedDecl.LocalAssum(ids,typ)->ids,None,typ|CompactedDecl.LocalDef(ids,c,typ)->(* Force evaluation *)letpb=pr_lconstr_env~inctx:trueenvsigmacinletpb=ifisCastcthensurroundpbelsepbinids,Somepb,typinletpids=hov0(prlist_with_seppr_comma(funid->pr_idid.binder_name)ids)inletpt=pr_ltype_envenvsigmatypinmatchpbodywith|None->hov2(pids++str" :"++spc()++pt)|Somepbody->hov2(pids++str" :="++spc()++pbody++spc()++str": "++pt)letpr_ecompacted_declenvsigma(decl:EConstr.compacted_declaration)=letRefl=EConstr.Unsafe.eqinpr_compacted_declenvsigmadeclletpr_named_declenvsigmadecl=decl|>CompactedDecl.of_named_decl|>pr_compacted_declenvsigmaletpr_enamed_declenvsigma(decl:EConstr.named_declaration)=letRefl=EConstr.Unsafe.eqinpr_named_declenvsigmadeclletpr_rel_declenvsigmadecl=letna=RelDecl.get_namedeclinlettyp=RelDecl.get_typedeclinletpbody=matchdeclwith|RelDecl.LocalAssum_->mt()|RelDecl.LocalDef(_,c,_)->(* Force evaluation *)letpb=pr_lconstr_env~inctx:trueenvsigmacinletpb=ifisCastcthensurroundpbelsepbin(str":="++spc()++pb++spc())inletptyp=pr_ltype_envenvsigmatypinmatchnawith|Anonymous->hov2(str"<>"++spc()++pbody++str":"++spc()++ptyp)|Nameid->hov2(pr_idid++spc()++pbody++str":"++spc()++ptyp)letpr_erel_declenvsigma(decl:EConstr.rel_declaration)=letRefl=EConstr.Unsafe.eqinpr_rel_declenvsigmadecl(* Prints out an "env" in a nice format. We print out the
* signature,then a horizontal bar, then the debruijn environment.
* It's printed out from outermost to innermost, so it's readable. *)(* Prints a signature, all declarations on the same line if possible *)letpr_named_context_ofenvsigma=letmake_decl_listenvdpps=pr_named_declenvsigmad::ppsinletpsl=List.rev(fold_named_contextmake_decl_listenv~init:[])inhv0(prlist_with_sep(fun_->ws2)(funx->x)psl)letpr_var_list_declenvsigmadecl=hov0(pr_ecompacted_declenvsigmadecl)letpr_named_contextenvsigmane_context=hv0(Context.Named.fold_outside(fundpps->pps++ws2++pr_named_declenvsigmad)ne_context~init:(mt()))letpr_rel_contextenvsigmarel_context=letrel_context=EConstr.of_rel_contextrel_contextinpr_bindersenvsigma(extern_rel_contextNoneenvsigmarel_context)letpr_rel_context_ofenvsigma=pr_rel_contextenvsigma(rel_contextenv)(* Prints an env (variables and de Bruijn). Separator: newline *)letpr_context_unlimitedenvsigma=letsign_env=Context.Compacted.fold(fundpps->letpidt=pr_ecompacted_declenvsigmadin(pps++fnl()++pidt))(Termops.compact_named_contextsigma(EConstr.named_contextenv))~init:(mt())inletdb_env=fold_rel_context(funenvdpps->letpnat=pr_rel_declenvsigmadin(pps++fnl()++pnat))env~init:(mt())in(sign_env++db_env)letpr_ne_context_ofheaderenvsigma=ifList.is_empty(Environ.rel_contextenv)&&List.is_empty(Environ.named_contextenv)then(mt())elseletpenv=pr_context_unlimitedenvsigmain(header++penv++fnl())(* Heuristic for horizontalizing hypothesis that the user probably
considers as "variables": An hypothesis H:T where T:S and S<>Prop. *)letshould_compactenvsigmatyp=get_compact_context()&&lettype_of_typ=Retyping.get_type_ofenvsigmatypinnot(Termops.is_Propsigmatype_of_typ)(* If option Compact Contexts is set, we pack "simple" hypothesis in a
hov box (with three sapaces as a separator), the global box being a
v box *)letrecbld_sign_envenvsigmactxtpps=matchctxtwith|[]->pps|CompactedDecl.LocalAssum(ids,typ)::ctxt'whenshould_compactenvsigmatyp->letpps',ctxt'=bld_sign_env_idenvsigmactxt(mt())truein(* putting simple hyps in a more horizontal flavor *)bld_sign_envenvsigmactxt'(pps++brk(0,0)++hov0pps')|d::ctxt'->letpidt=pr_var_list_declenvsigmadinletpps'=pps++brk(0,0)++pidtinbld_sign_envenvsigmactxt'pps'andbld_sign_env_idenvsigmactxtppsis_start=matchctxtwith|[]->pps,ctxt|CompactedDecl.LocalAssum(ids,typ)asd::ctxt'whenshould_compactenvsigmatyp->letpidt=pr_var_list_declenvsigmadinletpps'=pps++(ifnotis_startthenbrk(3,0)else(mt()))++pidtinbld_sign_env_idenvsigmactxt'pps'false|_->pps,ctxt(* compact printing an env (variables and de Bruijn). Separator: three
spaces between simple hyps, and newline otherwise *)letpr_context_limit_compact?nenvsigma=letctxt=EConstr.named_contextenvinletctxt=Termops.compact_named_contextsigmactxtinletlgth=List.lengthctxtinletn_capped=matchnwith|None->lgth|Somenwhenn>lgth->lgth|Somen->ninletctxt_chopped,ctxt_hidden=Util.List.chopn_cappedctxtin(* a dot line hinting the number of hidden hyps. *)lethidden_dots=String.make(List.lengthctxt_hidden)'.'inletsign_env=v0(strhidden_dots++(mt())++bld_sign_envenvsigma(List.revctxt_chopped)(mt()))inletdb_env=fold_rel_context(funenvdpps->pps++fnl()++pr_rel_declenvsigmad)env~init:(mt())insign_env++db_env(* The number of printed hypothesis in a goal *)(* If [None], no limit *)let{Goptions.get=print_hyps_limit}=Goptions.declare_intopt_option_and_ref~key:["Hyps";"Limit"]~value:None()letpr_context_ofenvsigma=matchprint_hyps_limit()with|None->hv0(pr_context_limit_compactenvsigma)|Somen->hv0(pr_context_limit_compact~nenvsigma)(* display goal parts (Proof mode) *)letpr_predicatepr_elt(b,elts)=letpr_elts=prlist_with_sepspcpr_elteltsinifbthenstr"all"++(ifList.is_emptyeltsthenmt()elsestr" except: "++pr_elts)elseifList.is_emptyeltsthenstr"none"elsepr_eltsletpr_cpredp=letsafe_pr_constantenvkn=trypr_constantenvknwithNot_foundwhen!Flags.in_debugger||!Flags.in_ml_toplevel->Names.Constant.printkninpr_predicate(safe_pr_constant(Global.env()))(Cpred.elementsp)letpr_idpredp=pr_predicateId.print(Id.Pred.elementsp)letpr_prpredp=pr_predicateProjection.Repr.print(PRpred.elementsp)letpr_transparent_statets=hv0(str"VARIABLES: "++pr_idpredts.TransparentState.tr_var++fnl()++str"CONSTANTS: "++pr_cpredts.TransparentState.tr_cst++fnl()++str"PROJECTIONS: "++pr_prpredts.TransparentState.tr_prj++fnl())letgoal_reprsigmag=letEvarInfoevi=Evd.findsigmaginletenv=Evd.evar_filtered_env(Global.env())eviinletconcl=matchEvd.evar_bodyeviwith|Evd.Evar_empty->Evd.evar_conclevi|Evd.Evar_definedb->Retyping.get_type_ofenvsigmabinenv,concl(* display complete goal
og_s has goal+sigma on the previous proof step for diffs
g_s has goal+sigma on the current proof step
*)letpr_goal?diffssigmag=letgoal=matchdiffswith|Someog_s->letg=Proof_diffs.make_goal(Global.env())sigmaginlet(hyps_pp_list,concl_pp)=Proof_diffs.diff_goal?og_sginlethyp_list_to_pphyps=matchhypswith|h::tl->List.fold_left(funxy->x++cut()++y)htl|[]->mt()inv0((hyp_list_to_pphyps_pp_list)++cut()++str"============================"++cut()++concl_pp)|None->letenv,concl=goal_reprsigmaginpr_context_ofenvsigma++cut()++str"============================"++cut()++hov0(pr_letype_env~goal_concl_style:trueenvsigmaconcl)instr" "++v0goal(* display a goal tag *)letpr_goal_tagg=lets=" (ID "^Proof.goal_uidg^")"instrs(* display a goal name *)letpr_goal_namesigmag=ifshould_gname()thenstr" "++Pp.surround(pr_existential_key(Global.env())sigmag)elsemt()letpr_goal_headernmesigmag=str"goal "++nme++(ifshould_tag()thenpr_goal_taggelsestr"")++(ifshould_gname()thenstr" "++Pp.surround(pr_existential_key(Global.env())sigmag)elsemt())(* display the conclusion of a goal *)letpr_concln?diffssigmag=letenv,concl=goal_reprsigmaginletpc=matchdiffswith|Someog_s->Proof_diffs.diff_concl?og_s(Proof_diffs.make_goalenvsigmag)|None->pr_letype_env~goal_concl_style:trueenvsigmaconclinletheader=pr_goal_header(intn)sigmaginheader++str" is:"++cut()++str" "++pc(* display evar type: a context and a type *)letpr_evgl_signenvsigma(evi:undefinedevar_info)=letenv=evar_envenveviinletps=pr_named_context_ofenvsigmainlet_,l=matchFilter.repr(evar_filterevi)with|None->[],[]|Somef->List.filter2(funbc->notb)f(evar_contextevi)inletids=List.rev_mapNamedDecl.get_idlinletwarn=ifList.is_emptyidsthenmt()else(str" ("++prlist_with_seppr_commapr_idids++str" cannot be used)")inletconcl=Evd.evar_concleviinletpc=pr_leconstr_envenvsigmaconclinletcandidates=beginmatchEvd.evar_candidateseviwith|None->mt()|Somel->spc()++str"= {"++prlist_with_sep(fun()->str"|")(pr_leconstr_envenvsigma)l++str"}"endinhov0(str"["++ps++spc()++str"|- "++pc++str"]"++candidates++warn)(* Print an existential variable *)letpr_evarsigma(evk,evi)=letenv=Global.env()inletpegl=pr_evgl_signenvsigmaeviinhov2(pr_existential_keyenvsigmaevk++str" :"++spc()++pegl)(* Print an enumerated list of existential variables *)letrecpr_evars_int_hdprsigmai=function|[]->mt()|(evk,evi)::rest->(hov0(prievkevi))++(matchrestwith[]->mt()|_->fnl()++pr_evars_int_hdprsigma(i+1)rest)letpr_evars_intsigma~shelf~given_upievs=letpr_statusi=ifList.memishelfthenstr" (shelved)"elseifList.memigiven_upthenstr" (given up)"elsemt()inpr_evars_int_hd(funievkevi->str"Existential "++inti++str" ="++spc()++pr_evarsigma(evk,evi)++pr_statusevk)sigmai(Evar.Map.bindingsevs)letpr_evarssigmaevs=pr_evars_int_hd(funievkevi->pr_evarsigma(evk,evi))sigma1(Evar.Map.bindingsevs)(* Display a list of evars given by their name, with a prefix *)letpr_ne_evar_sethdtlsigmal=ifl!=Evar.Set.emptythenletl=Evar.Map.bind(funev->letevi=Evd.find_undefinedsigmaevinEvarutil.nf_evar_infosigmaevi)linhd++pr_evarssigmal++tlelsemt()letpr_selected_subgoalnamesigmag=letpg=pr_goalsigmaginletheader=pr_goal_headernamesigmaginv0(header++str" is:"++cut()++pg)letpr_subgoalnsigma=letrecprrecp=function|[]->user_errPp.(str"No such goal.")|g::rest->ifInt.equalp1thenpr_selected_subgoal(intn)sigmagelseprrec(p-1)restinprrecnletpr_internal_existential_keyev=Evar.printevletprint_evar_constraintsglsigma=letpr_env=matchglwith|None->fune'->pr_context_ofe'sigma|Someg->letenv,_=goal_reprsigmaginfune'->beginifContext.Named.equalSorts.relevance_equalConstr.equal(named_contextenv)(named_contexte')thenifContext.Rel.equalSorts.relevance_equalConstr.equal(rel_contextenv)(rel_contexte')thenmt()elsepr_rel_context_ofe'sigma++str" |-"++spc()elsepr_context_ofe'sigma++str" |-"++spc()endinletpr_evconstr(pbty,env,t1,t2)=lett1=Evarutil.nf_evarsigmat1andt2=Evarutil.nf_evarsigmat2inletenv=(* We currently allow evar instances to refer to anonymous de Bruijn
indices, so we protect the error printing code in this case by giving
names to every de Bruijn variable in the rel_context of the conversion
problem. MS: we should rather stop depending on anonymous variables, they
can be used to indicate independency. Also, this depends on a strategy for
naming/renaming *)Namegen.make_all_name_differentenvsigmainstr" "++hov2(pr_envenv++pr_leconstr_envenvsigmat1++spc()++str(matchpbtywith|Conversion.CONV->"=="|Conversion.CUMUL->"<=")++spc()++pr_leconstr_envenvsigmat2)inletpr_candidateevevi(candidates,acc)=ifOption.has_some(Evd.evar_candidatesevi)then(succcandidates,acc++pr_evarsigma(ev,evi)++fnl())else(candidates,acc)inletconstraints=let_,cstrs=Evd.extract_all_conv_pbssigmainifList.is_emptycstrsthenmt()elsefnl()++str(String.plural(List.lengthcstrs)"unification constraint")++str":"++fnl()++hov0(prlist_with_sepfnlpr_evconstrcstrs)inletcandidates,ppcandidates=Evd.fold_undefinedpr_candidatesigma(0,mt())inconstraints++ifcandidates>0thenfnl()++str(String.pluralcandidates"existential")++str" with candidates:"++fnl()++hov0ppcandidateselsemt()let{Goptions.get=should_print_dependent_evars}=Goptions.declare_bool_option_and_ref~key:["Printing";"Dependent";"Evars";"Line"]~value:false()letevar_nodes_of_termc=letrecevrecaccc=matchkindcwith|Evar(n,l)->Evar.Set.addn(SList.Skip.foldevrecaccl)|_->Constr.foldevrecacccinevrecEvar.Set.empty(EConstr.Unsafe.to_constrc)(* spiwack: a few functions to gather evars on which goals depend. *)letqueue_setqis_dependentset=Evar.Set.iter(funa->Queue.push(is_dependent,a)q)setletqueue_termqis_dependentc=queue_setqis_dependent(evar_nodes_of_termc)letprocess_dependent_evarqaccevmis_dependente=letEvarInfoevi=Evd.findevmein(* Queues evars appearing in the types of the goal (conclusion, then
hypotheses), they are all dependent. *)let()=matchEvd.evar_bodyeviwith|Evar_empty->queue_termqtrue(Evd.evar_conclevi)|Evar_definedb->letenv=Evd.evar_filtered_env(Global.env())eviinqueue_termqtrue(Retyping.get_type_ofenvevmb)inList.iterbeginfundecl->letopenNamedDeclinqueue_termqtrue(NamedDecl.get_typedecl);matchdeclwith|LocalAssum_->()|LocalDef(_,b,_)->queue_termqtruebend(EConstr.named_context_of_val(Evd.evar_hypsevi));matchEvd.evar_bodyeviwith|Evar_empty->ifis_dependentthenEvar.Map.addeNoneaccelseacc|Evar_definedb->letsubevars=evar_nodes_of_termbin(* evars appearing in the definition of an evar [e] are marked
as dependent when [e] is dependent itself: if [e] is a
non-dependent goal, then, unless they are reach from another
path, these evars are just other non-dependent goals. *)queue_setqis_dependentsubevars;ifis_dependentthenEvar.Map.adde(Somesubevars)accelseacc(** [gather_dependent_evars evm seeds] classifies the evars in [evm]
as dependent_evars and goals (these may overlap). A goal is an evar
appearing in the (partial) definition [seeds] (including defined evars). A
dependent evar is an evar appearing in the type
(hypotheses and conclusion) of a goal, or in the type or (partial)
definition of a dependent evar. The value return is a map
associating to each dependent evar [None] if it has no (partial)
definition or [Some s] if [s] is the list of evars appearing in
its (partial) definition. This completely breaks the EConstr abstraction. *)letgather_dependent_evarsevml=letq=Queue.create()inList.iter(queue_termqfalse)l;letacc=refEvar.Map.emptyinwhilenot(Queue.is_emptyq)dolet(is_dependent,e)=Queue.popqin(* checks if [e] has already been added to [!acc] *)beginifnot(Evar.Map.meme!acc)thenacc:=process_dependent_evarq!accevmis_dependenteenddone;!acc(* /spiwack *)letgather_dependent_evars_goalsigmagoals=letmapevk=letEvarInfoevi=Evd.findsigmaevkinEConstr.mkEvar(evk,Evd.evar_identity_substevi)ingather_dependent_evarssigma(List.mapmapgoals)letprint_dependent_evars_coreglsigmaevars=letmt_pp=mt()inletevars_pp=Evar.Map.fold(funeis->lete'=pr_internal_existential_keyeinletsep=ifs=mt_ppthen""else", "ins++strsep++e'++(matchiwith|None->str":"++(Termops.pr_existential_key(Global.env())sigmae)|Somei->letusing=Evar.Set.fold(funds->s++str" "++(pr_internal_existential_keyd))imt_ppinstr" using"++using))evarsmt_ppinletevars_current_pp=matchglwith|None->mt_pp|Somegl->letevars_current=gather_dependent_evars_goalsigma[gl]inEvar.Map.fold(fune_s->s++str" "++(pr_internal_existential_keye))evars_currentmt_ppincut()++cut()++str"(dependent evars: "++evars_pp++str"; in current goal:"++evars_current_pp++str")"letprint_dependent_evarsglsigmaseeds=ifshould_print_dependent_evars()thenletevars=gather_dependent_evars_goalsigmaseedsinprint_dependent_evars_coreglsigmaevarselsemt()letprint_dependent_evars_entryglsigma=function|None->mt()|Someentry->ifshould_print_dependent_evars()thenletterms=List.mappi2(Proofview.initial_goalsentry)inletevars=gather_dependent_evarssigmatermsinprint_dependent_evars_coreglsigmaevarselsemt()(* Print open subgoals. Checks for uninstantiated existential variables *)(* spiwack: [entry] is for printing dependent evars in emacs mode. *)(* spiwack: [pr_first] is true when the first goal must be singled out
and printed in its entirety. *)(* [os_map] is derived from the previous proof step, used for diffs *)letpr_subgoals?(pr_first=true)?diffs?entrysigma~shelf~stack~unfocused~goals=(* Printing functions for the extra informations. *)letrecprint_stacka=function|[]->Pp.inta|b::l->Pp.inta++str"-"++print_stackblinletprint_unfocused_numsl=matchlwith|[]->None|a::l->Some(str"unfocused: "++print_stackal)inletprint_shelfl=matchlwith|[]->None|_->Some(str"shelved: "++Pp.int(List.lengthl))inletrecprint_comma_separated_listal=matchlwith|[]->a|b::l->print_comma_separated_list(a++str", "++b)linletprint_extra_listl=matchlwith|[]->Pp.mt()|a::l->Pp.spc()++str"("++print_comma_separated_listal++str")"inletextra=Option.List.flatten[print_unfocused_numsstack;print_shelfshelf]inletprint_extra=print_extra_listextrainletfocused_if_needed=letneeded=not(CList.is_emptyextra)&&pr_firstinifneededthenstr" focused "elsestr" "(* non-breakable space *)inletget_ogsmapg=matchmapwith|None->None|Somemap->Proof_diffs.map_goalgmapinletrecpr_recn=function|[]->(mt())|g::rest->letdiffs=Option.map(funmap->get_ogsmapg)diffsinletpc=pr_concln?diffssigmaginletprest=pr_rec(n+1)restin(cut()++pc++prest)inletprint_multiple_goalsgl=ifpr_firstthenletdiffs=Option.map(funmap->get_ogsmapg)diffsinpr_goal?diffssigmag++(ifl=[]thenmt()elsecut())++pr_rec2lelsepr_rec1(g::l)inletpr_evar_infogl=letfirst_goal=ifpr_firstthenglelseNoneinprint_evar_constraintsglsigma++print_dependent_evars_entryfirst_goalsigmaentryin(* Main function *)matchgoalswith|[]->letexl=Evd.undefined_mapsigmainifEvar.Map.is_emptyexlthenv0(str"No more goals."++pr_evar_infoNone)elseletpei=pr_evars_intsigma~shelf~given_up:[]1exlinv0((str"No more goals,"++str" but there are non-instantiated existential variables:"++cut()++(hov0pei)++pr_evar_infoNone++cut()++str"You can use Unshelve."))|g1::rest->letgoals=print_multiple_goalsg1restinletngoals=List.lengthrest+1inv0(hov0(intngoals++focused_if_needed++str(String.pluralngoals"goal")++print_extra)++str(ifpr_first&&(should_gname())&&ngoals>1then", goal 1"else"")++(ifpr_first&&should_tag()thenpr_goal_tagg1elsestr"")++(ifpr_firstthenpr_goal_namesigmag1elsemt())++cut()++goals++(ifunfocused=[]thenstr""else(cut()++cut()++str"*** Unfocused goals:"++cut()++pr_rec(List.lengthrest+2)unfocused))++pr_evar_info(Someg1))letpr_open_subgoals?(quiet=false)?diffsproof=(* spiwack: it shouldn't be the job of the printer to look up stuff
in the [evar_map], I did stuff that way because it was more
straightforward, but seriously, [Proof.proof] should return
[evar_info]-s instead. *)letp=proofinletProof.{goals;stack;sigma;entry}=Proof.datapinletshelf=Evd.shelfsigmainletgiven_up=Evd.given_upsigmainletstack=List.map(fun(l,r)->List.lengthl+List.lengthr)stackinbeginmatchgoalswith|[]->letbgoals=Proof.background_subgoalspinbeginmatchbgoals,shelf,given_upwith|[],[],gwhenEvar.Set.is_emptyg->pr_subgoalssigma~entry~shelf~stack~unfocused:[]~goals|[],[],_->Feedback.msg_info(str"No more goals, but there are some goals you gave up:");fnl()++pr_subgoals~pr_first:falsesigma~entry~shelf:[]~stack:[]~unfocused:[]~goals:(Evar.Set.elementsgiven_up)++fnl()++str"You need to go back and solve them."|[],_,_->Feedback.msg_info(str"All the remaining goals are on the shelf.");fnl()++pr_subgoals~pr_first:falsesigma~entry~shelf:[]~stack:[]~unfocused:[]~goals:shelf|_,_,_->let()=ifquietthen()elseFeedback.msg_info(str"This subproof is complete, but there are some unfocused goals."++(lets=Proof_bullet.suggestpinifPp.ismtsthenselsefnl()++s)++fnl())inpr_subgoals~pr_first:falsesigma~entry~shelf~stack:[]~unfocused:[]~goals:bgoalsend|_->letbgoals=Proof.background_subgoalspinletbgoals_focused,bgoals_unfocused=List.partition(funx->List.memxgoals)bgoalsinletunfocused_if_needed=ifshould_unfoc()thenbgoals_unfocusedelse[]inletdiffs=matchdiffswith|Some(Someop)->Some(trySome(Proof_diffs.make_goal_mapopproof)withPp_diff.Diff_Failuremsg->Proof_diffs.notify_proof_diff_failuremsg;None)|SomeNone->SomeNone|None->Noneinpr_subgoals~pr_first:true?diffssigma~entry~shelf~stack:[]~unfocused:unfocused_if_needed~goals:bgoals_focusedendletpr_nth_open_subgoal~proofn=letProof.{goals;sigma}=Proof.dataproofinpr_subgoalnsigmagoalsletpr_goal_by_id~proofid=trylet{Proof.sigma}=Proof.dataproofinletg=Evd.evar_keyidsigmainpr_selected_subgoal(pr_idid)sigmagwithNot_found->user_errPp.(str"No such goal.")(** print a goal identified by the goal id as it appears in -emacs mode.
sid should be the Stm state id corresponding to proof. Used to support
the Prooftree tool in Proof General. (https://askra.de/software/prooftree/).
*)letpr_goal_emacs~proofgidsid=matchproofwith|None->user_errPp.(str"No proof for that state.")|Someproof->letprsigmags=v0((str"goal ID "++(intgid)++str" at state "++(intsid))++cut()++pr_goalsigmags)intrylet{Proof.sigma}=Proof.dataproofinletgl=Evar.unsafe_of_intgidinv0(prsigmagl++print_dependent_evars(Somegl)sigma[gl])withNot_found->user_errPp.(str"No such goal.")(* Printer function for sets of Assumptions.assumptions.
It is used primarily by the Print Assumptions command. *)typeaxiom=|ConstantofConstant.t|PositiveofMutInd.t|GuardedofGlobRef.t|TypeInTypeofGlobRef.t|UIPofMutInd.ttypecontext_object=|VariableofId.t(* A section variable or a Let definition *)|Axiomofaxiom*(Label.t*Constr.rel_context*types)list|OpaqueofConstant.t(* An opaque constant. *)|TransparentofConstant.t(* Defines a set of [assumption] *)moduleOrderedContextObject=structtypet=context_objectletcompare_axiomxy=matchx,ywith|Constantk1,Constantk2->Constant.CanOrd.comparek1k2|Positivem1,Positivem2|UIPm1,UIPm2->MutInd.CanOrd.comparem1m2|Guardedk1,Guardedk2|TypeInTypek1,TypeInTypek2->GlobRef.CanOrd.comparek1k2|Constant_,_->-1|_,Constant_->1|Positive_,_->-1|_,Positive_->1|Guarded_,_->-1|_,Guarded_->1|TypeInType_,_->-1|_,TypeInType_->1letcomparexy=matchx,ywith|Variablei1,Variablei2->Id.comparei1i2|Variable_,_->-1|_,Variable_->1|Axiom(k1,_),Axiom(k2,_)->compare_axiomk1k2|Axiom_,_->-1|_,Axiom_->1|Opaquek1,Opaquek2->Constant.CanOrd.comparek1k2|Opaque_,_->-1|_,Opaque_->1|Transparentk1,Transparentk2->Constant.CanOrd.comparek1k2endmoduleContextObjectSet=Set.Make(OrderedContextObject)moduleContextObjectMap=Map.Make(OrderedContextObject)letpr_assumptionsetenvsigmas=ifContextObjectMap.is_emptys&¬(rewrite_rules_allowedenv)&¬(is_impredicative_setenv)thenstr"Closed under the global context"elseletsafe_pr_constantenvkn=trypr_constantenvknwithNot_found->Names.Constant.printkninletsafe_pr_globalenvgr=trypr_global_env(Termops.vars_of_envenv)grwithNot_found->letopenGlobRefinmatchgrwith|VarRefid->Id.printid|ConstRefcon->Constant.printcon|IndRef(mind,_)->MutInd.printmind|ConstructRef_->assertfalseinletsafe_pr_inductiveenvkn=trypr_inductiveenv(kn,0)withNot_found->MutInd.printkninletsafe_pr_ltypeenvsigmatyp=trystr" :"++spc()++pr_ltype_envenvsigmatypwithewhenCErrors.noncriticale->mt()inletsafe_pr_ltype_relctx(rctx,typ)=letenv=Environ.push_rel_contextrctxenvintrystr" "++pr_ltype_envenvsigmatypwithewhenCErrors.noncriticale->mt()inletpr_axiomenvaxtyp=matchaxwith|Constantkn->hov2(safe_pr_constantenvkn++safe_pr_ltypeenvsigmatyp)|Positivem->hov2(safe_pr_inductiveenvm++spc()++strbrk"is assumed to be positive.")|Guardedgr->hov2(safe_pr_globalenvgr++spc()++strbrk"is assumed to be guarded.")|TypeInTypegr->hov2(safe_pr_globalenvgr++spc()++strbrk"relies on an unsafe hierarchy.")|UIPmind->hov2(safe_pr_inductiveenvmind++spc()++strbrk"relies on definitional UIP.")inletfoldttypaccu=let(v,a,o,tr)=accuinmatchtwith|Variableid->letvar=pr_idid++spc()++str": "++pr_ltype_envenvsigmatypin(var::v,a,o,tr)|Axiom(axiom,[])->letax=pr_axiomenvaxiomtypin(v,ax::a,o,tr)|Axiom(axiom,l)->letax=pr_axiomenvaxiomtyp++spc()++prlist_with_sepcut(fun(lbl,ctx,ty)->str"used in "++Label.printlbl++str" to prove"++fnl()++safe_pr_ltype_relctx(ctx,ty))lin(v,ax::a,o,tr)|Opaquekn->letopq=safe_pr_constantenvkn++safe_pr_ltypeenvsigmatypin(v,a,opq::o,tr)|Transparentkn->lettran=safe_pr_constantenvkn++safe_pr_ltypeenvsigmatypin(v,a,o,tran::tr)inlet(vars,axioms,opaque,trans)=ContextObjectMap.foldfolds([],[],[],[])inlettheory=ifis_impredicative_setenvthen[str"Set is impredicative"]else[]inlettheory=ifrewrite_rules_allowedenvthenstr"Rewrite rules are allowed (subject reduction might be broken)"::theoryelsetheoryinlettheory=iftype_in_typeenvthenstr"Type hierarchy is collapsed (logic is inconsistent)"::theoryelsetheoryinletopt_listtitle=function|[]->None|l->letsection=title++fnl()++v0(prlist_with_sepfnl(funs->s)l)inSomesectioninletassums=[opt_list(str"Transparent constants:")trans;opt_list(str"Section Variables:")vars;opt_list(str"Axioms:")axioms;opt_list(str"Opaque constants:")opaque;opt_list(str"Theory:")theory;]inprlist_with_sepfnl(funx->x)(Option.List.flattenassums)letpr_typing_flagsflags=str"check_guarded: "++boolflags.check_guarded++fnl()++str"check_positive: "++boolflags.check_positive++fnl()++str"check_universes: "++boolflags.check_universes++fnl()++str"definitional uip: "++boolflags.allow_uipmoduleDebug=structletpr_goalgl=pr_goal(Proofview.Goal.sigmagl)(Proofview.Goal.goalgl)end