123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenConstropenEConstropenNamesopenPattern(* Discrimination nets with bounded depth.
See the module dn.ml for further explanations.
Eduardo (5/8/97). *)letdnet_depth=ref8typeterm_label=|GRLabelofGlobRef.t|ProdLabel|SortLabelletcompare_term_labelt1t2=matcht1,t2with|GRLabelgr1,GRLabelgr2->GlobRef.CanOrd.comparegr1gr2|_->pervasives_comparet1t2(** OK *)type'reslookup_res='resDn.lookup_res=Labelof'res|Nothing|Everythingleteta_reduce=Reductionops.shrink_eta(* TODO: instead of doing that on patterns we should try to perform it on terms
before translating them into patterns in Hints. *)letreceta_reduce_patp=matchpwith|PLambda(_,_,q)->letf,cl=matcheta_reduce_patqwith|PApp(f,cl)->f,cl|q->q,[||]inletnapp=Array.lengthclinifnapp>0thenletr=eta_reduce_pat(Array.lastcl)inmatchrwith|PRel1->letlc=Array.subcl0(napp-1)inletu=ifArray.is_emptylcthenfelsePApp(f,lc)inifPatternops.noccurn_pattern1uthenPatternops.lift_pattern(-1)uelsep|_->pelsep|PRef_|PVar_|PEvar_|PRel_|PApp_|PSoApp_|PProj_|PProd_|PLetIn_|PSort_|PMeta_|PIf_|PCase_|PFix_|PCoFix_|PInt_|PFloat_|PArray_->pletdecomp_patp=letrecdecrecacc=function|PApp(f,args)->decrec(Array.to_listargs@acc)f|PProj(p,c)->lethole=PMetaNoneinletparams=List.make(Projection.nparsp)holein(PRef(GlobRef.ConstRef(Projection.constantp)),params@c::acc)|c->(c,acc)indecrec[](eta_reduce_patp)letdecompsigmat=letrecdecrecaccc=matchEConstr.kindsigmacwith|App(f,l)->decrec(Array.fold_right(funal->a::l)lacc)f|Proj(p,c)->(* Hack: fake evar to generate [Everything] in the functions below *)lethole=mkEvar(Evar.unsafe_of_int(-1),SList.empty)inletparams=List.make(Projection.nparsp)holein(* UnsafeMonomorphic: universes are ignored by the only user *)(UnsafeMonomorphic.mkConst(Projection.constantp),params@c::acc)|Cast(c1,_,_)->decrecaccc1|_->(c,acc)indecrec[](eta_reducesigmat)letevaluable_constantcenvts=(* This is a hack to work around a broken Print Module implementation, see
bug #2668. *)(ifEnviron.mem_constantcenvthenEnviron.evaluable_constantcenvelsetrue)&&(matchtswithNone->true|Somets->TransparentState.is_transparent_constanttsc)letevaluable_namedidenvts=(tryEnviron.evaluable_namedidenvwithNot_found->true)&&(matchtswithNone->true|Somets->TransparentState.is_transparent_variabletsid)(* The pattern view functions below try to overapproximate βι-neutral terms up
to η-conversion. Some historical design choices are still incorrect w.r.t. to
this specification. TODO: try to make them follow the spec. *)letconstr_val_discrenvsigmatst=(* Should we perform weak βι here? *)letc,l=decompsigmatinletopenGlobRefinmatchEConstr.kindsigmacwith|Const(c,u)->ifevaluable_constantcenvtsthenEverythingelseLabel(GRLabel(ConstRefc),l)|Ind(ind_sp,u)->Label(GRLabel(IndRefind_sp),l)|Construct(cstr_sp,u)->Label(GRLabel(ConstructRefcstr_sp),l)|Varid->ifevaluable_namedidenvtsthenEverythingelseLabel(GRLabel(VarRefid),l)|Prod(n,d,c)->Label(ProdLabel,[d;c])|Lambda(n,d,c)->ifOption.is_emptyts&&List.is_emptylthenNothingelseEverything|Sort_->Label(SortLabel,[])|Evar_->Everything|Case(_,_,_,_,_,c,_)->(* Overapproximate wildly. TODO: be less brutal. *)Everything|Rel_|Meta_|Cast_|LetIn_|App_|Fix_|CoFix_|Proj_|Int_|Float_|Array_->Nothingletconstr_pat_discrenvtst=letopenGlobRefinmatchdecomp_pattwith|PRef((IndRef_)asref),args|PRef((ConstructRef_)asref),args->Some(GRLabelref,args)|PRef((VarRefv)asref),args->ifevaluable_namedvenvtsthenNoneelseSome(GRLabelref,args)|PRef((ConstRefc)asref),args->ifevaluable_constantcenvtsthenNoneelseSome(GRLabelref,args)|PVarv,args->ifevaluable_namedvenvtsthenNoneelseSome(GRLabel(VarRefv),args)|PProd(_,d,c),[]->Some(ProdLabel,[d;c])|PLambda(_,d,c),[]->None|PSorts,[]->Some(SortLabel,[])|_->Noneletbounded_constr_pat_discrenvst(t,depth)=ifInt.equaldepth0thenNoneelsematchconstr_pat_discrenvsttwith|None->None|Some(c,l)->Some(c,List.map(func->(c,depth-1))l)letbounded_constr_val_discrenvstsigma(t,depth)=ifInt.equaldepth0thenNothingelsematchconstr_val_discrenvsigmasttwith|Label(c,l)->Label(c,List.map(func->(c,depth-1))l)|Nothing->Nothing|Everything->EverythingmoduleMake=functor(Z:Map.OrderedType)->structmoduleY=structtypet=term_labelletcompare=compare_term_labelendmoduleDn=Dn.Make(Y)(Z)typet=Dn.ttypepattern=Dn.patternletpatternenvstpat=Dn.pattern(bounded_constr_pat_discrenvst)(pat,!dnet_depth)letconstr_patternenvsigmastpat=letmkp=matchbounded_constr_val_discrenvstsigmapwith|Labell->Somel|Everything|Nothing->NoneinDn.patternmk(pat,!dnet_depth)letempty=Dn.emptyletadd=Dn.addletrmv=Dn.rmvletlookupenvsigmastdnt=Dn.lookupdn(bounded_constr_val_discrenvstsigma)(t,!dnet_depth)end