Skip to content

Commit aaa3656

Browse files
committed
Support for cumul and non-cumulative inductives
1 parent b305f80 commit aaa3656

File tree

6 files changed

+110
-87
lines changed

6 files changed

+110
-87
lines changed

builtin-doc/coq-builtin.elpi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,7 @@ external pred coq.univ-instance.unify-leq i:gref, i:univ-instance,
10781078
% @udecl-cumul! macros). Note that only inductive types can be
10791079
% declared as cumulative.
10801080

1081-
% Constraint between two universes level variables
1081+
% Constraint between two universes
10821082
kind univ-constraint type.
10831083
type le univ -> univ -> univ-constraint.
10841084
type eq univ -> univ -> univ-constraint.
@@ -1090,16 +1090,16 @@ type covariant univ.variable -> univ-variance.
10901090
type invariant univ.variable -> univ-variance.
10911091
type irrelevant univ.variable -> univ-variance.
10921092

1093-
% Constraints for a non-cumulative declaration. Boolean tt means loose
1093+
% Constraints for a polymorphic, non-cumulative declaration. Boolean tt means loose
10941094
% (e.g. the '+' in f@{u v + | u < v +})
10951095
kind upoly-decl type.
10961096
type upoly-decl list univ.variable -> bool -> list univ-constraint ->
10971097
bool -> upoly-decl.
10981098

