Source file ccprojectability.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
open Names
open EConstr
open Inductiveops
type term_composition =
| FromEnv of EConstr.t
| FromParameter of EConstr.t * EConstr.t * int * term_extraction
| FromIndex of EConstr.t * int * term_extraction
| Composition of term_composition * term_composition array
type projection_type =
| Simple
| NotProjectable
let get_ith_arg sigma i term =
let (rels_to_arg, rest) = decompose_prod_n sigma (i-1) term in
let (arg_name, arg_type,rest) = destProd sigma rest in
(rels_to_arg, (arg_name, arg_type), rest)
let is_field_i_dependent env sigma cnstr i =
let constructor_type = e_type_of_constructor env sigma cnstr in
let ind_n_params = inductive_nparams env (fst (fst cnstr)) in
let (_, (_, field_type), _) = get_ith_arg sigma (i + ind_n_params) constructor_type in
not (Vars.noccur_between sigma 1 (i - 1) field_type)
let build_simple_projection env sigma intype cnstr special default =
let open Context in
let ci = (snd (fst cnstr)) in
let body = Combinators.make_selector env sigma ~pos:ci ~special ~default (mkRel 1) intype in
let id = Id.of_string "t" in
mkLambda (make_annot (Name id) ERelevance.relevant, intype, body)
let (let*) m f = match m with
| None -> None
| Some x -> f x
let find_term_composition env sigma cnstr argindex env_field_type ind env_ind_params env_ind_args =
let env_ind_n_params = Array.length env_ind_params in
let rel_type_of_constructor = type_of_constructor env cnstr in
let (_, (_, rel_field_type), rel_field_rest) = get_ith_arg sigma (argindex+env_ind_n_params) rel_type_of_constructor in
let (rel_target_context, rel_target_type) = decompose_prod sigma rel_field_rest in
let rel_field_type_lifted = Vars.lift (List.length rel_target_context + 1) rel_field_type in
let (_, rel_args) = decompose_app sigma rel_target_type in
let (rel_ind_params, rel_ind_args) = CArray.chop env_ind_n_params rel_args in
let rec find_term_composition_rec env sigma rel_term_to_compose env_term_to_compose =
if isRef sigma rel_term_to_compose then
Some (FromEnv rel_term_to_compose)
else match find_arg env sigma rel_term_to_compose rel_ind_params env_ind_params with
| Some (i, ) ->
Some (FromParameter (env_term_to_compose, env_ind_params.(i-1), i, extraction))
| None ->
begin match find_arg env sigma rel_term_to_compose rel_ind_args env_ind_args with
| Some (i, ) ->
Some (FromIndex (env_term_to_compose, i, extraction))
| None ->
begin match EConstr.kind sigma rel_term_to_compose with
| App (rel_f,rel_args) ->
let (env_f,env_args) = decompose_app sigma env_term_to_compose in
let* f_composition = find_term_composition_rec env sigma rel_f env_f in
if Array.length env_args != Array.length rel_args then
None
else
let* args_compositions =
let exception ArgNotComposable in
let map i rel_arg =
let arg_composition = find_term_composition_rec env sigma rel_arg env_args.(i) in
match arg_composition with
| Some arg_composition -> arg_composition
| None -> raise ArgNotComposable
in
try Some (CArray.mapi map rel_args) with ArgNotComposable -> None
in
Some (Composition (f_composition, args_compositions))
| _ -> None
end
end
and find_arg env sigma env_types_of_fields =
let find (i, ) =
let* r = find_term_extraction env sigma term_to_extract term_to_extract_from env_types_of_fields.(i) in
Some (i + 1, r)
in
let rec seq_find_map xs = match xs() with
| Seq.Nil -> None
| Seq.Cons(x,xs) ->
match find x with
| None -> seq_find_map xs
| Some _ as result -> result
in
seq_find_map (Array.to_seqi terms_to_extract_from)
and env sigma =
if eq_constr_nounivs sigma term_to_extract term_to_extract_from then
Some Id
else match EConstr.kind sigma term_to_extract_from with
| App (f, args) ->
begin match EConstr.kind sigma f with
| Construct c ->
let (_, env_args) = decompose_app sigma type_of_term_to_extract_from in
let* (i, ) = find_arg env sigma term_to_extract args env_args in
Some (Extraction (c, type_of_term_to_extract_from, i, extraction_result))
| _ -> None
end
| _ -> None
in
find_term_composition_rec env sigma rel_field_type_lifted env_field_type
let projectability_test env sigma cnstr argindex field_type ind ind_params ind_args =
let dependent = is_field_i_dependent env sigma cnstr argindex in
if dependent then
let composition = find_term_composition env sigma cnstr argindex field_type ind ind_params ind_args in
match composition with
| Some composition -> Dependent_Extractable composition
| None -> NotProjectable
else Simple
let rec env sigma default =
match extraction with
| Id -> rel_term_to_extract_from
| Extraction ((cnstr, _), , index, ) ->
let cnstr_n_args = constructor_nrealargs env cnstr in
let special = build_term_extraction env sigma default (mkRel (cnstr_n_args-(index-1))) env_next_term_to_extract_from next_extraction in
let pos = snd cnstr in
let (_, match_type) = Typing.type_of env sigma env_term_to_extract_from in
Combinators.make_selector env sigma ~pos ~special ~default rel_term_to_extract_from match_type
let rec build_term_composition env sigma term_composition ind_params n_ind_params ind_args n_ind_args =
match term_composition with
| FromEnv env_type_to_compose -> env_type_to_compose
| FromParameter (env_type_to_compose, , parameter_index, ) ->
let = ind_params.(parameter_index-1) in
build_term_extraction env sigma env_type_to_compose env_parameter_to_extract_from type_to_extract_from extraction
| FromIndex (env_type_to_compose, index_index, ) ->
let = ind_args.(index_index-1) in
build_term_extraction env sigma env_type_to_compose (mkRel (n_ind_args-(index_index-1))) type_to_extract_from extraction
| Composition (f_composition, arg_compositions) ->
let = build_term_composition env sigma f_composition ind_params n_ind_params ind_args n_ind_args in
let map arg_composition = build_term_composition env sigma arg_composition ind_params n_ind_params ind_args n_ind_args in
let = Array.map map arg_compositions in
mkApp (f_extraction_term, arg_extraction_terms)
let match_indices env sigma cnst_summary term_to_match n_ind_args max_free_rel =
let rec replace_rec n t = match EConstr.kind sigma t with
| Rel i ->
if i <= n_ind_args + n && i > n then
cnst_summary.cs_concl_realargs.(n_ind_args-i)
else t
| _ -> EConstr.map_with_binders sigma (fun n -> n+1) replace_rec n t
in
EConstr.map_with_binders sigma (fun n -> n+1) replace_rec 0 term_to_match
let make_annot_numbered s i r =
Context.make_annot (Name.mk_name (Nameops.make_ident s i)) r
let make_selector_match_indices env sigma ~pos ~special c (ind_fam, ind_args) return_type composition_type_template =
let n_ind_args = List.length ind_args in
let indt = IndType (ind_fam, ind_args) in
let (ind, _),_ = dest_ind_family ind_fam in
let () = Tacred.check_privacy env ind in
let (_, mip) = Inductive.lookup_mind_specif env ind in
let deparsign = make_arity_signature env sigma true ind_fam in
let p = it_mkLambda_or_LetIn return_type deparsign in
let cstrs = get_constructors env ind_fam in
let build_branch i =
let max_free_rel = Option.default 0 (Int.Set.max_elt_opt (Termops.free_rels sigma composition_type_template)) in
let matched_template = match_indices env sigma cstrs.(i-1) composition_type_template n_ind_args max_free_rel in
let endpt = if Int.equal i pos then
mkLambda (Context.make_annot Name.Anonymous ERelevance.relevant, matched_template, Vars.lift 1 special)
else
mkLambda (make_annot_numbered "t" None ERelevance.relevant, matched_template, mkRel 1)
in
let args = cstrs.(i-1).cs_args in
it_mkLambda_or_LetIn endpt args
in
let brl =
List.map build_branch(CList.interval 1 (Array.length mip.mind_consnames)) in
let rci = ERelevance.relevant in
let ci = make_case_info env ind RegularStyle in
make_case_or_project env sigma indt ci (p, rci) c (Array.of_list brl)
let build_dependent_projection_with_term_composition env sigma cnstr default special argty term_composition ((ind, ind_params) as ind_fam) ind_args =
let n_ind_params = List.length ind_params in
let n_ind_args = List.length ind_args in
let composition_type_template = build_term_composition env sigma term_composition (Array.of_list ind_params) n_ind_params (Array.of_list ind_args) n_ind_args in
let return_type = Vars.lift 1 (
mkProd (Context.make_annot Name.Anonymous ERelevance.relevant, composition_type_template, Vars.lift 1 composition_type_template)
) in
let e_match = make_selector_match_indices env sigma ~pos:(snd (fst cnstr)) ~special (mkRel 1) (make_ind_family ind_fam, ind_args) return_type composition_type_template in
let match_default = mkApp (e_match, [|default|]) in
let proj = mkLambda (make_annot_numbered "e" None ERelevance.relevant, argty, match_default) in
proj
let build_projection env sigma
cnstr
argindex
field_type
default
special
argty =
let IndType (ind_family,ind_args) =
try find_rectype env sigma argty
with Not_found ->
CErrors.user_err
Pp.(str "Cannot discriminate on inductive constructors with \
dependent types.") in
let (ind, ind_params) = dest_ind_family ind_family in
let cnstr = (fst cnstr, EInstance.make (snd cnstr)) in
let proj_result = projectability_test env sigma cnstr argindex field_type ind (Array.of_list ind_params) (Array.of_list ind_args) in
match proj_result with
| Simple | NotProjectable ->
let p = build_simple_projection env sigma argty cnstr special default in
sigma, p
| Dependent_Extractable type_composition ->
let p = build_dependent_projection_with_term_composition env sigma cnstr default special argty type_composition (ind, ind_params) ind_args in
sigma, p