123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenConstropenNamesopenPattern(* Discrimination nets with bounded depth.
See the module dn.ml for further explanations.
Eduardo (5/8/97). *)letdnet_depth=ref8typeterm_label=|GRLabelofGlobRef.t|ProjLabelofProjection.Repr.t*int(** [ProjLabel (p, n)] represents a possibly partially applied projection [p]
with [n] arguments missing to be fully applied. [n] is always zero for
labels derived from [Proj] terms but can be greater than zero for labels
derived from compatibility constants. *)|ProdLabel|SortLabelletcompare_term_labelt1t2=matcht1,t2with|GRLabelgr1,GRLabelgr2->GlobRef.UserOrd.comparegr1gr2|ProjLabel(p1,n1),ProjLabel(p2,n2)->letc=Int.comparen1n2inifc<>0thencelse(Projection.Repr.UserOrd.comparep1p2)|_->Stdlib.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_pat(p:constr_pattern)=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_|PString_|PArray_->p|PUninstantiated_->.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->Structures.PrimitiveProjections.is_transparent_constanttsc)letevaluable_namedidenvts=(tryEnviron.evaluable_namedidenvwithNot_found->true)&&(matchtswithNone->true|Somets->TransparentState.is_transparent_variabletsid)letevaluable_projectionp_envts=(matchtswithNone->true|Somets->TransparentState.is_transparent_projectionts(Projection.reprp))letlabel_of_opaque_constantcstack=matchStructures.PrimitiveProjections.find_optcwith|None->(GRLabel(ConstRefc),stack)|Somep->letn_args_needed=Structures.Structure.projection_nparamsc+1in(* +1 for the record value itself *)letn_args_given=List.lengthstackinletn_args_missing=max(n_args_needed-n_args_given)0inletn_args_drop=min(n_args_needed-1)n_args_givenin(* we do not drop the record value from the stack *)(ProjLabel(p,n_args_missing),List.skipnn_args_dropstack)(* 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? *)letopenGlobRefinletrecdecompstackt=matchEConstr.kindsigmatwith|App(f,l)->decomp(Array.fold_right(funal->a::l)lstack)f|Proj(p,_,c)whenevaluable_projectionpenvts->Everything|Proj(p,_,c)->Label(ProjLabel(Projection.reprp,0),c::stack)|Cast(c,_,_)->decompstackc|Const(c,_)whenevaluable_constantcenvts->Everything|Const(c,_)->letc=Environ.QConstant.canonizeenvcinLabel(label_of_opaque_constantcstack)|Ind(ind_sp,_)->letind_sp=Environ.QInd.canonizeenvind_spinLabel(GRLabel(IndRefind_sp),stack)|Construct(cstr_sp,_)->letcstr_sp=Environ.QConstruct.canonizeenvcstr_spinLabel(GRLabel(ConstructRefcstr_sp),stack)|Varidwhenevaluable_namedidenvts->Everything|Varid->Label(GRLabel(VarRefid),stack)|Prod(n,d,c)->Label(ProdLabel,[d;c])|Lambda_whenOption.is_emptyts&&List.is_emptystack->Nothing|Lambda_->Everything|Sort_->Label(SortLabel,[])|Evar_->Everything|Case_->Everything(* Overapproximate wildly. TODO: be less brutal. *)|Rel_|Meta_|LetIn_|Fix_|CoFix_|Int_|Float_|String_|Array_->Nothingindecomp[](eta_reducesigmat)letconstr_pat_discrenvtsp=letopenGlobRefinletrecdecompstackp=matchpwith|PApp(f,args)->decomp(Array.to_listargs@stack)f|PProj(p,c)whenevaluable_projectionpenvts->None|PProj(p,c)->Some(ProjLabel(Projection.reprp,0),c::stack)|PRef((IndRef_)asref)|PRef((ConstructRef_)asref)->letref=Environ.QGlobRef.canonizeenvrefinSome(GRLabelref,stack)|PRef(VarRefv)whenevaluable_namedvenvts->None|PRef((VarRef_)asref)->Some(GRLabelref,stack)|PRef(ConstRefc)whenevaluable_constantcenvts->None|PRef(ConstRefc)->letc=Environ.QConstant.canonizeenvcinSome(label_of_opaque_constantcstack)|PVarvwhenevaluable_namedvenvts->None|PVarv->Some(GRLabel(VarRefv),stack)|PProd(_,d,c)whenstack=[]->Some(ProdLabel,[d;c])|PSortswhenstack=[]->Some(SortLabel,[])|_->Noneindecomp[](eta_reduce_patp)letconstr_pat_discr_syntacticenvp=letopenGlobRefinletrecdecompstackp=matcheta_reduce_patpwith|PApp(f,args)->decomp(Array.to_listargs@stack)f|PProj(p,c)->Some(ProjLabel(Names.Projection.reprp,0),c::stack)|PRef((IndRef_)asref)|PRef((ConstructRef_)asref)->letref=Environ.QGlobRef.canonizeenvrefinSome(GRLabelref,stack)|PRef((VarRef_)asref)->Some(GRLabelref,stack)|PRef(ConstRefc)->letc=Environ.QConstant.canonizeenvcinSome(label_of_opaque_constantcstack)|PVarv->Some(GRLabel(VarRefv),stack)|PProd(_,d,c)whenstack=[]->Some(ProdLabel,[d;c])|PSortswhenstack=[]->Some(SortLabel,[])|_->Noneindecomp[]pletbounded_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_pat_discr_syntacticenv(t,depth)=ifInt.equaldepth0thenNoneelsematchconstr_pat_discr_syntacticenvtwith|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)letpattern_syntacticenvpat=Dn.pattern(bounded_constr_pat_discr_syntacticenv)(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