@@ -215,18 +215,17 @@ and betared st s bd f args =
215
215
betared st s bd f args
216
216
217
217
(* -------------------------------------------------------------------- *)
218
- and app_red st f1 args =
219
- match f1.f_node with
220
- (* β-reduction *)
221
- | Fquant (Llambda, bd , f2 ) when not (Args. isempty args) && st.st_ri.beta ->
222
- betared st Subst. subst_id bd f2 args
223
-
224
- (* ι-reduction (records projection) *)
225
- | Fop (p, _) when
226
- st.st_ri.iota
218
+ and try_reduce_record_projection
219
+ (st : state ) ((p , _tys ) : EcPath. path * ty list ) (args : args )
220
+ =
221
+ let exception Bailout in
222
+
223
+ try
224
+ if not (
225
+ st .st_ri .iota
227
226
&& EcEnv.Op. is_projection st .st_env p
228
227
&& not (Args. isempty args )
229
- -> begin
228
+ ) then raise Bailout;
230
229
231
230
let mk , args1 = oget (Args. pop args) in
232
231
@@ -235,75 +234,92 @@ and app_red st f1 args =
235
234
when (EcEnv.Op. is_record_ctor st.st_env mkp) ->
236
235
let v = oget (EcEnv.Op. by_path_opt p st.st_env) in
237
236
let v = proj3_2 (EcDecl. operator_as_proj v) in
238
- app_red st (List. nth mkargs v) args1
237
+ Some ( app_red st (List. nth mkargs v) args1)
239
238
240
239
| _ ->
241
- f_app f1 args.stack args.resty
242
- end
240
+ None
243
241
244
- (* ι-reduction (fix-def reduction) *)
245
- | Fop (p, tys)
246
- when st.st_ri.iota && EcEnv.Op. is_fix_def st.st_env p
247
- -> begin
248
- let module E = struct exception NoCtor end in
249
-
250
- try
251
- let Args. { resty = ty; stack = args; } = args in
252
- let op = oget (EcEnv.Op. by_path_opt p st.st_env) in
253
- let fix = EcDecl. operator_as_fix op in
254
-
255
- if List. length args < snd (fix.EcDecl. opf_struct) then
256
- raise E. NoCtor ;
257
-
258
- let args, eargs = List. split_at (snd (fix.EcDecl. opf_struct)) args in
259
-
260
- let vargs = Array. of_list args in
261
- let pargs = List. fold_left (fun (opb , acc ) v ->
262
- let v = vargs.(v) in
263
-
264
- match fst_map (fun x -> x.f_node) (EcFol. destr_app v) with
265
- | (Fop (p , _ ), cargs ) when EcEnv.Op. is_dtype_ctor st.st_env p -> begin
266
- let idx = EcEnv.Op. by_path p st.st_env in
267
- let idx = snd (EcDecl. operator_as_ctor idx) in
268
- match opb with
269
- | EcDecl. OPB_Leaf _ -> assert false
270
- | EcDecl. OPB_Branch bs ->
271
- ((Parray. get bs idx).EcDecl. opb_sub, cargs :: acc)
272
- end
273
- | _ -> raise E. NoCtor )
274
- (fix.EcDecl. opf_branches, [] ) (fst fix.EcDecl. opf_struct)
275
- in
276
-
277
- let pargs, (bds, body) =
278
- match pargs with
279
- | EcDecl. OPB_Leaf (bds , body ), cargs -> (List. rev cargs, (bds, body))
280
- | _ -> assert false
281
- in
282
-
283
- let subst =
284
- List. fold_left2
285
- (fun subst (x , _ ) fa -> Subst. bind_local subst x fa)
286
- Subst. subst_id fix.EcDecl. opf_args args in
287
-
288
- let subst =
289
- List. fold_left2
290
- (fun subst bds cargs ->
291
- List. fold_left2
292
- (fun subst (x , _ ) fa -> Subst. bind_local subst x fa)
293
- subst bds cargs)
294
- subst bds pargs in
295
-
296
- let body = EcFol. form_of_expr EcFol. mhr body in
297
- let body =
298
- Tvar. f_subst ~freshen: true (List. map fst op.EcDecl. op_tparams) tys body in
299
-
300
- cbv st subst body (Args. create ty eargs)
301
- with E. NoCtor ->
302
- reduce_user_delta st f1 p tys args
303
- end
242
+ with Bailout ->
243
+ None
244
+
245
+ (* -------------------------------------------------------------------- *)
246
+ and try_reduce_fixdef
247
+ (st : state ) ((p , tys ) : EcPath. path * ty list ) (args : args )
248
+ =
249
+ let exception Bailout in
250
+
251
+ try
252
+ if not (st .st_ri .iota && EcEnv.Op. is_fix_def st .st_env p ) then
253
+ raise Bailout;
254
+
255
+ let Args. { resty = ty ; stack = args ; } = args in
256
+ let op = oget (EcEnv.Op. by_path_opt p st.st_env) in
257
+ let fix = EcDecl. operator_as_fix op in
258
+
259
+ if List. length args < snd (fix.EcDecl. opf_struct) then
260
+ raise Bailout ;
261
+
262
+ let args, eargs = List. split_at (snd (fix.EcDecl. opf_struct)) args in
263
+
264
+ let vargs = Array. of_list args in
265
+ let pargs = List. fold_left (fun (opb , acc ) v ->
266
+ let v = vargs.(v) in
267
+
268
+ match fst_map (fun x -> x.f_node) (EcFol. destr_app v) with
269
+ | (Fop (p , _ ), cargs ) when EcEnv.Op. is_dtype_ctor st.st_env p -> begin
270
+ let idx = EcEnv.Op. by_path p st.st_env in
271
+ let idx = snd (EcDecl. operator_as_ctor idx) in
272
+ match opb with
273
+ | EcDecl. OPB_Leaf _ -> assert false
274
+ | EcDecl. OPB_Branch bs ->
275
+ ((Parray. get bs idx).EcDecl. opb_sub, cargs :: acc)
276
+ end
277
+ | _ -> raise Bailout )
278
+ (fix.EcDecl. opf_branches, [] ) (fst fix.EcDecl. opf_struct)
279
+ in
280
+
281
+ let pargs, (bds, body) =
282
+ match pargs with
283
+ | EcDecl. OPB_Leaf (bds , body ), cargs -> (List. rev cargs, (bds, body))
284
+ | _ -> assert false
285
+ in
286
+
287
+ let subst =
288
+ List. fold_left2
289
+ (fun subst (x , _ ) fa -> Subst. bind_local subst x fa)
290
+ Subst. subst_id fix.EcDecl. opf_args args in
291
+
292
+ let subst =
293
+ List. fold_left2
294
+ (fun subst bds cargs ->
295
+ List. fold_left2
296
+ (fun subst (x , _ ) fa -> Subst. bind_local subst x fa)
297
+ subst bds cargs)
298
+ subst bds pargs in
299
+
300
+ let body = EcFol. form_of_expr EcFol. mhr body in
301
+ let body =
302
+ Tvar. f_subst ~freshen: true (List. map fst op.EcDecl. op_tparams) tys body in
303
+
304
+ Some (cbv st subst body (Args. create ty eargs))
305
+
306
+ with Bailout ->
307
+ None
308
+
309
+ (* -------------------------------------------------------------------- *)
310
+ and app_red st f1 args =
311
+ match f1.f_node with
312
+ (* β-reduction *)
313
+ | Fquant (Llambda, bd , f2 ) when not (Args. isempty args) && st.st_ri.beta ->
314
+ betared st Subst. subst_id bd f2 args
304
315
305
- | Fop (p , tys ) ->
306
- reduce_user_delta st f1 p tys args
316
+ (* op reduction (ι-reduction / delta / user-defined rules) *)
317
+ | Fop (p , tys ) ->
318
+ List. find_map_opt
319
+ (fun f -> f st (p, tys) args)
320
+ [ try_reduce_record_projection
321
+ ; try_reduce_fixdef]
322
+ |> ofdfl (fun () -> reduce_user_delta st f1 p tys args)
307
323
308
324
| _ ->
309
325
f_app f1 args.stack args.resty
0 commit comments