Skip to content

Commit

Permalink
clarify env rewindin
Browse files Browse the repository at this point in the history
  • Loading branch information
gares committed Mar 3, 2023
1 parent 6d01ae7 commit c0f48be
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 22 deletions.
49 changes: 36 additions & 13 deletions src/coq_elpi_HOAS.ml
Original file line number Diff line number Diff line change
Expand Up @@ -758,9 +758,13 @@ module CoqEngine_HOAS : sig

val engine : coq_engine S.component

val from_env_keep_univ_of_sigma : Environ.env -> Evd.evar_map -> coq_engine
val from_env_sigma : Environ.env -> Evd.evar_map -> coq_engine

(* when the env changes under the hood, we can adapt sigma or drop it but keep
its constraints *)
val from_env_keep_univ_of_sigma : env0:Environ.env -> env:Environ.env -> Evd.evar_map -> coq_engine
val from_env_keep_univ_and_sigma : env0:Environ.env -> env:Environ.env -> Evd.evar_map -> coq_engine

end = struct

let pp_coq_engine ?with_univs fmt { sigma } =
Expand All @@ -776,10 +780,18 @@ let show_coq_engine ?with_univs e = Format.asprintf "%a" (pp_coq_engine ?with_un

let from_env env = from_env_sigma env (Evd.from_env env)

let from_env_keep_univ_of_sigma env sigma0 =
let from_env_keep_univ_and_sigma ~env0 ~env sigma0 =
assert(env0 != env);
let uctx = UState.update_sigma_univs (Evd.evar_universe_context sigma0) (Environ.universes env) in
let uctx = UState.demote_global_univs env uctx in
from_env_sigma env (Evd.set_universe_context sigma0 uctx)

let from_env_keep_univ_of_sigma ~env0 ~env sigma0 =
assert(env0 != env);
let uctx = UState.update_sigma_univs (Evd.evar_universe_context sigma0) (Environ.universes env) in
let sigma = Evd.from_ctx (UState.demote_global_univs env uctx) in
from_env_sigma env sigma
let uctx = UState.demote_global_univs env uctx in
from_env_sigma env (Evd.from_ctx uctx)

let init () = from_env (Global.env ())

let engine : coq_engine S.component =
Expand Down Expand Up @@ -1986,11 +1998,13 @@ and create_evar_unknown ~calldepth syntactic_constraints (coq_ctx : 'a coq_conte

let state, (k, kty) = S.update_return engine state (fun ({ sigma } as e) ->
let sigma, (ty, _) = Evarutil.new_type_evar ~naming:(Namegen.IntroFresh (Names.Id.of_string "e")) env sigma Evd.univ_rigid in
let ty_key, _ = EConstr.destEvar sigma ty in
if on_ty then
{ e with sigma }, (fst (EConstr.destEvar sigma ty), None)
{ e with sigma }, (ty_key, None)
else
let sigma, t = Evarutil.new_evar ~typeclass_candidate:false ~naming:(Namegen.IntroFresh (Names.Id.of_string "e")) env sigma ty in
{ e with sigma }, (fst (EConstr.destEvar sigma t), Some (fst (EConstr.destEvar sigma ty)))) in
let t_key, _ = EConstr.destEvar sigma t in
{ e with sigma }, (t_key, Some ty_key)) in
(*let state = S.update UVMap.uvmap state (UVMap.add elpi_evk k) in*)
let state, gls_kty =
match kty with
Expand Down Expand Up @@ -2046,22 +2060,31 @@ let grab_global_env state =
if env == env0 then state
else
if Environ.universes env0 == Environ.universes env then
let state = S.set engine state (CoqEngine_HOAS.from_env_sigma env (Evd.from_ctx (Evd.evar_universe_context (get_sigma state)))) in
let state = UVMap.empty state in
let state = S.set engine state (CoqEngine_HOAS.from_env_sigma env (get_sigma state)) in
(*let state = UVMap.empty state in*)
state
else
let state = S.set engine state (CoqEngine_HOAS.from_env_keep_univ_of_sigma env (get_sigma state)) in
let state = UVMap.empty state in
let state = S.set engine state (CoqEngine_HOAS.from_env_keep_univ_and_sigma ~env0 ~env (get_sigma state)) in
(*let state = UVMap.empty state in*)
state
let grab_global_env_drop_univs state =
let grab_global_env_drop_univs_and_sigma state =
let env0 = get_global_env state in
let env = Global.env () in
if env == get_global_env state then state
if env == env0 then state
else
let state = S.set engine state (CoqEngine_HOAS.from_env_sigma env (Evd.from_env env)) in
let state = UVMap.empty state in
state


let grab_global_env_drop_sigma state =
let env0 = get_global_env state in
let env = Global.env () in
if env == env0 then state
else
let state = S.set engine state (CoqEngine_HOAS.from_env_keep_univ_of_sigma ~env0 ~env (get_sigma state)) in
let state = UVMap.empty state in
state


let solvec = E.Constants.declare_global_symbol "solve"
let msolvec = E.Constants.declare_global_symbol "msolve"
Expand Down
3 changes: 2 additions & 1 deletion src/coq_elpi_HOAS.mli
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ val body_of_constant :
State.t * EConstr.t option * Univ.Instance.t option

val grab_global_env : State.t -> State.t
val grab_global_env_drop_univs : State.t -> State.t
val grab_global_env_drop_univs_and_sigma : State.t -> State.t
val grab_global_env_drop_sigma : State.t -> State.t

val mk_decl : depth:int -> Name.t -> ty:term -> term
(* Adds an Arg for the normal form with ctx_len context entry vars in scope *)
Expand Down
9 changes: 4 additions & 5 deletions src/coq_elpi_builtins.ml
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ let on_global_state ?(abstract_exception=false) ?options api thunk = (); (fun st
Coq_elpi_utils.err Pp.(strbrk ("API " ^ api ^ " cannot be used in tactics"));
let state, result, gls = thunk state in
match options with
| Some { keepunivs = Some false } -> Coq_elpi_HOAS.grab_global_env_drop_univs state, result, gls
| Some { keepunivs = Some false } -> Coq_elpi_HOAS.grab_global_env_drop_univs_and_sigma state, result, gls
| _ -> Coq_elpi_HOAS.grab_global_env state, result, gls)

(* This is for stuff that is not monotonic in the env, eg section closing *)
let on_global_state_does_rewind_env api thunk = (); (fun state ->
if State.get tactic_mode state then
Coq_elpi_utils.err Pp.(strbrk ("API " ^ api ^ " cannot be used in tactics"));
let state, result, gls = thunk state in
Coq_elpi_HOAS.grab_global_env_drop_univs state, result, gls)
Coq_elpi_HOAS.grab_global_env_drop_sigma state, result, gls)

