123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156(************************************************************************)(* * 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) *)(************************************************************************)(* Interpretation of search commands *)openCErrorsopenNamesopenUtilopenPpopenPrinteropenSearchopenVernacexpropenGoptionsletglobal_moduleqid=tryNametab.full_name_moduleqidwithNot_found->user_err?loc:qid.CAst.loc(str"Module/Section "++Ppconstr.pr_qualidqid++str" not found.")letinterp_search_restriction=function|SearchOutsidel->SearchOutside(List.mapglobal_modulel)|SearchInsidel->SearchInside(List.mapglobal_modulel)letkind_searcherenv=Decls.(function(* Kinds referring to the keyword introducing the object *)|IsAssumption_|IsDefinition(Definition|Example|Fixpoint|CoFixpoint|Method|StructureComponent|Let|LetContext)|IsProof_|IsPrimitive|IsSymbolask->Inlk(* Kinds referring to the status of the object *)|IsDefinition(Coercion|SubClass|IdentityCoercionask')->letcoercions=Coercionops.coercions()inInr(fungr->List.exists(func->Environ.QGlobRef.equalenvc.Coercionops.coe_valuegr&&(k'<>SubClass&&k'<>IdentityCoercion||c.Coercionops.coe_is_identity))coercions)|IsDefinitionCanonicalStructure->letcanonproj=Structures.CSTable.entries()inInr(fungr->List.exists(func->Environ.QGlobRef.equalenvc.Structures.CSTable.solutiongr)canonproj)|IsDefinitionScheme->letschemes=DeclareScheme.all_schemes()inletschemes=lazybeginIndmap.fold(fun_schemesacc->CString.Map.fold(fun_cacc->Cset.addcacc)schemesacc)schemesCset.emptyendinInr(function|ConstRefc->Cset.memc(Lazy.forceschemes)|_->false)|IsDefinitionInstance->letinstances=Typeclasses.all_instances()inInr(fungr->List.exists(func->Environ.QGlobRef.equalenvc.Typeclasses.is_implgr)instances))letinterp_constr_patternenvsigma?(expected_type=Pretyping.WithoutTypeConstraint)c=letc=Constrintern.intern_genexpected_type~pattern_mode:trueenvsigmacinletflags={Pretyping.no_classes_no_fail_inference_flagswithexpand_evars=false}inletsigma,c=Pretyping.understand_tcc~flagsenvsigma~expected_typecin(* FIXME: it is necessary to be unsafe here because of the way we handle
evars in the pretyper. Sometimes they get solved eagerly. *)Patternops.legacy_bad_pattern_of_constrenvsigmacletinterp_search_itemenvsigma=function|SearchSubPattern((where,head),pat)->letexpected_type=Pretyping.(ifheadthenIsTypeelseWithoutTypeConstraint)inletpat=tryinterp_constr_patternenvsigma~expected_typepatwithewhenCErrors.noncriticale->(* We cannot ensure (yet?) that a typable pattern will
actually be typed, consider e.g. (forall A, A -> A /\ A)
which fails, not seeing that A can be Prop; so we use an
untyped pattern as a fallback (i.e w/o no insertion of
coercions, no compilation of pattern-matching) *)snd(Constrintern.intern_constr_patternenvsigma~as_type:headpat)inGlobSearchSubPattern(where,head,pat)|SearchString((Anywhere,false),s,None)whenId.is_valid_ident_parts&&String.equal(String.drop_simple_quotess)s->GlobSearchStrings|SearchString((where,head),s,sc)->letsc=Option.mapsndscinletref=Notation.interp_notation_as_global_reference~head:false(fun_->true)sscinGlobSearchSubPattern(where,head,Pattern.PRefref)|SearchKindk->matchkind_searcherenvkwith|Inlk->GlobSearchKindk|Inrf->GlobSearchFilterfletrecinterp_search_requestenvsigma=function|b,SearchLiterali->b,GlobSearchLiteral(interp_search_itemenvsigmai)|b,SearchDisjConjl->b,GlobSearchDisjConj(List.map(List.map(interp_search_requestenvsigma))l)(* 05f22a5d6d5b8e3e80f1a37321708ce401834430 introduced the
`search_output_name_only` option to avoid excessive printing when
searching.
The motivation was to make search usable for IDE completion,
however, it is still too slow due to the non-indexed nature of the
underlying search mechanism.
In the future we should deprecate the option and provide a fast,
indexed name-searching interface.
*)letsearch_output_name_only=reffalselet()=declare_bool_option{optstage=Summary.Stage.Interp;optdepr=None;optkey=["Search";"Output";"Name";"Only"];optread=(fun()->!search_output_name_only);optwrite=(:=)search_output_name_only}letinterp_searchenvsigmasr=letr=interp_search_restrictionrinletget_patternc=snd(Constrintern.intern_constr_patternenvsigmac)inletwarnlist=ref[]inletpr_searchrefkindenvsigmac=letpr=pr_globalrefinletpp=if!search_output_name_onlythenprelsebeginletopenImpargsinletimpls=implicits_of_globalrefinletimpargs=select_stronger_impargsimplsinletimpargs=List.mapbinding_kind_of_statusimpargsinifList.lengthimpls>1||List.existsGlob_term.(functionExplicit->false|MaxImplicit|NonMaxImplicit->true)(List.skipn_at_best(Termops.nb_prod_modulo_zetasigma(EConstr.of_constrc))impargs)thenwarnlist:=pr::!warnlist;letpc=pr_ltype_envenvsigma~impargscinhov2(pr++str":"++spc()++pc)endinFeedback.msg_noticeppin(matchswith|SearchPatternc->(Search.search_patternenvsigma(get_patternc)r|>Search.prioritize_search)pr_search|SearchRewritec->(Search.search_rewriteenvsigma(get_patternc)r|>Search.prioritize_search)pr_search|Searchsl->(Search.searchenvsigma(List.map(interp_search_requestenvEvd.(from_envenv))sl)r|>Search.prioritize_search)pr_search);if!warnlist<>[]thenFeedback.msg_notice(str"("++hov0(strbrk"use \"About\" for full details on the implicit arguments of "++pr_enum(funx->x)!warnlist++str")"))