@@ -1052,6 +1052,95 @@ open Declarations
1052
1052
1053
1053
(* Translation of inductives. *)
1054
1054
1055
+ let get_arity t =
1056
+ let decls, s = Term. decompose_prod_decls t in
1057
+ match Constr. kind s with
1058
+ | Sort (Type s ) ->
1059
+ begin match Univ.Universe. level s with
1060
+ | None -> None
1061
+ | Some l -> Some (decls, l)
1062
+ end
1063
+ | _ -> None
1064
+
1065
+ (* Workaround to ensure that template universe levels are linear *)
1066
+ let fix_template_params order evdr env temp b params =
1067
+ let templ = List. rev temp.template_param_levels in
1068
+ (* For all template levels generate fresh levels for all translated parameters *)
1069
+ let rec freshen umap templ params = match templ with
1070
+ | [] ->
1071
+ let () = assert (List. is_empty params) in
1072
+ umap, []
1073
+ | None :: templ ->
1074
+ let decls, params = List. chop (order + 1 ) params in
1075
+ let umap, params = freshen umap templ params in
1076
+ umap, decls @ params
1077
+ | Some _ :: templ ->
1078
+ let decls, params = List. chop (order + 1 ) params in
1079
+ let umap, params = freshen umap templ params in
1080
+ let rel, pdecls = match decls with
1081
+ | rel :: decls -> rel, decls
1082
+ | _ -> assert false
1083
+ in
1084
+ let u0 = match get_arity (Context.Rel.Declaration. get_type rel) with
1085
+ | None -> assert false
1086
+ | Some (_ , l ) -> l
1087
+ in
1088
+ let umap, (ur, repl) = match Univ.Level.Map. find_opt u0 umap with
1089
+ | None ->
1090
+ let ur = UnivGen. fresh_level () in
1091
+ let r = List. init order (fun _ -> UnivGen. fresh_level () ) in
1092
+ let r = (ur, r) in
1093
+ Univ.Level.Map. add u0 r umap, r
1094
+ | Some r -> umap, r
1095
+ in
1096
+ let map pdecl u = match pdecl with
1097
+ | Context.Rel.Declaration. LocalDef _ -> assert false
1098
+ | Context.Rel.Declaration. LocalAssum (na , pdecl ) ->
1099
+ match get_arity pdecl with
1100
+ | Some (ctx , _ ) ->
1101
+ let u = Univ.Universe. make u in
1102
+ let pdecl = Term. it_mkProd_or_LetIn (Constr. mkType u) ctx in
1103
+ Context.Rel.Declaration. LocalAssum (na, pdecl)
1104
+ | None -> assert false
1105
+ in
1106
+ let rel = map rel ur in
1107
+ let pdecls = List. map2 map pdecls repl in
1108
+ umap, rel :: pdecls @ params
1109
+ in
1110
+ let umap, decls = freshen Univ.Level.Map. empty templ params in
1111
+ (* Add corresponding declaration and constraints for each new level *)
1112
+ let fold_univs u0 accu = match Univ.Level.Map. find_opt u0 umap with
1113
+ | None -> assert false (* unbound template level *)
1114
+ | Some (ur , repl ) ->
1115
+ let accu = Univ.Level.Set. add ur accu in
1116
+ let fold accu u = Univ.Level.Set. add u accu in
1117
+ List. fold_left fold accu repl
1118
+ in
1119
+ let fold_cstrs (u0 , cst , v ) accu =
1120
+ (* We know that v cannot be template because of the unbounded-from-below property *)
1121
+ let () = assert (not (Univ.Level.Map. mem v umap)) in
1122
+ match Univ.Level.Map. find_opt u0 umap with
1123
+ | None ->
1124
+ (* not template, this is technically allowed but dubious *)
1125
+ Univ.Constraints. add (u0, cst, v) accu
1126
+ | Some (ur , repl ) ->
1127
+ let accu = Univ.Constraints. add (ur, cst, v) accu in
1128
+ let fold accu u = Univ.Constraints. add (u, cst, v) accu in
1129
+ List. fold_left fold accu repl
1130
+ in
1131
+ let fold_templ u0 (ur , repl ) accu =
1132
+ (* This is needed to typecheck inner template applications of the inductive.
1133
+ FIXME: when new-template-poly lands this can probably be removed. *)
1134
+ let accu = Univ.Constraints. add (ur, Le , u0) accu in
1135
+ let fold accu u = Univ.Constraints. add (u, Le , u0) accu in
1136
+ List. fold_left fold accu repl
1137
+ in
1138
+ let (univs, cstrs) = temp.template_context in
1139
+ let univs = Univ.Level.Set. fold fold_univs univs Univ.Level.Set. empty in
1140
+ let cstrs = Univ.Constraints. fold fold_cstrs cstrs Univ.Constraints. empty in
1141
+ let cstrs = Univ.Level.Map. fold fold_templ umap cstrs in
1142
+ umap, (univs, cstrs), decls
1143
+
1055
1144
let rec translate_mind_body name order evdr env kn b inst =
1056
1145
(* XXX: What is going on here? This doesn't make sense after cumulativity *)
1057
1146
(* let env = push_context b.mind_universes env in *)
@@ -1082,6 +1171,12 @@ let rec translate_mind_body name order evdr env kn b inst =
1082
1171
let mind_entry_params_R =
1083
1172
translate_mind_param order evdr env (CVars. subst_instance_context inst b.mind_params_ctxt)
1084
1173
in
1174
+ let template_univs, mind_entry_params_R = match b.mind_template with
1175
+ | None -> None , mind_entry_params_R
1176
+ | Some temp ->
1177
+ let umap, univs, params = fix_template_params order evdr env temp b mind_entry_params_R in
1178
+ Some (umap, univs), params
1179
+ in
1085
1180
debug_string [`Inductive ] " translatation of inductive ..." ;
1086
1181
let mind_entry_inds_R =
1087
1182
List. mapi
@@ -1091,14 +1186,36 @@ let rec translate_mind_body name order evdr env kn b inst =
1091
1186
debug_evar_map [`Inductive ] " translate_mind, evd = \n " env ! evdr;
1092
1187
let univs = match b.mind_universes with
1093
1188
| Monomorphic ->
1094
- begin match b.mind_template with
1189
+ begin match template_univs with
1095
1190
| None -> Monomorphic_ind_entry
1096
- | Some t -> Template_ind_entry t. Declarations. template_context
1191
+ | Some ( _ , ctx ) -> Template_ind_entry ctx
1097
1192
end
1098
1193
| Polymorphic _ ->
1099
1194
let uctx, _ = (Evd. univ_entry ~poly: true ! evdr) in
1100
1195
match uctx with Polymorphic_entry uctx -> Polymorphic_ind_entry uctx | _ -> assert false
1101
1196
in
1197
+ let mind_entry_inds_R = match template_univs with
1198
+ | None -> mind_entry_inds_R
1199
+ | Some (umap , _ ) ->
1200
+ let entry = match mind_entry_inds_R with
1201
+ | [entry] -> entry
1202
+ | _ -> assert false
1203
+ in
1204
+ let decls, sort = Term. decompose_prod_decls entry.mind_entry_arity in
1205
+ let sort = match Constr. kind sort with
1206
+ | Sort (Type u ) ->
1207
+ let u = Univ.Universe. repr u in
1208
+ let map (u0 , n ) = match Univ.Level.Map. find_opt u0 umap with
1209
+ | None -> [u0, n]
1210
+ | Some (ur , repl ) -> (ur, n) :: List. map (fun u -> u, n) repl
1211
+ in
1212
+ Constr. mkType (Univ.Universe. unrepr (List. map_append map u))
1213
+ | _ -> sort
1214
+ in
1215
+ let arity = Term. it_mkProd_or_LetIn sort decls in
1216
+ let entry = { entry with mind_entry_arity = arity } in
1217
+ [entry]
1218
+ in
1102
1219
let res = {
1103
1220
mind_entry_record = None ;
1104
1221
mind_entry_finite = b.mind_finite;
0 commit comments