let warn_if_contains_univ_levels ~depth t =
let global_univs = UGraph.domain (Environ.universes (Global.env ())) in
Expand Down Expand Up @@ -1988,7 +1988,7 @@ coq.env.begin-module Name MP :-
MLCode(Pred("coq.env.end-module",
Out(modpath, "ModPath",
Full(unit_ctx, "end the current module that becomes known as ModPath *E*")),
(fun _ ~depth _ _ -> on_global_state "coq.env.end-module" (fun state ->
(fun _ ~depth _ _ -> on_global_state_does_rewind_env "coq.env.end-module" (fun state ->
let mp = Declaremods.end_module () in
state, !: mp, []))),
DocAbove);
Expand Down Expand Up @@ -2023,7 +2023,7 @@ coq.env.begin-module-type Name :-
MLCode(Pred("coq.env.end-module-type",
Out(modtypath, "ModTyPath",
Full(unit_ctx, "end the current module type that becomes known as ModPath *E*")),
(fun _ ~depth _ _ -> on_global_state "coq.env.end-module-type" (fun state ->
(fun _ ~depth _ _ -> on_global_state_does_rewind_env "coq.env.end-module-type" (fun state ->
let mp = Declaremods.end_modtype () in
state, !: mp, []))),
DocAbove);
Expand Down Expand Up @@ -3476,7 +3476,6 @@ fold_left over the terms, letin body comes before the type).
proofview pv in

Declare.Internal.export_side_effects (Evd.eval_side_effects sigma);
let sigma = Evd.drop_side_effects sigma in

let state, assignments = set_current_sigma ~depth state sigma in
state, !: subgoals, assignments
Expand Down
7 changes: 4 additions & 3 deletions tests/test_ltac3.v
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

From elpi Require Export elpi.
From Coq Require Import ssreflect ssrfun ssrbool.

Ltac ltac_foo := cut True; [ abstract trivial | idtac].
Ltac ltac_foo := cut True; [ idtac | abstract (exact I) ].

Record fooType := Foo { sort :> Type; }.
Canonical unit_fooType := Foo unit.
Expand All @@ -16,8 +17,8 @@ solve (goal _ _ _ _ [_] as G) GS :-
}}.
Elpi Typecheck.

Goal True.
Goal nat.
Proof.
elpi fail_foo ([the fooType of unit : Type]).
exact I.
exact (fun _ => 0).
Qed.

0 comments on commit c0f48be

Please sign in to comment.