123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185(************************************************************************)(* * 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) *)(************************************************************************)(************************************************************************)(** {6 Tables of opaque proof terms} *)(** We now store opaque proof terms apart from the rest of the environment.
This way, we can quickly load a first half of a .vo file without these opaque
terms, and access them only when a specific command (e.g. Print or
Print Assumptions) needs it. *)type'aconst_entry_body='aEntries.proof_outputFuture.computationtype'ajoinable=|Computationof'aFuture.computation|Joinedof'atypeopaque_result=|OpaqueCertifofSafe_typing.opaque_certificatejoinableref|OpaqueValueofOpaqueproof.opaque_prooftermletforcec=match!cwith|Computationc->Future.forcec|Joinedv->v(** Current table of opaque terms *)moduleSummary=structtypet=opaque_resultOpaqueproof.HandleMap.tletstate:tref=refOpaqueproof.HandleMap.emptyletinit()=state:=Opaqueproof.HandleMap.emptyletfreeze~marshallable=ifmarshallablethenletiter_pf=matchpfwith|OpaqueCertifcert->beginmatch!certwith|Computationc->cert:=Joined(Future.forcec)|Joined_->()end|OpaqueValue_->()inlet()=Opaqueproof.HandleMap.iteriter!statein!stateelse!stateletunfreezes=state:=sletjoin?(except=Future.UUIDSet.empty)()=letiteripf=matchpfwith|OpaqueValue_->()|OpaqueCertifcert->match!certwith|Joinedcert->(* FIXME: in this case we lost the fix_exn wrapper. Does that matter? *)ifnot@@Safe_typing.is_filled_opaquei(Global.safe_env())thenGlobal.fill_opaquecert|Computationcert->ifFuture.UUIDSet.mem(Future.uuidcert)exceptthen()elseifSafe_typing.is_filled_opaquei(Global.safe_env())thenassert(Future.is_overcert)else(* Little belly dance to preserve the fix_exn wrapper around filling *)Future.force@@Future.chaincert(funcert->Global.fill_opaquecert)inOpaqueproof.HandleMap.iteriter!stateendtypeopaque_disk=Opaqueproof.opaque_prooftermoptionarrayletget_opaque_diskit=leti=Opaqueproof.repr_handleiinlet()=assert(0<=i&&i<Array.lengtht)int.(i)letset_opaque_diski(c,priv)t=leti=Opaqueproof.repr_handleiinlet()=assert(0<=i&&i<Array.lengtht)inlet()=assert(Option.is_emptyt.(i))inletc=Constr.hconscint.(i)<-Some(c,priv)letcurrent_opaques=Summary.stateletdeclare_defined_opaque?feedback_idi(body:Safe_typing.private_constantsconst_entry_body)=(* Note that the environment in which the variable is checked it the one when
the thunk is evaluated, not the one where this function is called. It does
not matter because the former must be an extension of the latter or
otherwise the call to Safe_typing would throw an anomaly. *)letproof=Future.chainbodybeginfun(body,eff)->letcert=Safe_typing.check_opaque(Global.safe_env())i(body,eff)inlet()=Option.iter(funid->Feedback.feedback~idFeedback.Complete)feedback_idincertendin(* If the proof is already computed we fill it eagerly *)let()=matchFuture.peek_valproofwith|None->()|Somecert->Global.fill_opaquecertinletproof=OpaqueCertif(ref(Computationproof))inlet()=assert(not@@Opaqueproof.HandleMap.memi!current_opaques)incurrent_opaques:=Opaqueproof.HandleMap.addiproof!current_opaquesletdeclare_private_opaqueopaque=let(i,pf)=Safe_typing.repr_exported_opaqueopaquein(* Joining was already done at private declaration time *)letproof=OpaqueValuepfinlet()=assert(not@@Opaqueproof.HandleMap.memi!current_opaques)incurrent_opaques:=Opaqueproof.HandleMap.addiproof!current_opaquesletget_current_opaquei=tryletpf=Opaqueproof.HandleMap.findi!current_opaquesinmatchpfwith|OpaqueValuepf->Somepf|OpaqueCertifcert->letc,ctx=Safe_typing.repr_certificate(forcecert)inletctx=matchctxwith|Opaqueproof.PrivateMonomorphic_->Opaqueproof.PrivateMonomorphic()|Opaqueproof.PrivatePolymorphic_asctx->ctxinSome(c,ctx)withNot_found->Noneletget_current_constraintsi=tryletpf=Opaqueproof.HandleMap.findi!current_opaquesinmatchpfwith|OpaqueValue_->None|OpaqueCertifcert->let_,ctx=Safe_typing.repr_certificate(forcecert)inletctx=matchctxwith|Opaqueproof.PrivateMonomorphicctx->ctx|Opaqueproof.PrivatePolymorphic_->Univ.ContextSet.emptyinSomectxwithNot_found->Noneletdump?(except=Future.UUIDSet.empty)()=letn=ifOpaqueproof.HandleMap.is_empty!current_opaquesthen0else(Opaqueproof.repr_handle@@fst@@Opaqueproof.HandleMap.max_binding!current_opaques)+1inletopaque_table=Array.makenNoneinletfoldhcuf2t_map=matchcuwith|OpaqueValuep->leti=Opaqueproof.repr_handlehinlet()=opaque_table.(i)<-Somepinf2t_map|OpaqueCertifc->leti=Opaqueproof.repr_handlehinletf2t_map,proof=match!cwith|Computationcert->letuid=Future.uuidcertinletf2t_map=Future.UUIDMap.adduidhf2t_mapinletc=Future.peek_valcertinlet()=ifOption.is_emptyc&&(not@@Future.UUIDSet.memuidexcept)thenCErrors.anomalyPp.(str"Proof object "++inti++str" is not checked nor to be checked")inf2t_map,c|Joinedcert->f2t_map,Somecertinletc=matchproofwith|None->None|Somecert->let(c,priv)=Safe_typing.repr_certificatecertinletpriv=matchprivwith|Opaqueproof.PrivateMonomorphic_->Opaqueproof.PrivateMonomorphic()|Opaqueproof.PrivatePolymorphic_asp->pinSome(c,priv)inlet()=opaque_table.(i)<-cinf2t_mapinletf2t_map=Opaqueproof.HandleMap.foldfold!current_opaquesFuture.UUIDMap.emptyin(opaque_table,f2t_map)