@@ -611,16 +611,14 @@ let check_inductive_codomain env p =
611611 isInd i
612612
613613let get_codomain_tree env p =
614- let absctx, ar = dest_lam_assum env p in
615- let arctx, s = dest_prod_assum env ar in
614+ let absctx, ar = dest_lam_assum env p in (* TODO: reduce or preserve lets? *)
615+ let arctx, s = dest_prod_assum env ar in (* TODO: check number of prods *)
616616 let i,l' = decompose_app (whd_betadeltaiota env s) in
617617 match kind_of_term i with
618618 | Ind i ->
619619 let (_,mip) = lookup_mind_specif env i in Subterm (Strict ,mip.mind_recargs)
620620 | _ -> Not_subterm
621621
622-
623-
624622(* [subterm_specif renv t] computes the recursive structure of [t] and
625623 compare its size with the size of the initial recursive argument of
626624 the fixpoint we are checking. [renv] collects such information
@@ -650,6 +648,7 @@ let rec subterm_specif renv stack t =
650648 furthermore when f is applied to a term which is strictly less than
651649 n, one may assume that x itself is strictly less than n
652650 *)
651+ (* TODO: is this necessary? *)
653652 if not (check_inductive_codomain renv.env typarray.(i)) then Not_subterm
654653 else
655654 let (ctxt,clfix) = dest_prod renv.env typarray.(i) in
@@ -686,7 +685,7 @@ let rec subterm_specif renv stack t =
686685
687686 | Lambda (x ,a ,b ) ->
688687 let () = assert (List. is_empty l) in
689- let spec,stack' = extract_stack renv a stack in
688+ let spec,stack' = extract_stack stack in
690689 subterm_specif (push_var renv (x,a,spec)) stack' b
691690
692691 (* Metas and evars are considered OK *)
@@ -702,7 +701,7 @@ and stack_element_specif = function
702701 | SClosure (h_renv ,h ) -> lazy_subterm_specif h_renv [] h
703702 | SArg x -> x
704703
705- and extract_stack renv a = function
704+ and extract_stack = function
706705 | [] -> Lazy. lazy_from_val Not_subterm , []
707706 | h ::t -> stack_element_specif h, t
708707
@@ -732,6 +731,34 @@ let error_illegal_rec_call renv fx (arg_renv,arg) =
732731let error_partial_apply renv fx =
733732 raise (FixGuardError (renv.env,NotEnoughArgumentsForFixCall fx))
734733
734+ let filter_stack_domain env ci p stack =
735+ let absctx, ar = dest_lam_assum env p in
736+ let env = push_rel_context absctx env in
737+ let rec filter_stack env ar stack =
738+ let t = whd_betadeltaiota env ar in
739+ match stack, kind_of_term t with
740+ | elt :: stack' , Prod (n ,a ,c0 ) ->
741+ let d = (n,None ,a) in
742+ let ty, _ = decompose_app a in (* TODO: reduce a? *)
743+ let elt = match kind_of_term ty with
744+ | Ind i ->
745+ let (_,mip) = lookup_mind_specif env i in
746+ let spec' = stack_element_specif elt in (* TODO: this is recomputed
747+ each time*)
748+ (match (Lazy. force spec') with (* TODO: are we forcing too much? *)
749+ | Not_subterm -> elt
750+ | Subterm (_ ,path ) ->
751+ if eq_wf_paths path mip.mind_recargs then elt
752+ else (SArg (lazy Not_subterm ))) (* TODO: intersection *)
753+ (* TODO: not really an SArg *)
754+ | _ -> (SArg (lazy Not_subterm ))
755+ in
756+ elt :: filter_stack (push_rel d env) c0 stack'
757+ | _ ,_ -> List. fold_right (fun _ l -> SArg (lazy Not_subterm ) :: l) stack []
758+ (* TODO: is it correct to empty the stack instead? *)
759+ in
760+ filter_stack env ar stack
761+
735762(* Check if [def] is a guarded fixpoint body with decreasing arg.
736763 given [recpos], the decreasing arguments of each mutually defined
737764 fixpoint. *)
@@ -786,6 +813,7 @@ let check_one_fix renv recpos def =
786813 let case_spec = branches_specif renv
787814 (lazy_subterm_specif renv [] c_0) ci in
788815 let stack' = push_stack_closures renv l stack in
816+ let stack' = filter_stack_domain renv.env ci p stack' in
789817 Array. iteri (fun k br' ->
790818 let stack_br = push_stack_args case_spec.(k) stack' in
791819 check_rec_call renv stack_br br') lrest
@@ -828,7 +856,7 @@ let check_one_fix renv recpos def =
828856 | Lambda (x ,a ,b ) ->
829857 let () = assert (List. is_empty l) in
830858 check_rec_call renv [] a ;
831- let spec, stack' = extract_stack renv a stack in
859+ let spec, stack' = extract_stack stack in
832860 check_rec_call (push_var renv (x,a,spec)) stack' b
833861
834862 | Prod (x ,a ,b ) ->
0 commit comments