1099-
% Constraints for a cumulative declaration. Boolean tt means loose (e.g.
1099+
% Constraints for a polymorphic cumulative declaration. Boolean tt means loose (e.g.
11001100
% the '+' in f@{u v + | u < v +})
11011101
kind upoly-decl-cumul type.
1102-
type upoly-decl-cumul list univ-variance -> bool ->
1102+
type upoly-decl-cumul list univ.variable -> bool ->
11031103
list univ-constraint -> bool -> upoly-decl-cumul.
11041104

11051105
% -- Primitive --------------------------------------------------------

elpi/coq-lib.elpi

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,16 +199,17 @@ coq.upoly-decl.complete-constraints (upoly-decl VS LV CS LC) (upoly-decl VS LV C
199199
].
200200
pred coq.upoly-decl-cumul.complete-constraints i:upoly-decl-cumul, o:upoly-decl-cumul.
201201
coq.upoly-decl-cumul.complete-constraints (upoly-decl-cumul VS LV CS LC) (upoly-decl-cumul VS LV CS1 LC) :- std.do! [
202-
std.map VS coq.upoly-decl-cumul.complete-constraints.aux ExtraL,
202+
% std.map VS coq.upoly-decl-cumul.complete-constraints.aux ExtraL,
203+
std.map VS coq.univ.variable.constraints ExtraL,
203204
std.flatten ExtraL Extra,
204205
std.filter Extra (c\not(std.mem CS c)) New,
205206
std.append CS New CS1,
206207
].
207-
pred coq.upoly-decl-cumul.complete-constraints.aux i:univ-variance, o:list univ-constraint.
208-
coq.upoly-decl-cumul.complete-constraints.aux (auto V) CS :- coq.univ.variable.constraints V CS.
209-
coq.upoly-decl-cumul.complete-constraints.aux (covariant V) CS :- coq.univ.variable.constraints V CS.
210-
coq.upoly-decl-cumul.complete-constraints.aux (invariant V) CS :- coq.univ.variable.constraints V CS.
211-
coq.upoly-decl-cumul.complete-constraints.aux (irrelevant V) CS :- coq.univ.variable.constraints V CS.
208+
% pred coq.upoly-decl-cumul.complete-constraints.aux i:univ-variance, o:list univ-constraint.
209+
% coq.upoly-decl-cumul.complete-constraints.aux (auto V) CS :- coq.univ.variable.constraints V CS.
210+
% coq.upoly-decl-cumul.complete-constraints.aux (covariant V) CS :- coq.univ.variable.constraints V CS.
211+
% coq.upoly-decl-cumul.complete-constraints.aux (invariant V) CS :- coq.univ.variable.constraints V CS.
212+
% coq.upoly-decl-cumul.complete-constraints.aux (irrelevant V) CS :- coq.univ.variable.constraints V CS.
212213

213214

214215
pred coq.build-indt-decl

src/rocq_elpi_HOAS.ml

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ let universe_level_variable =
207207
let universe_constraint : Univ.univ_constraint API.Conversion.t =
208208
let open API.Conversion in let open API.AlgebraicData in declare {
209209
ty = TyName "univ-constraint";
210-
doc = "Constraint between two universes level variables";
210+
doc = "Constraint between two universes";
211211
pp = (fun fmt _ -> Format.fprintf fmt "<todo>");
212212
constructors = [
213213
K("le","",A(univ,A(univ,N)),
@@ -240,20 +240,28 @@ let universe_variance : (Univ.Level.t * UVars.Variance.t option) API.Conversion.
240240
]
241241
} |> API.ContextualConversion.(!<)
242242

243-
type universe_decl = (Univ.Level.t list * bool) * (Univ.Constraints.t * bool)
244-
let universe_decl : universe_decl API.Conversion.t =
245-
let open API.Conversion in let open API.BuiltInData in let open API.AlgebraicData in let open Elpi.Builtin in declare {
243+
let universe_decl : UState.universe_decl API.Conversion.t =
244+
let open API.Conversion in let open API.BuiltInData in let open API.AlgebraicData in let open Elpi.Builtin in
245+
let open UState in declare {
246246
ty = TyName "upoly-decl";
247-
doc = "Constraints for a non-cumulative declaration. Boolean tt means loose (e.g. the '+' in f@{u v + | u < v +})";
247+
doc = "Constraints for a polymorphic declaration. Boolean tt means loose (e.g. the '+' in f@{u v + | u < v +})";
248248
pp = (fun fmt _ -> Format.fprintf fmt "<todo>");
249249
constructors = [
250250
K("upoly-decl","",A(list universe_level_variable,A(bool,A(list universe_constraint,A(bool,N)))),
251-
B (fun x sx y sy-> (x,sx),(Univ.Constraints.of_list y,sy)),
252-
M (fun ~ok ~ko:_ ((x,sx),(y,sy)) -> ok x sx (Univ.Constraints.elements y) sy))
251+
B (fun x sx y sy ->
252+
{ univdecl_qualities = []; univdecl_extensible_qualities = false;
253+
univdecl_instance = x; univdecl_extensible_instance = sx;
254+
univdecl_variances = None;
255+
univdecl_constraints = Univ.Constraints.of_list y;
256+
univdecl_extensible_constraints = sy }),
257+
M (fun ~ok ~ko:_ x ->
258+
ok x.univdecl_instance x.univdecl_extensible_instance
259+
(Univ.Constraints.elements x.univdecl_constraints)
260+
x.univdecl_extensible_constraints))
253261
]
254262
} |> API.ContextualConversion.(!<)
255263

256-
type universe_decl_cumul = ((Univ.Level.t * UVars.Variance.t option) list * bool) * (Univ.Constraints.t * bool)
264+
(* type universe_decl_cumul = ((Univ.Level.t * UVars.Variance.t option) list * bool) * (Univ.Constraints.t * bool)
257265
let universe_decl_cumul : universe_decl_cumul API.Conversion.t =
258266
let open API.Conversion in let open API.BuiltInData in let open API.AlgebraicData in let open Elpi.Builtin in declare {
259267
ty = TyName "upoly-decl-cumul";
@@ -264,7 +272,7 @@ let universe_decl_cumul : universe_decl_cumul API.Conversion.t =
264272
B (fun x sx y sy -> ((x,sx),(Univ.Constraints.of_list y,sy))),
265273
M (fun ~ok ~ko:_ ((x,sx),(y,sy)) -> ok x sx (Univ.Constraints.elements y) sy))
266274
]
267-
} |> API.ContextualConversion.(!<)
275+
} |> API.ContextualConversion.(!<) *)
268276

