Skip to content

Commit 4de4597

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 e78b3c9 commit 4de4597

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
@@ -799,31 +799,16 @@ let vernac_record ~template udecl ~cumulative k ~poly ?typing_flags ~primitive_p
799799
let map ((is_coercion, name), binders, sort, nameopt, cfs, ido) =
800800
let idbuild = match nameopt with
801801
| None -> Nameops.add_prefix "Build_" name.v
802-
| Some lid ->
803-
let () = Dumpglob.dump_definition lid false "constr" in
804-
lid.v
802+
| Some lid -> lid.v
805803
in
806804
let default_inhabitant_id = Option.map (fun CAst.{v=id} -> id) ido in
807-
let () =
808-
if Dumpglob.dump () then
809-
let () = Dumpglob.dump_definition name false "rec" in
810-
let iter (x, _) = match x with
811-
| Vernacexpr.(AssumExpr ({loc;v=Name id}, _, _) | DefExpr ({loc;v=Name id}, _, _, _)) ->
812-
Dumpglob.dump_definition (make ?loc id) false "proj"
813-
| _ -> ()
814-
in
815-
List.iter iter cfs
816-
in
817805
Record.Ast.{ name; is_coercion; binders; cfs; idbuild; sort; default_inhabitant_id }
818806
in
819807
let records = List.map map records in
820808
match typing_flags with
821809
| Some _ ->
822810
CErrors.user_err (Pp.str "Typing flags are not yet supported for records.")
823-
| None ->
824-
let _ : _ list =
825-
Record.definition_structure ~template udecl k ~cumulative ~poly ~primitive_proj finite records in
826-
()
811+
| None -> records
827812

828813
let extract_inductive_udecl (indl:(inductive_expr * decl_notation list) list) =
829814
match indl with
@@ -869,7 +854,33 @@ let primitive_proj =
869854
| Some t -> return t
870855
| None -> return (primitive_flag ())
871856

