aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar jforest <jforest@85f007b7-540e-0410-9357-904b9bb8a0f7>2010-05-04 13:24:59 +0000
committerGravatar jforest <jforest@85f007b7-540e-0410-9357-904b9bb8a0f7>2010-05-04 13:24:59 +0000
commit090403f8cc2f1fa0e8c98c86fd6559182258b009 (patch)
tree0339e27ede58534946fc1c3ed56329be4e6f3a15
parent5a5f774de94a1e822d5f8b079178dcef7ffdd0b0 (diff)
Correction of bug 2290
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12989 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--plugins/funind/recdef.ml98
1 files changed, 48 insertions, 50 deletions
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 1780ff827..3cbe0a03c 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -67,45 +67,39 @@ let pf_get_new_id id g =
let h_intros l =
tclMAP h_intro l
-let debug_queue = Queue.create ()
+let debug_queue = Stack.create ()
-let rec print_debug_queue e =
- let lmsg,goal = Queue.pop debug_queue in
- if Queue.is_empty debug_queue
- then
- msgnl (lmsg ++ (str " raised exception " ++ Cerrors.explain_exn e) ++ str " on goal " ++ goal)
- else
+let rec print_debug_queue b e =
+ if not (Stack.is_empty debug_queue)
+ then
begin
- print_debug_queue e;
- msgnl (str " from " ++ lmsg ++ str " on goal " ++ goal);
+ let lmsg,goal = Stack.pop debug_queue in
+ if b then
+ msgnl (lmsg ++ (str " raised exception " ++ Cerrors.explain_exn e) ++ str " on goal " ++ goal)
+ else
+ begin
+ msgnl (str " from " ++ lmsg ++ str " on goal " ++ goal);
+ end;
+ print_debug_queue false e;
end
+
let do_observe_tac s tac g =
let goal = Printer.pr_goal g in
- let lmsg = (str "recdef ") ++ (str s) in
- Queue.add (lmsg,goal) debug_queue;
+ let lmsg = (str "recdef : ") ++ (str s) in
+ Stack.push (lmsg,goal) debug_queue;
try
let v = tac g in
- ignore(Queue.pop debug_queue);
+ ignore(Stack.pop debug_queue);
v
with e ->
- if not (Queue.is_empty debug_queue)
+ if not (Stack.is_empty debug_queue)
then
- print_debug_queue e;
+ print_debug_queue true e;
raise e
-(*let do_observe_tac s tac g =
- let goal = begin (Printer.pr_goal (sig_it g)) end in
- try let v = tac g in msgnl (goal ++ fnl () ++ (str "recdef ") ++
- (str s)++(str " ")++(str "finished")); v
- with e ->
- msgnl (str "observation "++str s++str " raised exception " ++
- Cerrors.explain_exn e ++ str " on goal " ++ goal );
- raise e;;
-*)
-
let observe_tac s tac g =
if Tacinterp.get_debug () <> Tactic_debug.DebugOff
then do_observe_tac s tac g
@@ -178,20 +172,22 @@ let rank_for_arg_list h =
| x::tl -> if predicate h x then Some i else rank_aux (i+1) tl in
rank_aux 0;;
-let rec (find_call_occs : int -> constr -> constr ->
+let rec (find_call_occs : int -> int -> constr -> constr ->
(constr list -> constr) * constr list list) =
- fun nb_lam f expr ->
+ fun nb_arg nb_lam f expr ->
match (kind_of_term expr) with
App (g, args) when g = f ->
+ if Array.length args <> nb_arg then errorlabstrm "recdef" (str "Partial application of function " ++ Printer.pr_lconstr expr ++ str " in its body is not allowed while using Function");
(fun l -> List.hd l), [Array.to_list args]
| App (g, args) ->
+ msgnl (str "NB_ARGS " ++ int nb_arg ++ str " " ++ Printer.pr_lconstr g);
let (largs: constr list) = Array.to_list args in
let rec find_aux = function
[] -> (fun x -> []), []
| a::upper_tl ->
(match find_aux upper_tl with
(cf, ((arg1::args) as args_for_upper_tl)) ->
- (match find_call_occs nb_lam f a with
+ (match find_call_occs nb_arg nb_lam f a with
cf2, (_ :: _ as other_args) ->
let rec avoid_duplicates args =
match args with
@@ -215,7 +211,7 @@ let rec (find_call_occs : int -> constr -> constr ->
other_args'@args_for_upper_tl
| _, [] -> (fun x -> a::cf x), args_for_upper_tl)
| _, [] ->
- (match find_call_occs nb_lam f a with
+ (match find_call_occs nb_arg nb_lam f a with
cf, (arg1::args) -> (fun l -> cf l::upper_tl), (arg1::args)
| _, [] -> (fun x -> a::upper_tl), [])) in
begin
@@ -225,15 +221,16 @@ let rec (find_call_occs : int -> constr -> constr ->
(fun l -> mkApp (g, Array.of_list (cf l))), args
end
| Rel(v) -> if v > nb_lam then error "find_call_occs : Rel" else ((fun l -> expr),[])
+ | Var(_) when expr = f -> errorlabstrm "recdef" (str "Partial application of function " ++ Printer.pr_lconstr expr ++ str " in its body is not allowed while using Function")
| Var(id) -> (fun l -> expr), []
| Meta(_) -> error "find_call_occs : Meta"
| Evar(_) -> error "find_call_occs : Evar"
| Sort(_) -> (fun l -> expr), []
- | Cast(b,_,_) -> find_call_occs nb_lam f b
+ | Cast(b,_,_) -> find_call_occs nb_arg nb_lam f b
| Prod(_,_,_) -> error "find_call_occs : Prod"
| Lambda(na,t,b) ->
begin
- match find_call_occs (succ nb_lam) f b with
+ match find_call_occs nb_arg (succ nb_lam) f b with
| _, [] -> (* Lambda are authorized as long as they do not contain
recursives calls *)
(fun l -> expr),[]
@@ -241,7 +238,7 @@ let rec (find_call_occs : int -> constr -> constr ->
end
| LetIn(na,v,t,b) ->
begin
- match find_call_occs nb_lam f v, find_call_occs (succ nb_lam) f b with
+ match find_call_occs nb_arg nb_lam f v, find_call_occs nb_arg (succ nb_lam) f b with
| (_,[]),(_,[]) ->
((fun l -> expr), [])
| (_,[]),(cf,(_::_ as l)) ->
@@ -254,7 +251,7 @@ let rec (find_call_occs : int -> constr -> constr ->
| Ind(_) -> (fun l -> expr), []
| Construct (_, _) -> (fun l -> expr), []
| Case(i,t,a,r) ->
- (match find_call_occs nb_lam f a with
+ (match find_call_occs nb_arg nb_lam f a with
cf, (arg1::args) -> (fun l -> mkCase(i, t, (cf l), r)),(arg1::args)
| _ -> (fun l -> expr),[])
| Fix(_) -> error "find_call_occs : Fix"
@@ -657,13 +654,13 @@ let rec introduce_all_values concl_tac is_mes acc_inv func context_fn
)
-let rec_leaf_terminate f_constr concl_tac is_mes acc_inv hrec (func:global_reference) eqs expr =
- match find_call_occs 0 f_constr expr with
+let rec_leaf_terminate nb_arg f_constr concl_tac is_mes acc_inv hrec (func:global_reference) eqs expr =
+ match find_call_occs nb_arg 0 f_constr expr with
| context_fn, args ->
observe_tac "introduce_all_values"
(introduce_all_values concl_tac is_mes acc_inv func context_fn eqs hrec args [] [])
-let proveterminate rec_arg_id is_mes acc_inv (hrec:identifier)
+let proveterminate nb_arg rec_arg_id is_mes acc_inv (hrec:identifier)
(f_constr:constr) (func:global_reference) base_leaf rec_leaf =
let rec proveterminate (eqs:constr list) (expr:constr) =
try
@@ -671,7 +668,7 @@ let proveterminate rec_arg_id is_mes acc_inv (hrec:identifier)
let v =
match (kind_of_term expr) with
Case (ci, t, a, l) ->
- (match find_call_occs 0 f_constr a with
+ (match find_call_occs nb_arg 0 f_constr a with
_,[] ->
(fun g ->
let destruct_tac, rev_to_thin_intro =
@@ -686,13 +683,13 @@ let proveterminate rec_arg_id is_mes acc_inv (hrec:identifier)
ci.ci_cstr_ndecls.(i))
0 (Array.to_list l)) g)
| _, _::_ ->
- (match find_call_occs 0 f_constr expr with
+ (match find_call_occs nb_arg 0 f_constr expr with
_,[] -> observe_tac "base_leaf" (base_leaf func eqs expr)
| _, _:: _ ->
observe_tac "rec_leaf"
(rec_leaf is_mes acc_inv hrec func eqs expr)))
| _ ->
- (match find_call_occs 0 f_constr expr with
+ (match find_call_occs nb_arg 0 f_constr expr with
_,[] ->
(try observe_tac "base_leaf" (base_leaf func eqs expr)
with e -> (msgerrnl (str "failure in base case");raise e ))
@@ -864,6 +861,7 @@ let whole_start (concl_tac:tactic) nb_args is_mes func input_type relation rec_a
rec_arg_id
(fun rec_arg_id hrec acc_inv g ->
(proveterminate
+ nb_args
[rec_arg_id]
is_mes
acc_inv
@@ -871,7 +869,7 @@ let whole_start (concl_tac:tactic) nb_args is_mes func input_type relation rec_a
(mkVar f_id)
func
base_leaf_terminate
- (rec_leaf_terminate (mkVar f_id) concl_tac)
+ (rec_leaf_terminate nb_args (mkVar f_id) concl_tac)
[]
expr
)
@@ -1304,12 +1302,12 @@ let rec_leaf_eq termine f ids functional eqs expr fn args =
functional termine f p heq1 p [] [] eqs ids args);
observe_tac "failing here" (apply (delayed_force refl_equal))]
-let rec prove_eq (termine:constr) (f:constr)(functional:global_reference)
+let rec prove_eq nb_arg (termine:constr) (f:constr)(functional:global_reference)
(eqs:constr list) (expr:constr) =
(* tclTRY *)
observe_tac "prove_eq" (match kind_of_term expr with
Case(ci,t,a,l) ->
- (match find_call_occs 0 f a with
+ (match find_call_occs nb_arg 0 f a with
_,[] ->
(fun g ->
let destruct_tac,rev_to_thin_intro = mkDestructEq [] a g in
@@ -1318,11 +1316,11 @@ let rec prove_eq (termine:constr) (f:constr)(functional:global_reference)
(list_map_i
(fun i -> mk_intros_and_continue
(List.rev rev_to_thin_intro) true
- (prove_eq termine f functional)
+ (prove_eq nb_arg termine f functional)
eqs ci.ci_cstr_ndecls.(i))
0 (Array.to_list l)) g)
| _,_::_ ->
- (match find_call_occs 0 f expr with
+ (match find_call_occs nb_arg 0 f expr with
_,[] -> observe_tac "base_leaf_eq(1)" (base_leaf_eq functional eqs f)
| fn,args ->
fun g ->
@@ -1331,7 +1329,7 @@ let rec prove_eq (termine:constr) (f:constr)(functional:global_reference)
(constr_of_global functional)
eqs expr fn args) g))
| _ ->
- (match find_call_occs 0 f expr with
+ (match find_call_occs nb_arg 0 f expr with
_,[] -> observe_tac "base_leaf_eq(2)" ( base_leaf_eq functional eqs f)
| fn,args ->
fun g ->
@@ -1340,10 +1338,10 @@ let rec prove_eq (termine:constr) (f:constr)(functional:global_reference)
termine f ids (constr_of_global functional)
eqs expr fn args) g));;
-let (com_eqn : identifier ->
+let (com_eqn : int -> identifier ->
global_reference -> global_reference -> global_reference
-> constr -> unit) =
- fun eq_name functional_ref f_ref terminate_ref equation_lemma_type ->
+ fun nb_arg eq_name functional_ref f_ref terminate_ref equation_lemma_type ->
let opacity =
match terminate_ref with
| ConstRef c ->
@@ -1360,7 +1358,7 @@ let (com_eqn : identifier ->
by
(start_equation f_ref terminate_ref
(fun x ->
- prove_eq
+ prove_eq nb_arg
(constr_of_global terminate_ref)
f_constr
functional_ref
@@ -1393,12 +1391,12 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
generate_induction_principle using_lemmas : unit =
let function_type = interp_constr Evd.empty (Global.env()) type_of_f in
let env = push_named (function_name,None,function_type) (Global.env()) in
-(* Pp.msgnl (str "function type := " ++ Printer.pr_lconstr function_type); *)
+ (* Pp.msgnl (str "function type := " ++ Printer.pr_lconstr function_type); *)
let equation_lemma_type =
nf_betaiotazeta
(interp_gen (OfType None) Evd.empty env ~impls:rec_impls eq)
in
-(* Pp.msgnl (str "lemma type := " ++ Printer.pr_lconstr equation_lemma_type ++ fnl ()); *)
+ (* Pp.msgnl (str "lemma type := " ++ Printer.pr_lconstr equation_lemma_type ++ fnl ()); *)
let res_vars,eq' = decompose_prod equation_lemma_type in
let env_eq' = Environ.push_rel_context (List.map (fun (x,y) -> (x,None,y)) res_vars) env in
let eq' = nf_zeta env_eq' eq' in
@@ -1434,7 +1432,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
(* message "start second proof"; *)
let stop = ref false in
begin
- try com_eqn equation_id functional_ref f_ref term_ref (subst_var function_name equation_lemma_type)
+ try com_eqn (List.length res_vars) equation_id functional_ref f_ref term_ref (subst_var function_name equation_lemma_type)
with e ->
begin
if Tacinterp.get_debug () <> Tactic_debug.DebugOff