Skip to content

Commit d1d74f5

Browse files
committed
[vernac] expose inductive/record pre-processing
The syntax conflates the two declarations, but then the code paths are different and there are checks to ensure only meaningful options/attributes are passed.
1 parent 09308eb commit d1d74f5

File tree

2 files changed

+105
-33
lines changed

2 files changed

+105
-33
lines changed

vernac/vernacentries.ml

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -796,31 +796,16 @@ let vernac_record ~template udecl ~cumulative k ~poly ?typing_flags ~primitive_p
796796
let map ((is_coercion, name), binders, sort, nameopt, cfs, ido) =
797797
let idbuild = match nameopt with
798798
| None -> Nameops.add_prefix "Build_" name.v
799-
| Some lid ->
800-
let () = Dumpglob.dump_definition lid false "constr" in
801-
lid.v
799+
| Some lid -> lid.v
802800
in
803801
let default_inhabitant_id = Option.map (fun CAst.{v=id} -> id) ido in
804-
let () =
805-
if Dumpglob.dump () then
806-
let () = Dumpglob.dump_definition name false "rec" in
807-
let iter (x, _) = match x with
808-
| Vernacexpr.(AssumExpr ({loc;v=Name id}, _, _) | DefExpr ({loc;v=Name id}, _, _, _)) ->
809-
Dumpglob.dump_definition (make ?loc id) false "proj"
810-
| _ -> ()
811-
in
812-
List.iter iter cfs
813-
in
814802
Record.Ast.{ name; is_coercion; binders; cfs; idbuild; sort; default_inhabitant_id }
815803
in
816804
let records = List.map map records in
817805
match typing_flags with
818806
| Some _ ->
819807
CErrors.user_err (Pp.str "Typing flags are not yet supported for records.")
820-
| None ->
821-
let _ : _ list =
822-
Record.definition_structure ~template udecl k ~cumulative ~poly ~primitive_proj finite records in
823-
()
808+
| None -> records
824809

825810
let extract_inductive_udecl (indl:(inductive_expr * decl_notation list) list) =
826811
match indl with
@@ -866,7 +851,33 @@ let primitive_proj =
866851
| Some t -> return t
867852
| None -> return (primitive_flag ())
868853