269277
let collapse_to_type_sigma sigma s =
270278
match s with
@@ -305,8 +313,8 @@ type uinstanceoption =
305313
(* a variable was provided, the command will compute the instance to unify with it *)
306314
type universe_decl_option =
307315
| NotUniversePolymorphic
308-
| Cumulative of universe_decl_cumul
309-
| NonCumulative of universe_decl
316+
| Cumulative of UState.universe_decl
317+
| NonCumulative of UState.universe_decl
310318
type options = {
311319
hoas_holes : hole_mapping option;
312320
local : bool option;
@@ -1127,6 +1135,9 @@ let in_elpiast_sort ~loc state s =
11271135

11281136
let get_sigma s = (S.get engine s).sigma
11291137
let update_sigma s f = (S.update engine s (fun e -> { e with sigma = f e.sigma }))
1138+
let update_return_sigma s f =
1139+
(S.update_return engine s (fun e -> let sigma, r = f e.sigma in
1140+
{ e with sigma }, r))
11301141
let get_global_env s = (S.get engine s).global_env
11311142

11321143
let declare_evc = E.Constants.declare_global_symbol "declare-evar"
@@ -1299,7 +1310,7 @@ let get_options ~depth hyps state =
12991310
| None, None -> NotUniversePolymorphic
13001311
| Some _, Some _ -> err Pp.(str"Conflicting attributes: @udecl! and @udecl-cumul! (or @univpoly! and @univpoly-cumul!)")
13011312
| Some (t,depth), None ->
1302-
let _, ud, gl = universe_decl_cumul.Elpi.API.Conversion.readback ~depth state t in
1313+
let _, ud, gl = universe_decl.Elpi.API.Conversion.readback ~depth state t in
13031314
assert (gl = []);
13041315
Cumulative ud
13051316
| None, Some (t,depth) ->
@@ -1733,10 +1744,9 @@ let evar_arity k state =
17331744
u < FOO.123
17341745
even if u is a binder, and FOO.123 is not.
17351746
Hence this is disabled. *)
1736-
let minimize_universes state = state (*
1747+
let minimize_universes state =
17371748
S.update engine state (fun ({ sigma } as x) ->
17381749
{ x with sigma = Evd.minimize_universes sigma })
1739-
*)
17401750

17411751
let is_sort ~depth x =
17421752
match E.look ~depth x with
@@ -3003,16 +3013,8 @@ let mk_universe_decl univdecl_extensible_instance univdecl_extensible_constraint
30033013
let poly_cumul_udecl_variance_of_options state options =
30043014
match options.universe_decl with
30053015
| NotUniversePolymorphic -> state, false, false, UState.default_univ_decl, None
3006-
| Cumulative ((univ_lvlt_var,univdecl_extensible_instance),(univdecl_constraints,univdecl_extensible_constraints)) ->
3007-
let univdecl_instance, variance = List.split univ_lvlt_var in
3008-
state, true, true,
3009-
mk_universe_decl univdecl_extensible_instance univdecl_extensible_constraints univdecl_constraints univdecl_instance,
3010-
Some (Array.of_list variance)
3011-
| NonCumulative((univ_lvlt,univdecl_extensible_instance),(univdecl_constraints,univdecl_extensible_constraints)) ->
3012-
let univdecl_instance = univ_lvlt in
3013-
state, true, false,
3014-
mk_universe_decl univdecl_extensible_instance univdecl_extensible_constraints univdecl_constraints univdecl_instance,
3015-
None
3016+
| Cumulative udecl -> state, true, true, udecl, None
3017+
| NonCumulative udecl -> state, true, false, udecl, None
30163018

