aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMaxime Dénès2013-12-21 14:21:10 -0500
committerMaxime Dénès2014-07-22 16:52:26 -0400
commitccd7546cd32c8a7901a4234f86aa23b4a7e1a043 (patch)
tree7613b0a969850897c1061bcddb9c83d509e64ae7 /kernel
parent34b0bde46bd46ab4c467caccc7a6aebb5a999a74 (diff)
Tentative patch for incompatibility between subterm relation and dependent
pattern matching. This patch should be improved in two ways: (1) Implement the same checks for the commutative cut subterm rule. (2) When checking safe recursive subterms for each of the branches in a match, instanciated parameters in the return predicate should be taken into account. Step (1) should be enough to restore a correct guard condition, but (2) will be required if we don't want to rule out some legitimate and practical examples.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/inductive.ml22
1 files changed, 16 insertions, 6 deletions
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 64b2c76f90..7698eed0fa 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -498,7 +498,7 @@ let spec_of_tree t =
then Not_subterm
else Subterm (Strict, t)
-let subterm_spec_glb =
+let subterm_spec_glb init =
let glb2 s1 s2 =
match s1, s2 with
s1, Dead_code -> s1
@@ -509,7 +509,7 @@ let subterm_spec_glb =
if eq_wf_paths t1 t2 then Subterm (size_glb a1 a2, t1)
(* branches do not return objects with same spec *)
else Not_subterm in
- Array.fold_left glb2 Dead_code
+ Array.fold_left glb2 init
type guard_env =
{ env : env;
@@ -608,7 +608,18 @@ let check_inductive_codomain env p =
let absctx, ar = dest_lam_assum env p in
let arctx, s = dest_prod_assum env ar in
let i,l' = decompose_app (whd_betadeltaiota env s) in
- isInd i
+ isInd i
+
+let get_codomain_tree env p =
+ let absctx, ar = dest_lam_assum env p in
+ let arctx, s = dest_prod_assum env ar in
+ let i,l' = decompose_app (whd_betadeltaiota env s) in
+ match kind_of_term i with
+ | Ind i ->
+ let (_,mip) = lookup_mind_specif env i in Subterm(Strict,mip.mind_recargs)
+ | _ -> Not_subterm
+
+
(* [subterm_specif renv t] computes the recursive structure of [t] and
compare its size with the size of the initial recursive argument of
@@ -623,8 +634,7 @@ let rec subterm_specif renv stack t =
| Rel k -> subterm_var k renv
| Case (ci,p,c,lbr) ->
let stack' = push_stack_closures renv l stack in
- if not (check_inductive_codomain renv.env p) then Not_subterm
- else
+ let pred_spec = get_codomain_tree renv.env p in
let cases_spec = branches_specif renv
(lazy_subterm_specif renv [] c) ci in
let stl =
@@ -632,7 +642,7 @@ let rec subterm_specif renv stack t =
let stack_br = push_stack_args (cases_spec.(i)) stack' in
subterm_specif renv stack_br br')
lbr in
- subterm_spec_glb stl
+ subterm_spec_glb pred_spec stl
| Fix ((recindxs,i),(_,typarray,bodies as recdef)) ->
(* when proving that the fixpoint f(x)=e is less than n, it is enough