869-
let vernac_inductive ~atts kind indl =
854+
module Preprocessed_Mind_decl = struct
855+
type flags = {
856+
template : bool option;
857+
udecl : Constrexpr.cumul_univ_decl_expr option;
858+
cumulative : bool;
859+
poly : bool;
860+
finite : Declarations.recursivity_kind;
861+
}
862+
type record = {
863+
flags : flags;
864+
primitive_proj : bool;
865+
kind : Vernacexpr.inductive_kind;
866+
records : Record.Ast.t list;
867+
}
868+
type inductive = {
869+
flags : flags;
870+
typing_flags : Declarations.typing_flags option;
871+
private_ind : bool;
872+
uniform : ComInductive.uniform_inductive_flag;
873+
inductives : (Vernacexpr.one_inductive_expr * Vernacexpr.decl_notation list) list;
874+
}
875+
type t =
876+
| Record of record
877+
| Inductive of inductive
878+
end
879+
880+
let preprocess_inductive_decl ~atts kind indl =
870881
let udecl, indl = extract_inductive_udecl indl in
871882
let is_defclass = match kind, indl with
872883
| Class _, [ ( id , bl , c , Constructors [l]), [] ] -> Some (id, bl, c, l)
@@ -895,16 +906,6 @@ let vernac_inductive ~atts kind indl =
895906
++ private_ind ++ typing_flags ++ prim_proj_attr)
896907
atts)
897908
in
898-
if Dumpglob.dump () then
899-
List.iter (fun (((coe,lid), _, _, cstrs), _) ->
900-
match cstrs with
901-
| Constructors cstrs ->
902-
Dumpglob.dump_definition lid false "ind";
903-
List.iter (fun (_, (lid, _)) ->
904-
Dumpglob.dump_definition lid false "constr") cstrs
905-
| _ -> () (* dumping is done by vernac_record (called below) *) )
906-
indl;
907-
908909
if Option.has_some is_defclass then
909910
(* Definitional class case *)
910911
let (id, bl, c, l) = Option.get is_defclass in
@@ -918,8 +919,10 @@ let vernac_inductive ~atts kind indl =
918919
let coe' = if coe then BackInstance else NoInstance in
919920
let f = AssumExpr ((make ?loc:lid.loc @@ Name lid.v), [], ce),
920921
{ rf_subclass = coe' ; rf_priority = None ; rf_notation = [] ; rf_canonical = true } in
921-
vernac_record ~template udecl ~cumulative (Class true) ~poly ?typing_flags ~primitive_proj
922-
finite [id, bl, c, None, [f], None]
922+
let recordl = [id, bl, c, None, [f], None] in
923+
let kind = Class true in
924+
let records = vernac_record ~template udecl ~cumulative kind ~poly ?typing_flags ~primitive_proj finite recordl in
925+
indl, Preprocessed_Mind_decl.(Record { flags = { template; udecl; cumulative; poly; finite; }; primitive_proj; kind; records })
923926
else if List.for_all is_record indl then
924927
(* Mutual record case *)
925928
let () = match kind with
@@ -944,7 +947,8 @@ let vernac_inductive ~atts kind indl =
944947
in
945948
let kind = match kind with Class _ -> Class false | _ -> kind in
946949
let recordl = List.map unpack indl in
947-
vernac_record ~template udecl ~cumulative kind ~poly ?typing_flags ~primitive_proj finite recordl
950+
let records = vernac_record ~template udecl ~cumulative kind ~poly ?typing_flags ~primitive_proj finite recordl in
951+
indl, Preprocessed_Mind_decl.(Record { flags = { template; udecl; cumulative; poly; finite; }; primitive_proj; kind; records })
948952
else if List.for_all is_constructor indl then
949953
(* Mutual inductive case *)
950954
let () = match kind with
@@ -966,11 +970,46 @@ let vernac_inductive ~atts kind indl =
966970
| Constructors l -> (id, bl, c, l), ntn
967971
| RecordDecl _ -> assert false (* ruled out above *)
968972
in
969-
let indl = List.map unpack indl in
973+
let inductives = List.map unpack indl in
970974
let uniform = should_treat_as_uniform () in
971-
ComInductive.do_mutual_inductive ~template udecl indl ~cumulative ~poly ?typing_flags ~private_ind ~uniform finite
975+
indl, Preprocessed_Mind_decl.(Inductive { flags = { template; udecl; cumulative; poly; finite }; typing_flags; private_ind; uniform; inductives })
972976
else
973977
user_err (str "Mixed record-inductive definitions are not allowed.")
978+
;;
979+
980+
981+
let vernac_inductive ~atts kind indl =
982+
let open Preprocessed_Mind_decl in
983+
let indl_for_glob, decl = preprocess_inductive_decl ~atts kind indl in
984+
if Dumpglob.dump () then
985+
List.iter (fun (((coe,lid), _, _, cstrs), _) ->
986+
match cstrs with
987+
| Constructors cstrs ->
988+
Dumpglob.dump_definition lid false "ind";
989+
List.iter (fun (_, (lid, _)) ->
990+
Dumpglob.dump_definition lid false "constr") cstrs
991+
| _ -> ())
992+
indl_for_glob;
993+
match decl with
994+
| Record { flags = { template; udecl; cumulative; poly; finite; }; kind; primitive_proj; records } ->
995+
let () =
996+
if Dumpglob.dump () then
997+
let dump_glob_proj (x, _) = match x with
998+
| Vernacexpr.(AssumExpr ({loc;v=Name id}, _, _) | DefExpr ({loc;v=Name id}, _, _, _)) ->
999+
Dumpglob.dump_definition (make ?loc id) false "proj"
1000+
| _ -> () in
1001+
records |> List.iter (fun { Record.Ast.cfs; name } ->
1002+
let () = Dumpglob.dump_definition name false "rec" in
1003+
List.iter dump_glob_proj cfs)
1004+
in
1005+
let _ : _ list =
1006+
Record.definition_structure ~template udecl kind ~cumulative ~poly ~primitive_proj finite records in
1007+
()
1008+
| Inductive { flags = { template; udecl; cumulative; poly; finite; }; typing_flags; private_ind; uniform; inductives } ->
1009+
ComInductive.do_mutual_inductive ~template udecl inductives ~cumulative ~poly ?typing_flags ~private_ind ~uniform finite
1010+
;;
1011+
let preprocess_inductive_decl ~atts kind indl =
1012+
snd @@ preprocess_inductive_decl ~atts kind indl
9741013

9751014
let vernac_fixpoint_common ~atts discharge l =
9761015
if Dumpglob.dump () then

vernac/vernacentries.mli

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,36 @@ val interp_redexp_hook : (Environ.env -> Evd.evar_map -> Genredexpr.raw_red_expr
2727
val command_focus : unit Proof.focus_kind
2828

2929
val allow_sprop_opt_name : string list
30+
31+
(** pre-processing and validation of VernacInductive *)
32+
module Preprocessed_Mind_decl : sig
33+
type flags = {
34+
template : bool option;
35+
udecl : Constrexpr.cumul_univ_decl_expr option;
36+
cumulative : bool;
37+
poly : bool;
38+
finite : Declarations.recursivity_kind;
39+
}
40+
type record = {
41+
flags : flags;
42+
primitive_proj : bool;
43+
kind : Vernacexpr.inductive_kind;
44+
records : Record.Ast.t list;
45+
}
46+
type inductive = {
47+
flags : flags;
48+
typing_flags : Declarations.typing_flags option;
49+
private_ind : bool;
50+
uniform : ComInductive.uniform_inductive_flag;
51+
inductives : (Vernacexpr.one_inductive_expr * Vernacexpr.decl_notation list) list;
52+
}
53+
type t =
54+
| Record of record
55+
| Inductive of inductive
56+
end
57+
58+
val preprocess_inductive_decl
59+
: atts:Attributes.vernac_flags
60+
-> Vernacexpr.inductive_kind
61+
-> (Vernacexpr.inductive_expr * Vernacexpr.decl_notation list) list
62+
-> Preprocessed_Mind_decl.t

0 commit comments

Comments
 (0)