30173019
[%%if coq = "8.20"]
30183020
let comInductive_interp_mutual_inductive_constr ~cumulative ~poly ~template ~finite =
@@ -3143,9 +3145,8 @@ let lp2inductive_entry ~depth coq_ctx constraints state t =
31433145
let open Context.Rel.Declaration in
31443146
LocalAssum(nameR itname, EConstr.it_mkProd_or_LetIn arity (nuparams @ params)) in
31453147
let env_ar_params = (Global.env ()) |> EC.push_rel the_type |> EC.push_rel_context (nuparams @ params) in
3146-
3147-
(* restruction to used universes *)
3148-
let state = minimize_universes state in
3148+
(* restriction to used universes *)
3149+
31493150
let used =
31503151
List.fold_left (fun acc t ->
31513152
Univ.Level.Set.union acc
@@ -3530,6 +3531,18 @@ let inductive_decl2lp ~depth coq_ctx constraints state (mutind,uinst,(mind,ind),
35303531
hoas_ind2lp ~depth coq_ctx state ind
35313532
;;
35323533

3534+
let udecl_of_entry vars csts variances loose_udecl =
3535+
let open UState in
3536+
let of_variances variances =
3537+
let variances = UVars.Variances.repr variances in
3538+
let variances = Array.map (fun v -> Some (UVars.VarianceOccurrence.typing_variances v)) variances in
3539+
variances
3540+
in
3541+
{ univdecl_qualities = []; univdecl_extensible_qualities = loose_udecl;
3542+
univdecl_instance = vars; univdecl_extensible_instance = loose_udecl;
3543+
univdecl_variances = Option.map of_variances variances;
3544+
univdecl_constraints = csts; univdecl_extensible_constraints = loose_udecl }
3545+
35333546
let upoly_decl_of ~depth state ~loose_udecl mie =
35343547
let open Entries in
35353548
match mie.mind_entry_universes with
@@ -3542,14 +3555,13 @@ let upoly_decl_of ~depth state ~loose_udecl mie =
35423555
let csts = UVars.UContext.constraints uc in
35433556
begin match variances with
35443557
| None | Some Infer_variances ->
3545-
let state, up, gls = universe_decl.API.Conversion.embed ~depth state ((Array.to_list vars,loose_udecl),(csts,loose_udecl)) in
3558+
let udecl = udecl_of_entry (Array.to_list vars) csts None loose_udecl in
3559+
let state, up, gls = universe_decl.API.Conversion.embed ~depth state udecl in
35463560
state, (fun i -> E.mkApp uideclc i [up]), gls
35473561
| Some (Check_variances variance) ->
3548-
let variance = UVars.Variances.repr variance in
3549-
assert(Array.length variance = Array.length vars);
3550-
let uv = Array.map2 (fun x y -> (x,Some (UVars.VarianceOccurrence.typing_variances y))) vars variance |> Array.to_list in
3551-
let state, up, gls = universe_decl_cumul.API.Conversion.embed ~depth state ((uv,loose_udecl),(csts,loose_udecl)) in
3552-
state, (fun i -> E.mkApp uideclc i [up]), gls
3562+
let udecl = udecl_of_entry (Array.to_list vars) csts (Some variance) loose_udecl in
3563+
let state, up, gls = universe_decl.API.Conversion.embed ~depth state udecl in
3564+
state, (fun i -> E.mkApp uideclc i [up]), gls
35533565
end
35543566
| Monomorphic_ind_entry -> state, (fun i -> E.mkApp ideclc i []), []
35553567

src/rocq_elpi_HOAS.mli

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,10 @@ type uinstanceoption =
2424
| VarInstance of (FlexibleData.Elpi.t * RawData.term list * inv_rel_key)
2525
(* a variable was provided, the command will compute the instance to unify with it *)
2626

27-
type universe_decl = (Univ.Level.t list * bool) * (Univ.Constraints.t * bool)
28-
type universe_decl_cumul = ((Univ.Level.t * UVars.Variance.t option) list * bool) * (Univ.Constraints.t * bool)
2927
type universe_decl_option =
3028
| NotUniversePolymorphic
31-
| Cumulative of universe_decl_cumul
32-
| NonCumulative of universe_decl
29+
| Cumulative of UState.universe_decl
30+
| NonCumulative of UState.universe_decl
3331

3432
type options = {
3533
hoas_holes : hole_mapping option;
@@ -223,8 +221,7 @@ val uinstance : UVars.Instance.t Conversion.t
223221

224222
val universe_constraint : Univ.univ_constraint Conversion.t
225223
val universe_variance : (Univ.Level.t * UVars.Variance.t option) Conversion.t
226-
val universe_decl : universe_decl Conversion.t
227-
val universe_decl_cumul : universe_decl_cumul Conversion.t
224+
val universe_decl : UState.universe_decl Conversion.t
228225

229226
module GRMap : Elpi.API.Utils.Map.S with type key = Names.GlobRef.t
230227
module GRSet : Elpi.API.Utils.Set.S with type elt = Names.GlobRef.t
@@ -317,6 +314,7 @@ val mk_def :
317314
val get_global_env : State.t -> Environ.env
318315
val get_sigma : State.t -> Evd.evar_map
319316
val update_sigma : State.t -> (Evd.evar_map -> Evd.evar_map) -> State.t
317+
val update_return_sigma : State.t -> (Evd.evar_map -> Evd.evar_map * 'a) -> State.t * 'a
320318

321319
type hyp = { ctx_entry : term; depth : int }
322320

0 commit comments

Comments
 (0)