@@ -346,7 +346,8 @@ and fterm =
346
346
| FProj of projection * fconstr
347
347
| FFix of fixpoint * fconstr subs
348
348
| FCoFix of cofixpoint * fconstr subs
349
- | FCases of case_info * fconstr * fconstr * fconstr array
349
+ | FCase of case_info * fconstr * fconstr * fconstr array
350
+ | FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
350
351
| FLambda of int * (Name. t * constr) list * constr * fconstr subs
351
352
| FProd of Name. t * fconstr * fconstr
352
353
| FLetIn of Name. t * fconstr * fconstr * constr * fconstr subs
@@ -376,6 +377,7 @@ let update v1 no t =
376
377
type stack_member =
377
378
| Zapp of fconstr array
378
379
| Zcase of case_info * fconstr * fconstr array
380
+ | ZcaseT of case_info * constr * constr array * fconstr subs
379
381
| Zproj of int * int * constant
380
382
| Zfix of fconstr * stack
381
383
| Zshift of int
@@ -490,72 +492,7 @@ let zupdate m s =
490
492
Zupdate (m)::s'
491
493
else s
492
494
493
- (* Closure optimization: *)
494
- let rec compact_constr (lg , subs as s ) c k =
495
- match kind_of_term c with
496
- Rel i ->
497
- if i < k then s, c else
498
- (try (lg,subs), mkRel (k + lg - List. index Int. equal (i- k+ 1 ) subs)
499
- with Not_found -> (lg+ 1 , (i- k+ 1 )::subs), mkRel (k+ lg))
500
- | (Sort _ |Var _ |Meta _ |Ind _ |Const _ |Construct _ ) -> s, c
501
- | Evar (ev ,v ) ->
502
- let (s, v') = compact_vect s v k in
503
- if v== v' then s, c else s, mkEvar(ev, v')
504
- | Cast (a ,ck ,b ) ->
505
- let (s, a') = compact_constr s a k in
506
- let (s, b') = compact_constr s b k in
507
- if a== a' && b== b' then s, c else s, mkCast(a', ck, b')
508
- | App (f ,v ) ->
509
- let (s, f') = compact_constr s f k in
510
- let (s, v') = compact_vect s v k in
511
- if f== f' && v== v' then s, c else s, mkApp(f',v')
512
- | Proj (p ,t ) ->
513
- let (s, t') = compact_constr s t k in
514
- if t'== t then s, c else s, mkProj (p,t')
515
- | Lambda (n ,a ,b ) ->
516
- let (s, a') = compact_constr s a k in
517
- let (s, b') = compact_constr s b (k+ 1 ) in
518
- if a== a' && b== b' then s, c else s, mkLambda(n,a',b')
519
- | Prod (n ,a ,b ) ->
520
- let (s, a') = compact_constr s a k in
521
- let (s, b') = compact_constr s b (k+ 1 ) in
522
- if a== a' && b== b' then s, c else s, mkProd(n,a',b')
523
- | LetIn (n ,a ,ty ,b ) ->
524
- let (s, a') = compact_constr s a k in
525
- let (s, ty') = compact_constr s ty k in
526
- let (s, b') = compact_constr s b (k+ 1 ) in
527
- if a== a' && ty== ty' && b== b' then s, c else s, mkLetIn(n,a',ty',b')
528
- | Fix (fi ,(na ,ty ,bd )) ->
529
- let (s, ty') = compact_vect s ty k in
530
- let (s, bd') = compact_vect s bd (k+ Array. length ty) in
531
- if ty== ty' && bd== bd' then s, c else s, mkFix(fi,(na,ty',bd'))
532
- | CoFix (i ,(na ,ty ,bd )) ->
533
- let (s, ty') = compact_vect s ty k in
534
- let (s, bd') = compact_vect s bd (k+ Array. length ty) in
535
- if ty== ty' && bd== bd' then s, c else s, mkCoFix(i,(na,ty',bd'))
536
- | Case (ci ,p ,a ,br ) ->
537
- let (s, p') = compact_constr s p k in
538
- let (s, a') = compact_constr s a k in
539
- let (s, br') = compact_vect s br k in
540
- if p== p' && a== a' && br== br' then s, c else s, mkCase(ci,p',a',br')
541
-
542
- and compact_vect s v k =
543
- let fold s c = compact_constr s c k in
544
- Array. smartfoldmap fold s v
545
-
546
- (* Computes the minimal environment of a closure.
547
- Idea: if the subs is not identity, the term will have to be
548
- reallocated entirely (to propagate the substitution). So,
549
- computing the set of free variables does not change the
550
- complexity. *)
551
- let optimise_closure env c =
552
- if is_subs_id env then (env,c) else
553
- let ((_,s), c') = compact_constr (0 ,[] ) c 1 in
554
- let env' = Array. map_of_list (fun i -> clos_rel env i) s in
555
- (subs_cons (env', subs_id 0 ),c')
556
-
557
495
let mk_lambda env t =
558
- let (env,t) = optimise_closure env t in
559
496
let (rvars,t') = decompose_lam t in
560
497
FLambda (List. length rvars, List. rev rvars, t', env)
561
498
@@ -601,8 +538,7 @@ let mk_clos_deep clos_fun env t =
601
538
term = FProj (p, clos_fun env c) }
602
539
| Case (ci ,p ,c ,v ) ->
603
540
{ norm = Red ;
604
- term = FCases (ci, clos_fun env p, clos_fun env c,
605
- CArray.Fun1. map clos_fun env v) }
541
+ term = FCaseT (ci, p, clos_fun env c, v, env) }
606
542
| Fix fx ->
607
543
{ norm = Cstr ; term = FFix (fx, env) }
608
544
| CoFix cfx ->
@@ -633,10 +569,14 @@ let rec to_constr constr_fun lfts v =
633
569
| FFlex (ConstKey op ) -> mkConstU op
634
570
| FInd op -> mkIndU op
635
571
| FConstruct op -> mkConstructU op
636
- | FCases (ci ,p ,c ,ve ) ->
572
+ | FCase (ci ,p ,c ,ve ) ->
637
573
mkCase (ci, constr_fun lfts p,
638
574
constr_fun lfts c,
639
575
CArray.Fun1. map constr_fun lfts ve)
576
+ | FCaseT (ci ,p ,c ,ve ,env ) ->
577
+ mkCase (ci, constr_fun lfts (mk_clos env p),
578
+ constr_fun lfts c,
579
+ Array. map (fun b -> constr_fun lfts (mk_clos env b)) ve)
640
580
| FFix ((op ,(lna ,tys ,bds )),e ) ->
641
581
let n = Array. length bds in
642
582
let ftys = CArray.Fun1. map mk_clos e tys in
@@ -702,35 +642,24 @@ let rec fstrong unfreeze_fun lfts v =
702
642
to_constr (fstrong unfreeze_fun) lfts (unfreeze_fun v)
703
643
*)
704
644
705
- let rec zip m stk rem = match stk with
706
- | [] ->
707
- begin match rem with
708
- | [] -> m
709
- | stk :: rem -> zip m stk rem
710
- end
711
- | Zapp args :: s -> zip {norm= neutr m.norm; term= FApp (m, args)} s rem
712
- | Zcase (ci ,p ,br )::s ->
713
- let t = FCases (ci, p, m, br) in
714
- zip {norm= neutr m.norm; term= t} s rem
715
- | Zproj (i ,j ,cst ) :: s ->
716
- zip {norm= neutr m.norm; term= FProj (Projection. make cst true ,m)} s rem
717
- | Zfix (fx ,par )::s ->
718
- zip fx par ((Zapp [|m|] :: s) :: rem)
719
- | Zshift (n )::s ->
720
- zip (lift_fconstr n m) s rem
721
- | Zupdate (rf )::s ->
722
- zip_update m s rem rf
723
-
724
- and zip_update m stk rem rf = match stk with
725
- | [] ->
726
- begin match rem with
727
- | [] -> update rf m.norm m.term
728
- | stk :: rem -> zip_update m stk rem rf
729
- end
730
- | Zupdate rf :: s -> zip_update m s rem rf
731
- | s -> zip (update rf m.norm m.term) s rem
732
-
733
- let zip m stk = zip m stk []
645
+ let rec zip m stk =
646
+ match stk with
647
+ | [] -> m
648
+ | Zapp args :: s -> zip {norm= neutr m.norm; term= FApp (m, args)} s
649
+ | Zcase (ci ,p ,br )::s ->
650
+ let t = FCase (ci, p, m, br) in
651
+ zip {norm= neutr m.norm; term= t} s
652
+ | ZcaseT (ci ,p ,br ,e )::s ->
653
+ let t = FCaseT (ci, p, m, br, e) in
654
+ zip {norm= neutr m.norm; term= t} s
655
+ | Zproj (i ,j ,cst ) :: s ->
656
+ zip {norm= neutr m.norm; term= FProj (Projection. make cst true ,m)} s
657
+ | Zfix (fx ,par )::s ->
658
+ zip fx (par @ append_stack [|m|] s)
659
+ | Zshift (n )::s ->
660
+ zip (lift_fconstr n m) s
661
+ | Zupdate (rf )::s ->
662
+ zip (update rf m.norm m.term) s
734
663
735
664
let fapp_stack (m ,stk ) = zip m stk
736
665
@@ -802,7 +731,8 @@ let rec get_args n tys f e stk =
802
731
803
732
(* Eta expansion: add a reference to implicit surrounding lambda at end of stack *)
804
733
let rec eta_expand_stack = function
805
- | (Zapp _ | Zfix _ | Zcase _ | Zshift _ | Zupdate _ | Zproj _ as e ) :: s ->
734
+ | (Zapp _ | Zfix _ | Zcase _ | ZcaseT _ | Zproj _
735
+ | Zshift _ | Zupdate _ as e ) :: s ->
806
736
e :: eta_expand_stack s
807
737
| [] ->
808
738
[Zshift 1 ; Zapp [|{norm= Norm ; term= FRel 1 }|]]
@@ -930,7 +860,8 @@ let rec knh info m stk =
930
860
| FCLOS (t ,e ) -> knht info e t (zupdate m stk)
931
861
| FLOCKED -> assert false
932
862
| FApp (a ,b ) -> knh info a (append_stack b (zupdate m stk))
933
- | FCases (ci ,p ,t ,br ) -> knh info t (Zcase (ci,p,br)::zupdate m stk)
863
+ | FCase (ci ,p ,t ,br ) -> knh info t (Zcase (ci,p,br)::zupdate m stk)
864
+ | FCaseT (ci ,p ,t ,br ,e ) -> knh info t (ZcaseT (ci,p,br,e)::zupdate m stk)
934
865
| FFix (((ri ,n ),(_ ,_ ,_ )),_ ) ->
935
866
(match get_nth_arg m ri.(n) stk with
936
867
(Some(pars ,arg ),stk' ) -> knh info arg (Zfix (m,pars)::stk')
@@ -958,7 +889,7 @@ and knht info e t stk =
958
889
| App (a ,b ) ->
959
890
knht info e a (append_stack (mk_clos_vect e b) stk)
960
891
| Case (ci ,p ,t ,br ) ->
961
- knht info e t (Zcase (ci, mk_clos e p, mk_clos_vect e br )::stk)
892
+ knht info e t (ZcaseT (ci, p, br, e )::stk)
962
893
| Fix _ -> knh info (mk_clos2 e t) stk
963
894
| Cast (a ,_ ,_ ) -> knht info e a stk
964
895
| Rel n -> knh info (clos_rel e n) stk
@@ -995,6 +926,10 @@ let rec knr info m stk =
995
926
assert (ci.ci_npar> = 0 );
996
927
let rargs = drop_parameters depth ci.ci_npar args in
997
928
kni info br.(c-1 ) (rargs@ s)
929
+ | (depth , args , ZcaseT(ci ,_ ,br ,e )::s ) ->
930
+ assert (ci.ci_npar> = 0 );
931
+ let rargs = drop_parameters depth ci.ci_npar args in
932
+ knit info e br.(c-1 ) (rargs@ s)
998
933
| (_ , cargs , Zfix(fx ,par )::s ) ->
999
934
let rarg = fapp_stack(m,cargs) in
1000
935
let stk' = par @ append_stack [|rarg|] s in
@@ -1007,7 +942,7 @@ let rec knr info m stk =
1007
942
| (_ ,args ,s ) -> (m,args@ s))
1008
943
| FCoFix _ when red_set info.i_flags fIOTA ->
1009
944
(match strip_update_shift_app m stk with
1010
- (_ , args , ((Zcase _ ::_ ) as stk' )) ->
945
+ (_ , args , ((( Zcase _ | ZcaseT _ ) ::_ ) as stk' )) ->
1011
946
let (fxe,fxbd) = contract_fix_vect m.term in
1012
947
knit info fxe fxbd (args@ stk')
1013
948
| (_ ,args ,s ) -> (m,args@ s))
@@ -1039,6 +974,10 @@ let rec zip_term zfun m stk =
1039
974
| Zcase (ci ,p ,br )::s ->
1040
975
let t = mkCase(ci, zfun p, m, Array. map zfun br) in
1041
976
zip_term zfun t s
977
+ | ZcaseT (ci ,p ,br ,e )::s ->
978
+ let t = mkCase(ci, zfun (mk_clos e p), m,
979
+ Array. map (fun b -> zfun (mk_clos e b)) br) in
980
+ zip_term zfun t s
1042
981
| Zproj (_ ,_ ,p )::s ->
1043
982
let t = mkProj (Projection. make p true , m) in
1044
983
zip_term zfun t s
0 commit comments