872-
let vernac_inductive ~atts kind indl =
857+
module Preprocessed_Mind_decl = struct
858+
type flags = {
859+
template : bool option;
860+
udecl : Constrexpr.cumul_univ_decl_expr option;
861+
cumulative : bool;
862+
poly : bool;
863+
finite : Declarations.recursivity_kind;
864+
}
865+
type record = {
866+
flags : flags;
867+
primitive_proj : bool;
868+
kind : Vernacexpr.inductive_kind;
869+
records : Record.Ast.t list;
870+
}
871+
type inductive = {
872+
flags : flags;
873+
typing_flags : Declarations.typing_flags option;
874+
private_ind : bool;
875+
uniform : ComInductive.uniform_inductive_flag;
876+
inductives : (Vernacexpr.one_inductive_expr * Vernacexpr.decl_notation list) list;
877+
}
878+
type t =
879+
| Record of record
880+
| Inductive of inductive
881+
end
882+
883+
let preprocess_inductive_decl ~atts kind indl =
873884
let udecl, indl = extract_inductive_udecl indl in
874885
let is_defclass = match kind, indl with
875886
| Class _, [ ( id , bl , c , Constructors [l]), [] ] -> Some (id, bl, c, l)
@@ -898,16 +909,6 @@ let vernac_inductive ~atts kind indl =
898909
++ private_ind ++ typing_flags ++ prim_proj_attr)
899910
atts)
900911
in
901-
if Dumpglob.dump () then
902-
List.iter (fun (((coe,lid), _, _, cstrs), _) ->
903-
match cstrs with
904-
| Constructors cstrs ->
905-
Dumpglob.dump_definition lid false "ind";
906-
List.iter (fun (_, (lid, _)) ->
907-
Dumpglob.dump_definition lid false "constr") cstrs
908-
| _ -> () (* dumping is done by vernac_record (called below) *) )
909-
indl;
910-
911912
if Option.has_some is_defclass then
912913
(* Definitional class case *)
913914
let (id, bl, c, l) = Option.get is_defclass in
@@ -921,8 +922,10 @@ let vernac_inductive ~atts kind indl =
921922
let coe' = if coe then BackInstance else NoInstance in
922923
let f = AssumExpr ((make ?loc:lid.loc @@ Name lid.v), [], ce),
923924
{ rf_subclass = coe' ; rf_priority = None ; rf_notation = [] ; rf_canonical = true } in
924-
vernac_record ~template udecl ~cumulative (Class true) ~poly ?typing_flags ~primitive_proj
925-
finite [id, bl, c, None, [f], None]
925+
let recordl = [id, bl, c, None, [f], None] in
926+
let kind = Class true in
927+
let records = vernac_record ~template udecl ~cumulative kind ~poly ?typing_flags ~primitive_proj finite recordl in
928+
indl, Preprocessed_Mind_decl.(Record { flags = { template; udecl; cumulative; poly; finite; }; primitive_proj; kind; records })
926929
else if List.for_all is_record indl then
927930
(* Mutual record case *)
928931
let () = match kind with
@@ -947,7 +950,8 @@ let vernac_inductive ~atts kind indl =
947950
in
948951
let kind = match kind with Class _ -> Class false | _ -> kind in
949952
let recordl = List.map unpack indl in
950-
vernac_record ~template udecl ~cumulative kind ~poly ?typing_flags ~primitive_proj finite recordl
953+
let records = vernac_record ~template udecl ~cumulative kind ~poly ?typing_flags ~primitive_proj finite recordl in
954+
indl, Preprocessed_Mind_decl.(Record { flags = { template; udecl; cumulative; poly; finite; }; primitive_proj; kind; records })
951955
else if List.for_all is_constructor indl then
952956
(* Mutual inductive case *)
953957
let () = match kind with
@@ -969,11 +973,46 @@ let vernac_inductive ~atts kind indl =
969973
| Constructors l -> (id, bl, c, l), ntn
970974
| RecordDecl _ -> assert false (* ruled out above *)
971975
in
972-
let indl = List.map unpack indl in
976+
let inductives = List.map unpack indl in
973977
let uniform = should_treat_as_uniform () in
974-
ComInductive.do_mutual_inductive ~template udecl indl ~cumulative ~poly ?typing_flags ~private_ind ~uniform finite
978+
indl, Preprocessed_Mind_decl.(Inductive { flags = { template; udecl; cumulative; poly; finite }; typing_flags; private_ind; uniform; inductives })
975979
else
976980
user_err (str "Mixed record-inductive definitions are not allowed.")
981+
;;
982+
983+
984+
let vernac_inductive ~atts kind indl =
985+
let open Preprocessed_Mind_decl in
986+
let indl_for_glob, decl = preprocess_inductive_decl ~atts kind indl in
987+
if Dumpglob.dump () then
988+
List.iter (fun (((coe,lid), _, _, cstrs), _) ->
989+
match cstrs with
990+
| Constructors cstrs ->
991+
Dumpglob.dump_definition lid false "ind";
992+
List.iter (fun (_, (lid, _)) ->
993+
Dumpglob.dump_definition lid false "constr") cstrs
994+
| _ -> ())
995+
indl_for_glob;
996+
match decl with
997+
| Record { flags = { template; udecl; cumulative; poly; finite; }; kind; primitive_proj; records } ->
998+
let () =
999+
if Dumpglob.dump () then
1000+
let dump_glob_proj (x, _) = match x with
1001+
| Vernacexpr.(AssumExpr ({loc;v=Name id}, _, _) | DefExpr ({loc;v=Name id}, _, _, _)) ->
1002+
Dumpglob.dump_definition (make ?loc id) false "proj"
1003+
| _ -> () in
1004+
records |> List.iter (fun { Record.Ast.cfs; name } ->
1005+
let () = Dumpglob.dump_definition name false "rec" in
1006+
List.iter dump_glob_proj cfs)
1007+
in
1008+
let _ : _ list =
1009+
Record.definition_structure ~template udecl kind ~cumulative ~poly ~primitive_proj finite records in
1010+
()
1011+
| Inductive { flags = { template; udecl; cumulative; poly; finite; }; typing_flags; private_ind; uniform; inductives } ->
1012+
ComInductive.do_mutual_inductive ~template udecl inductives ~cumulative ~poly ?typing_flags ~private_ind ~uniform finite
1013+
;;
1014+
let preprocess_inductive_decl ~atts kind indl =
1015+
snd @@ preprocess_inductive_decl ~atts kind indl
9771016

9781017
let vernac_fixpoint_common ~atts discharge l =
9791018
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)