123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161(************************************************************************)(* * The Rocq Prover / The Rocq 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) *)(************************************************************************)(* Created by Bruno Barras as part of the rewriting of the conversion
algorithm, Nov 2001 *)openNames(* Priority for the expansion of constant in the conversion test.
* Higher levels means that the expansion is less prioritary.
* (And Expand stands for -oo, and Opaque +oo.)
* The default value is [Level 100].
*)typelevel=Expand|Levelofint|Opaqueletpr_level=function|Expand->Pp.str"expand"|Level0->Pp.str"transparent"|Leveln->Pp.intn|Opaque->Pp.str"opaque"letdefault=Level0letis_default=function|Level0->true|_->falselettransparent=defaultletis_transparent=function|Level0->true|_->falsemoduleCmap=HMap.Make(Constant.CanOrd)modulePRmap=HMap.Make(Projection.Repr.CanOrd)(* TODO: should we hand-canonize without the env, or just change the semantics? *)typeoracle={var_opacity:levelId.Map.t;cst_opacity:levelCmap.t;prj_opacity:levelPRmap.t;var_trstate:Id.Pred.t;cst_trstate:Cpred.t;prj_trstate:PRpred.t;}letempty={var_opacity=Id.Map.empty;cst_opacity=Cmap.empty;prj_opacity=PRmap.empty;var_trstate=Id.Pred.full;cst_trstate=Cpred.full;prj_trstate=PRpred.full;}typeevaluable=|EvalVarRefofId.t|EvalConstRefofConstant.t|EvalProjectionRefofProjection.Repr.tletget_strategy{var_opacity;cst_opacity;prj_opacity;_}=function|EvalVarRefid->(tryId.Map.findidvar_opacitywithNot_found->default)|EvalConstRefc->(tryCmap.findccst_opacitywithNot_found->default)|EvalProjectionRefp->(tryPRmap.findpprj_opacitywithNot_found->default)letset_strategy({var_opacity;cst_opacity;prj_opacity;_}asoracle)kl=matchkwith|EvalVarRefid->letvar_opacity=ifis_defaultlthenId.Map.removeidvar_opacityelseId.Map.addidlvar_opacityinletvar_trstate=matchlwith|Opaque->Id.Pred.removeidoracle.var_trstate|_->Id.Pred.addidoracle.var_trstatein{oraclewithvar_opacity;var_trstate;}|EvalConstRefc->letcst_opacity=ifis_defaultlthenCmap.removeccst_opacityelseCmap.addclcst_opacityinletcst_trstate=matchlwith|Opaque->Cpred.removecoracle.cst_trstate|_->Cpred.addcoracle.cst_trstatein{oraclewithcst_opacity;cst_trstate;}|EvalProjectionRefp->letprj_opacity=ifis_defaultlthenPRmap.removepprj_opacityelsePRmap.addplprj_opacityinletprj_trstate=matchlwith|Opaque->PRpred.removeporacle.prj_trstate|_->PRpred.addporacle.prj_trstatein{oraclewithprj_opacity;prj_trstate}letfold_strategyf{var_opacity;cst_opacity;prj_opacity;_}accu=letfvaridlvlaccu=f(EvalVarRefid)lvlaccuinletfcstcstlvlaccu=f(EvalConstRefcst)lvlaccuinletfprjplvlaccu=f(EvalProjectionRefp)lvlaccuinletaccu=Id.Map.foldfvarvar_opacityaccuinletaccu=Cmap.foldfcstcst_opacityaccuinPRmap.foldfprjprj_opacityacculetget_transp_state{var_trstate;cst_trstate;prj_trstate;_}=letopenTransparentStatein{tr_var=var_trstate;tr_cst=cst_trstate;tr_prj=prj_trstate}typeorder=Left|Right|Sameletdep_orderk1k2=matchk1,k2with|None,None->Same|None,_->Left|Some_,None->Right|Somek1,Somek2->matchk1,k2with|EvalVarRef_,EvalVarRef_->Same|EvalVarRef_,(EvalConstRef_|EvalProjectionRef_)->Left|EvalConstRef_,EvalVarRef_->Right|EvalConstRef_,EvalProjectionRef_->Same|EvalConstRef_,EvalConstRef_->Same|EvalProjectionRef_,EvalVarRef_->Right|EvalProjectionRef_,EvalConstRef_->Same|EvalProjectionRef_,EvalProjectionRef_->Same(* Compare two constants based on their oracle levels.
Returns Same when both have equal levels and same key type. *)letoracle_compareok1k2=lets1=matchk1withNone->Expand|Somek1->get_strategyok1inlets2=matchk2withNone->Expand|Somek2->get_strategyok2inmatchs1,s2with|Expand,Expand->dep_orderk1k2|Expand,(Opaque|Level_)->Left|(Opaque|Level_),Expand->Right|Opaque,Opaque->dep_orderk1k2|Level_,Opaque->Left|Opaque,Level_->Right|Leveln1,Leveln2->ifInt.equaln1n2thendep_orderk1k2elseifn1<n2thenLeftelseRight(* Unfold the first constant only if it is "more transparent" than the
second one. In case of tie, use the recommended default. *)letoracle_orderol2rk1k2=matchoracle_compareok1k2with|Left->true|Right->false|Same->l2r