123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180(*************************************************************************)(* Copyright 2015-2019 MINES ParisTech -- Dual License LGPL 2.1+ / GPL3+ *)(* Copyright 2019-2024 Inria -- Dual License LGPL 2.1+ / GPL3+ *)(* Copyright 2024-2025 Emilio J. Gallego Arias -- LGPL 2.1+ / GPL3+ *)(* Copyright 2025 CNRS -- LGPL 2.1+ / GPL3+ *)(* Written by: Emilio J. Gallego Arias & coq-lsp contributors *)(*************************************************************************)(* Rocq Language Server Protocol: Rocq State API *)(*************************************************************************)typet=Vernacstate.t(* EJGA: This requires patches to Coq, they are in the lsp_debug branch
let any_out oc (a : Summary.Frozen.any) = (* let (Summary.Frozen.Any (tag,
_value)) = a in *) (* let name = Summary.Dyn.repr tag in *) (*
Lsp.Io.log_error "marshall" name; *) Marshal.to_channel oc a []
let _frozen_out oc (s : Summary.Frozen.t) = Summary.Frozen.iter (any_out oc)
s
let summary_out oc (s : Summary.frozen) = let { Summary.summaries; ml_module
} = s in (* frozen_out oc summaries; *) Marshal.to_channel oc summaries [];
Marshal.to_channel oc ml_module []; ()
let summary_in ic : Summary.frozen = let summaries = Marshal.from_channel ic
in let ml_module = Marshal.from_channel ic in { Summary.summaries; ml_module
}
let system_out oc ((l : Lib.frozen), (s : Summary.frozen)) = (* Both parts of
system have functional values !! Likely due to Lib.frozen having a
Summary.frozen inside? *) Marshal.to_channel oc l [ Closures ]; summary_out
oc s; ()
let system_in ic : Vernacstate.System.t = let l : Lib.frozen =
Marshal.from_channel ic in let s : Summary.frozen = summary_in ic in (l, s)
let _marshal_out oc st = let { Vernacstate.parsing; system; lemmas; program;
opaques; shallow } = st in Marshal.to_channel oc parsing []; system_out oc
system; (* lemmas doesn't !! *) Marshal.to_channel oc lemmas [];
Marshal.to_channel oc program []; Marshal.to_channel oc opaques [];
Marshal.to_channel oc shallow []; ()
let _marshal_in ic = let parsing = Marshal.from_channel ic in let system =
system_in ic in let lemmas = Marshal.from_channel ic in let program =
Marshal.from_channel ic in let opaques = Marshal.from_channel ic in let
shallow = Marshal.from_channel ic in { Vernacstate.parsing; system; lemmas;
program; opaques; shallow } *)letmarshal_inic:t=Marshal.from_channelicletmarshal_outocst=Marshal.to_channelocst[]letof_coqx=xletto_coqx=x(* let compare x y = compare x y *)letcompare(x:t)(y:t)=letopenVernacstateinlet{synterp=ss1;interp={system=is1;lemmas=l1;program=g1;opaques=o1}}=xinlet{synterp=ss2;interp={system=is2;lemmas=l2;program=g2;opaques=o2}}=yinifss1==ss2&&is1==is2&&l1==l2&&g1==g2&&o1==o2then0else1letequalxy=comparexy=0lethashx=(* OCaml's defaults are 10, 100, but not so good for us, much improved
settings are below (best try so far) *)letmeaningful,total=(256,256)inHashtbl.hash_parammeaningfultotalx(* XXX: This should restore the state properly before calling
get_default_proof_mode, as of now promotes buggy use. *)letmode~st=Option.map(fun_->Synterp.get_default_proof_mode())st.Vernacstate.interp.lemmasletparsing~st=Vernacstate.(Synterp.parsingst.synterp)moduleProof_=ProofmoduleProof=structtypet=Vernacstate.LemmaStack.tletto_coqx=xletequalxy=x==y(* OCaml's defaults are 10, 100, we use these values as to give better
precision for petanque-like users, it should not impact interactive use but
we gotta measure it *)lethashx=letmeaningful,total=(128,256)inHashtbl.hash_parammeaningfultotalxendletlemmas~st=st.Vernacstate.interp.lemmasletprogram~st=NeList.headst.Vernacstate.interp.program|>Declare.OblState.viewletdrop_proof~st=letopenVernacstateinletinterp={st.interpwithlemmas=Option.cata(funs->snd@@Vernacstate.LemmaStack.pops)Nonest.interp.lemmas}in{stwithinterp}letdrop_all_proofs~st=letopenVernacstateinletinterp={st.interpwithlemmas=None}in{stwithinterp}letin_state~token~st~fa=letfa=Vernacstate.unfreeze_full_statest;fainProtect.eval~token~faletin_stateM~token~st~fa=letopenProtect.E.Oinlet*()=Protect.eval~token~f:Vernacstate.unfreeze_full_statestinfaletadmit~st()=let()=Vernacstate.unfreeze_full_statestinmatchst.Vernacstate.interp.lemmaswith|None->st|Somelemmas->letpm=NeList.headst.Vernacstate.interp.programinletproof,lemmas=Vernacstate.(LemmaStack.poplemmas)inletpm=Declare.Proof.save_admitted~pm~proofinletprogram=NeList.map_head(fun_->pm)st.Vernacstate.interp.programinletst=Vernacstate.freeze_full_state()in{stwithinterp={st.interpwithlemmas;program}}letadmit~token~st=Protect.eval~token~f:(admit~st)()letadmit_goal~st()=let()=Vernacstate.unfreeze_full_statestinmatchst.Vernacstate.interp.lemmaswith|None->st|Somelemmas->letfpf=Declare.Proof.byProofview.give_uppf|>fstinletlemmas=Some(Vernacstate.LemmaStack.map_top~flemmas)in{stwithinterp={st.interpwithlemmas}}letadmit_goal~token~st=Protect.eval~token~f:(admit_goal~st)()letcount_edgesuniv=letuniv=UGraph.reprunivinUniv.Level.Map.fold(fun_nodeacc->acc+matchnodewith|UGraph.Alias_->1|Nodem->Univ.Level.Map.cardinalm)univ(Univ.Level.Map.cardinaluniv)letinfo_universes~token~st=letopenProtect.E.Oinlet+univ=in_state~token~st~f:Global.universes()inletunivs=UGraph.domainunivinletnuniv=Univ.Level.Set.cardinalunivsinletnconst=count_edgesunivin(nuniv,nconst)