123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229(************************************************************************)(* * 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) *)(************************************************************************)(** Declaration of uninterpretation functions (i.e. printing rules)
for notations *)(*i*)openUtilopenNamesopenGlobnamesopenConstrexpropenNotation_termopenGlob_term(*i*)letnotation_with_optional_scope_eqinscope1inscope2=match(inscope1,inscope2)with|LastLonelyNotation,LastLonelyNotation->true|NotationInScopes1,NotationInScopes2->String.equals1s2|(LastLonelyNotation|NotationInScope_),_->falseletentry_relative_level_eqt1t2=matcht1,t2with|LevelLtn1,LevelLtn2->Int.equaln1n2|LevelLen1,LevelLen2->Int.equaln1n2|LevelSome,LevelSome->true|(LevelLt_|LevelLe_|LevelSome),_->falseletnotation_entry_eqs1s2=match(s1,s2)with|InConstrEntry,InConstrEntry->true|InCustomEntrys1,InCustomEntrys2->String.equals1s2|(InConstrEntry|InCustomEntry_),_->falseletnotation_entry_level_eq(e1,n1)(e2,n2)=notation_entry_eqe1e2&&Int.equaln1n2letnotation_entry_relative_level_eq(e1,(n1,s1))(e2,(n2,s2))=notation_entry_eqe1e2&&entry_relative_level_eqn1n2&&s1=s2letnotation_eq(from1,ntn1)(from2,ntn2)=notation_entry_eqfrom1from2&&String.equalntn1ntn2letpair_eqfg(x1,y1)(x2,y2)=fx1x2&&gy1y2letnotation_binder_kind_eqk1k2=matchk1,k2with|AsIdent,AsIdent->true|AsName,AsName->true|AsAnyPattern,AsAnyPattern->true|AsStrictPattern,AsStrictPattern->true|(AsIdent|AsName|AsAnyPattern|AsStrictPattern),_->falseletnotation_binder_source_eqs1s2=matchs1,s2with|NtnBinderParsedAsSomeBinderKindbk1,NtnBinderParsedAsSomeBinderKindbk2->notation_binder_kind_eqbk1bk2|NtnBinderParsedAsBinder,NtnBinderParsedAsBinder->true|NtnBinderParsedAsConstrbk1,NtnBinderParsedAsConstrbk2->notation_binder_kind_eqbk1bk2|(NtnBinderParsedAsSomeBinderKind_|NtnBinderParsedAsBinder|NtnBinderParsedAsConstr_),_->falseletntpe_eqt1t2=matcht1,t2with|NtnTypeConstr,NtnTypeConstr->true|NtnTypeBinders1,NtnTypeBinders2->notation_binder_source_eqs1s2|NtnTypeConstrList,NtnTypeConstrList->true|NtnTypeBinderLists1,NtnTypeBinderLists2->notation_binder_source_eqs1s2|(NtnTypeConstr|NtnTypeBinder_|NtnTypeConstrList|NtnTypeBinderList_),_->falseletvar_attributes_eq(_,((entry1,sc1),tp1))(_,((entry2,sc2),tp2))=notation_entry_relative_level_eqentry1entry2&&pair_eq(List.equalString.equal)(List.equalString.equal)sc1sc2&&ntpe_eqtp1tp2letinterpretation_eq(vars1,t1asx1)(vars2,t2asx2)=x1==x2||List.equalvar_attributes_eqvars1vars2&&Notation_ops.eq_notation_constr(List.mapfstvars1,List.mapfstvars2)t1t2typelevel=notation_entry*entry_level*entry_relative_levellist(* first argument is InCustomEntry s for custom entries *)letlevel_eq(s1,l1,t1)(s2,l2,t2)=notation_entry_eqs1s2&&Int.equall1l2&&List.equalentry_relative_level_eqt1t2(* Uninterpretation tables *)type'ainterp_rule_gen=|NotationRuleofConstrexpr.specific_notation|AbbrevRuleof'atypeinterp_rule=KerName.tinterp_rule_gen(* We define keys for glob_constr and aconstr to split the syntax entries
according to the key of the pattern (adapted from Chet Murthy by HH) *)typekey=|RefKeyofGlobRef.t|Othletkey_comparek1k2=matchk1,k2with|RefKeygr1,RefKeygr2->GlobRef.CanOrd.comparegr1gr2|RefKey_,Oth->-1|Oth,RefKey_->1|Oth,Oth->0moduleKeyOrd=structtypet=keyletcompare=key_compareendmoduleKeyMap=Map.Make(KeyOrd)typenotation_applicative_status=|AppBoundedNotationofint|AppUnboundedNotation|NotAppNotationtypenotation_rule=interp_rule*interpretation*notation_applicative_statusletnotation_rule_eq(rule1,pat1,s1asx1)(rule2,pat2,s2asx2)=x1==x2||(rule1=rule2&&interpretation_eqpat1pat2&&s1=s2)letstrictly_finer_interpretation_than(_,(_,interp1,_))(_,(_,interp2,_))=Notation_ops.strictly_finer_interpretation_thaninterp1interp2letkeymap_addkeyinterpmap=letold=tryKeyMap.findkeymapwithNot_found->[]in(* strictly finer interpretation are kept in front *)letstrictly_finer,rest=List.partition(func->strictly_finer_interpretation_thancinterp)oldinKeyMap.addkey(strictly_finer@interp::rest)mapletkeymap_removekeyinterpmap=letold=tryKeyMap.findkeymapwithNot_found->[]inKeyMap.addkey(List.remove_first(fun(_,rule)->notation_rule_eqinterprule)old)mapletkeymap_findkeymap=tryKeyMap.findkeymapwithNot_found->[](* Scopes table : interpretation -> scope_name *)(* Boolean = for cases pattern also *)letnotations_key_table=ref(KeyMap.empty:(bool*notation_rule)listKeyMap.t)letglob_prim_constr_keyc=matchDAst.getcwith|GRef(ref,_)->Some(canonical_grref)|GApp(c,_)->beginmatchDAst.getcwith|GRef(ref,_)->Some(canonical_grref)|_->Noneend|GProj((cst,_),_,_)->Some(canonical_gr(GlobRef.ConstRefcst))|_->Noneletglob_constr_keysc=matchDAst.getcwith|GApp(c,_)->beginmatchDAst.getcwith|GRef(ref,_)->[RefKey(canonical_grref);Oth]|_->[Oth]end|GProj((cst,_),_,_)->[RefKey(canonical_gr(GlobRef.ConstRefcst))]|GRef(ref,_)->[RefKey(canonical_grref)]|_->[Oth]letcases_pattern_keyc=matchDAst.getcwith|PatCstr(ref,_,_)->RefKey(canonical_gr(GlobRef.ConstructRefref))|_->Othletnotation_constr_key=function(* Rem: NApp(NRef ref,[]) stands for @ref *)|NApp(NRef(ref,_),args)->RefKey(canonical_grref),AppBoundedNotation(List.lengthargs)|NProj((cst,_),args,_)->RefKey(canonical_gr(GlobRef.ConstRefcst)),AppBoundedNotation(List.lengthargs+1)|NList(_,_,NApp(NRef(ref,_),args),_,_)|NBinderList(_,_,NApp(NRef(ref,_),args),_,_)->RefKey(canonical_grref),AppBoundedNotation(List.lengthargs)|NRef(ref,_)->RefKey(canonical_grref),NotAppNotation|NApp(NList(_,_,NApp(NRef(ref,_),args),_,_),args')->RefKey(canonical_grref),AppBoundedNotation(List.lengthargs+List.lengthargs')|NApp(NList(_,_,NApp(_,args),_,_),args')->Oth,AppBoundedNotation(List.lengthargs+List.lengthargs')|NApp(_,args)->Oth,AppBoundedNotation(List.lengthargs)|NList(_,_,NApp(NVarx,_),_,_)whenx=Notation_ops.ldots_var->Oth,AppUnboundedNotation|_->Oth,NotAppNotationletuninterp_notationsc=List.map_append(funkey->List.mapsnd(keymap_findkey!notations_key_table))(glob_constr_keysc)letfilter_also_for_pattern=List.map_filter(function(true,x)->Somex|_->None)letuninterp_cases_pattern_notationsc=filter_also_for_pattern(keymap_find(cases_pattern_keyc)!notations_key_table)letuninterp_ind_pattern_notationsind=filter_also_for_pattern(keymap_find(RefKey(canonical_gr(GlobRef.IndRefind)))!notations_key_table)letremove_uninterpretationrule(metas,caspat)=let(key,n)=notation_constr_keycinnotations_key_table:=keymap_removekey((rule,pat,n))!notations_key_tableletdeclare_uninterpretation?(also_in_cases_pattern=true)rule(metas,caspat)=let(key,n)=notation_constr_keycinnotations_key_table:=keymap_addkey(also_in_cases_pattern,(rule,pat,n))!notations_key_tableletfreeze()=!notations_key_tableletunfreezefkm=notations_key_table:=fkmletinit()=notations_key_table:=KeyMap.emptylet()=Summary.declare_summary"notation_uninterpretation"{stage=Summary.Stage.Interp;Summary.freeze_function=freeze;Summary.unfreeze_function=unfreeze;Summary.init_function=init}letwith_notation_uninterpretation_protectionfx=letfs=freeze()intryleta=fxinunfreezefs;awithreraise->letreraise=Exninfo.capturereraiseinlet()=unfreezefsinExninfo.iraisereraise(** Miscellaneous *)typenotation_use=|OnlyPrinting|OnlyParsing|ParsingAndPrinting