aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar jforest <jforest@85f007b7-540e-0410-9357-904b9bb8a0f7>2008-11-23 20:31:14 +0000
committerGravatar jforest <jforest@85f007b7-540e-0410-9357-904b9bb8a0f7>2008-11-23 20:31:14 +0000
commit31eac37de7a01bf67be3e5547792794f97142f25 (patch)
tree72b1aa46db7737251b059edb2a342d7ab52abfb8
parent1e77a259834aa570a0ff41be7b9ba3f9e81cfe52 (diff)
first attempt to allow Function to deal with dependent pattern matching. This Functionnality is VERY VERY experimental and only works with non recursive functions and structurally defined function
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@11624 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--contrib/funind/functional_principles_proofs.ml151
-rw-r--r--contrib/funind/functional_principles_types.ml10
-rw-r--r--contrib/funind/indfun.ml16
-rw-r--r--contrib/funind/indfun_common.ml24
-rw-r--r--contrib/funind/indfun_common.mli4
-rw-r--r--contrib/funind/rawterm_to_relation.ml239
6 files changed, 337 insertions, 107 deletions
diff --git a/contrib/funind/functional_principles_proofs.ml b/contrib/funind/functional_principles_proofs.ml
index 6241eb1de..903136ca2 100644
--- a/contrib/funind/functional_principles_proofs.ml
+++ b/contrib/funind/functional_principles_proofs.ml
@@ -59,9 +59,9 @@ let list_chop ?(msg="") n l =
failwith (msg ^ msg')
-let make_refl_eq type_of_t t =
- let refl_equal_term = Lazy.force refl_equal in
- mkApp(refl_equal_term,[|type_of_t;t|])
+let make_refl_eq constructor type_of_t t =
+(* let refl_equal_term = Lazy.force refl_equal in *)
+ mkApp(constructor,[|type_of_t;t|])
type pte_info =
@@ -109,11 +109,19 @@ let intro_erasing id = tclTHEN (thin [id]) (introduction id)
let rec_hyp_id = id_of_string "rec_hyp"
let is_trivial_eq t =
- match kind_of_term t with
- | App(f,[|_;t1;t2|]) when eq_constr f (Lazy.force eq) ->
- eq_constr t1 t2
- | _ -> false
-
+ let res = try
+ begin
+ match kind_of_term t with
+ | App(f,[|_;t1;t2|]) when eq_constr f (Lazy.force eq) ->
+ eq_constr t1 t2
+ | App(f,[|t1;a1;t2;a2|]) when eq_constr f (jmeq ()) ->
+ eq_constr t1 t2 && eq_constr a1 a2
+ | _ -> false
+ end
+ with _ -> false
+ in
+(* observe (str "is_trivial_eq " ++ Printer.pr_lconstr t ++ (if res then str " true" else str " false")); *)
+ res
let rec incompatible_constructor_terms t1 t2 =
let c1,arg1 = decompose_app t1
@@ -127,10 +135,19 @@ let rec incompatible_constructor_terms t1 t2 =
)
let is_incompatible_eq t =
- match kind_of_term t with
- | App(f,[|_;t1;t2|]) when eq_constr f (Lazy.force eq) ->
- incompatible_constructor_terms t1 t2
- | _ -> false
+ let res =
+ try
+ match kind_of_term t with
+ | App(f,[|_;t1;t2|]) when eq_constr f (Lazy.force eq) ->
+ incompatible_constructor_terms t1 t2
+ | App(f,[|u1;t1;u2;t2|]) when eq_constr f (jmeq ()) ->
+ (eq_constr u1 u2 &&
+ incompatible_constructor_terms t1 t2)
+ | _ -> false
+ with _ -> false
+ in
+ if res then observe (str "is_incompatible_eq " ++ Printer.pr_lconstr t);
+ res
let change_hyp_with_using msg hyp_id t tac : tactic =
fun g ->
@@ -146,7 +163,7 @@ let change_hyp_with_using msg hyp_id t tac : tactic =
exception TOREMOVE
-let prove_trivial_eq h_id context (type_of_term,term) =
+let prove_trivial_eq h_id context (constructor,type_of_term,term) =
let nb_intros = List.length context in
tclTHENLIST
[
@@ -156,7 +173,7 @@ let prove_trivial_eq h_id context (type_of_term,term) =
fst (list_chop ~msg:"prove_trivial_eq : " nb_intros (pf_ids_of_hyps g))
in
let context_hyps' =
- (mkApp(Lazy.force refl_equal,[|type_of_term;term|]))::
+ (mkApp(constructor,[|type_of_term;term|]))::
(List.map mkVar context_hyps)
in
let to_refine = applist(mkVar h_id,List.rev context_hyps') in
@@ -165,10 +182,21 @@ let prove_trivial_eq h_id context (type_of_term,term) =
]
-let isAppConstruct t =
- if isApp t
- then isConstruct (fst (destApp t))
- else false
+
+let find_rectype env c =
+ let (t, l) = decompose_app (Reduction.whd_betadeltaiota env c) in
+ match kind_of_term t with
+ | Ind ind -> (t, l)
+ | Construct _ -> (t,l)
+ | _ -> raise Not_found
+
+
+let isAppConstruct ?(env=Global.env ()) t =
+ try
+ let t',l = find_rectype (Global.env ()) t in
+ observe (str "isAppConstruct : " ++ Printer.pr_lconstr t ++ str " -> " ++ Printer.pr_lconstr (applist (t',l)));
+ true
+ with Not_found -> false
let nf_betaiotazeta = (* Reductionops.local_strong Reductionops.whd_betaiotazeta *)
let clos_norm_flags flgs env sigma t =
@@ -176,10 +204,11 @@ let nf_betaiotazeta = (* Reductionops.local_strong Reductionops.whd_betaiotazeta
clos_norm_flags Closure.betaiotazeta Environ.empty_env Evd.empty
+
let change_eq env sigma hyp_id (context:Sign.rel_context) x t end_of_type =
- let nochange msg =
+ let nochange ?t' msg =
begin
-(* observe (str ("Not treating ( "^msg^" )") ++ pr_lconstr t ); *)
+ observe (str ("Not treating ( "^msg^" )") ++ pr_lconstr t ++ str " " ++ match t' with None -> str "" | Some t -> Printer.pr_lconstr t );
failwith "NoChange";
end
in
@@ -188,12 +217,23 @@ let change_eq env sigma hyp_id (context:Sign.rel_context) x t end_of_type =
then nochange "dependent"; (* if end_of_type depends on this term we don't touch it *)
if not (isApp t) then nochange "not an equality";
let f_eq,args = destApp t in
- if not (eq_constr f_eq (Lazy.force eq)) then nochange "not an equality";
- let t1 = args.(1)
- and t2 = args.(2)
- and t1_typ = args.(0)
+ let constructor,t1,t2,t1_typ =
+ try
+ if (eq_constr f_eq (Lazy.force eq))
+ then
+ let t1 = (args.(1),args.(0))
+ and t2 = (args.(2),args.(0))
+ and t1_typ = args.(0)
+ in
+ (Lazy.force refl_equal,t1,t2,t1_typ)
+ else
+ if (eq_constr f_eq (jmeq ()))
+ then
+ (jmeq_refl (),(args.(1),args.(0)),(args.(3),args.(2)),args.(0))
+ else nochange "not an equality"
+ with _ -> nochange "not an equality"
in
- if not (closed0 t1) then nochange "not a closed lhs";
+ if not ((closed0 (fst t1)) && (closed0 (snd t1)))then nochange "not a closed lhs";
let rec compute_substitution sub t1 t2 =
(* observe (str "compute_substitution : " ++ pr_lconstr t1 ++ str " === " ++ pr_lconstr t2); *)
if isRel t2
@@ -211,16 +251,17 @@ let change_eq env sigma hyp_id (context:Sign.rel_context) x t end_of_type =
else if isAppConstruct t1 && isAppConstruct t2
then
begin
- let c1,args1 = destApp t1
- and c2,args2 = destApp t2
+ let c1,args1 = find_rectype env t1
+ and c2,args2 = find_rectype env t2
in
- if not (eq_constr c1 c2) then anomaly "deconstructing equation";
- array_fold_left2 compute_substitution sub args1 args2
+ if not (eq_constr c1 c2) then nochange "cannot solve (diff)";
+ List.fold_left2 compute_substitution sub args1 args2
end
else
- if (eq_constr t1 t2) then sub else nochange "cannot solve"
+ if (eq_constr t1 t2) then sub else nochange ~t':(make_refl_eq constructor (Reduction.whd_betadeltaiota env t1) t2) "cannot solve (diff)"
in
- let sub = compute_substitution Intmap.empty t1 t2 in
+ let sub = compute_substitution Intmap.empty (snd t1) (snd t2) in
+ let sub = compute_substitution sub (fst t1) (fst t2) in
let end_of_type_with_pop = pop end_of_type in (*the equation will be removed *)
let new_end_of_type =
(* Ugly hack to prevent Map.fold order change between ocaml-3.08.3 and ocaml-3.08.4
@@ -234,7 +275,7 @@ let change_eq env sigma hyp_id (context:Sign.rel_context) x t end_of_type =
in
let old_context_length = List.length context + 1 in
let witness_fun =
- mkLetIn(Anonymous,make_refl_eq t1_typ t1,t,
+ mkLetIn(Anonymous,make_refl_eq constructor t1_typ (fst t1),t,
mkApp(mkVar hyp_id,Array.init old_context_length (fun i -> mkRel (old_context_length - i)))
)
in
@@ -450,14 +491,20 @@ let clean_hyp_with_heq ptes_infos eq_hyps hyp_id env sigma =
let real_type_of_hyp =
it_mkProd_or_LetIn ~init:popped_t' context
in
- let _,args = destApp t_x in
+ let hd,args = destApp t_x in
+ let get_args hd args =
+ if eq_constr hd (Lazy.force eq)
+ then (Lazy.force refl_equal,args.(0),args.(1))
+ else (jmeq_refl (),args.(0),args.(1))
+ in
tclTHENLIST
[
change_hyp_with_using
"prove_trivial_eq"
hyp_id
real_type_of_hyp
- ((* observe_tac "prove_trivial_eq" *) (prove_trivial_eq hyp_id context (args.(0),args.(1))));
+ ((* observe_tac "prove_trivial_eq" *)
+ (prove_trivial_eq hyp_id context (get_args hd args)));
scan_type context popped_t'
]
else
@@ -631,28 +678,32 @@ let build_proof
let g_nb_prod = nb_prod (pf_concl g) in
let type_of_term = pf_type_of g t in
let term_eq =
- make_refl_eq type_of_term t
+ make_refl_eq (Lazy.force refl_equal) type_of_term t
in
tclTHENSEQ
[
h_generalize (term_eq::(List.map mkVar dyn_infos.rec_hyps));
thin dyn_infos.rec_hyps;
pattern_option [(false,[1]),t] None;
- h_simplest_case t;
- (fun g' ->
- let g'_nb_prod = nb_prod (pf_concl g') in
- let nb_instanciate_partial = g'_nb_prod - g_nb_prod in
- observe_tac "treat_new_case"
- (treat_new_case
- ptes_infos
- nb_instanciate_partial
- (build_proof do_finalize)
- t
- dyn_infos)
- g'
- )
+ (fun g -> observe_tac "toto" (
+ tclTHENSEQ [h_simplest_case t;
+ (fun g' ->
+ let g'_nb_prod = nb_prod (pf_concl g') in
+ let nb_instanciate_partial = g'_nb_prod - g_nb_prod in
+ observe_tac "treat_new_case"
+ (treat_new_case
+ ptes_infos
+ nb_instanciate_partial
+ (build_proof do_finalize)
+ t
+ dyn_infos)
+ g'
+ )
- ] g
+ ]) g
+ )
+ ]
+ g
in
build_proof do_finalize_t {dyn_infos with info = t} g
| Lambda(n,t,b) ->
@@ -1206,7 +1257,7 @@ let prove_princ_for_struct interactive_proof fun_num fnames all_funs _nparams :
nb_rec_hyps = List.length branches
}
in
- (* observe_tac "cleaning" *) (clean_goal_with_heq
+ observe_tac "cleaning" (clean_goal_with_heq
(Idmap.map prove_rec_hyp ptes_to_fix)
do_prove
dyn_infos)
diff --git a/contrib/funind/functional_principles_types.ml b/contrib/funind/functional_principles_types.ml
index b03bdf31a..5155e614d 100644
--- a/contrib/funind/functional_principles_types.ml
+++ b/contrib/funind/functional_principles_types.ml
@@ -328,7 +328,7 @@ let build_functional_principle interactive_proof old_princ_type sorts funs i pro
in
(* let time2 = System.get_time () in *)
(* Pp.msgnl (str "computing principle type := " ++ System.fmt_time_difference time1 time2); *)
- (* observe (str "new_principle_type : " ++ pr_lconstr new_principle_type); *)
+ observe (str "new_principle_type : " ++ pr_lconstr new_principle_type);
let new_princ_name =
next_global_ident_away true (id_of_string "___________princ_________") []
in
@@ -356,6 +356,7 @@ let generate_functional_principle
old_princ_type sorts new_princ_name funs i proof_tac
=
try
+
let f = funs.(i) in
let type_sort = Termops.new_sort_in_family InType in
let new_sorts =
@@ -718,9 +719,10 @@ let build_case_scheme fa =
in
let princ_name = (fun (x,_,_) -> x) fa in
let _ =
-(* observe (str "Generating " ++ Ppconstr.pr_id princ_name ++str " with " ++ *)
-(* pr_lconstr scheme_type ++ str " and " ++ (fun a -> prlist_with_sep spc (fun c -> pr_lconstr (mkConst c)) (Array.to_list a)) this_block_funs *)
-(* ); *)
+ (* Pp.msgnl (str "Generating " ++ Ppconstr.pr_id princ_name ++str " with " ++
+ pr_lconstr scheme_type ++ str " and " ++ (fun a -> prlist_with_sep spc (fun c -> pr_lconstr (mkConst c)) (Array.to_list a)) this_block_funs
+ );
+ *)
generate_functional_principle
false
scheme_type
diff --git a/contrib/funind/indfun.ml b/contrib/funind/indfun.ml
index b6b2cbd11..d7a7c311a 100644
--- a/contrib/funind/indfun.ml
+++ b/contrib/funind/indfun.ml
@@ -272,26 +272,36 @@ let derive_inversion fix_names =
with _ -> ()
let warning_error names e =
+ let e_explain e =
+ match e with
+ | ToShow e -> spc () ++ Cerrors.explain_exn e
+ | _ -> if do_observe () then (spc () ++ Cerrors.explain_exn e) else mt ()
+ in
match e with
| Building_graph e ->
Pp.msg_warning
(str "Cannot define graph(s) for " ++
h 1 (prlist_with_sep (fun _ -> str","++spc ()) Ppconstr.pr_id names) ++
- if do_observe () then (spc () ++ Cerrors.explain_exn e) else mt ())
+ e_explain e)
| Defining_principle e ->
Pp.msg_warning
(str "Cannot define principle(s) for "++
h 1 (prlist_with_sep (fun _ -> str","++spc ()) Ppconstr.pr_id names) ++
- if do_observe () then Cerrors.explain_exn e else mt ())
+ e_explain e)
| _ -> anomaly ""
let error_error names e =
+ let e_explain e =
+ match e with
+ | ToShow e -> spc () ++ Cerrors.explain_exn e
+ | _ -> if do_observe () then (spc () ++ Cerrors.explain_exn e) else mt ()
+ in
match e with
| Building_graph e ->
errorlabstrm ""
(str "Cannot define graph(s) for " ++
h 1 (prlist_with_sep (fun _ -> str","++spc ()) Ppconstr.pr_id names) ++
- if do_observe () then (spc () ++ Cerrors.explain_exn e) else mt ())
+ e_explain e)
| _ -> anomaly ""
let generate_principle on_error
diff --git a/contrib/funind/indfun_common.ml b/contrib/funind/indfun_common.ml
index 4892128a0..69cc0607b 100644
--- a/contrib/funind/indfun_common.ml
+++ b/contrib/funind/indfun_common.ml
@@ -524,3 +524,27 @@ let _ = declare_bool_option strict_tcc_sig
exception Building_graph of exn
exception Defining_principle of exn
+exception ToShow of exn
+
+let init_constant dir s =
+ try
+ Coqlib.gen_constant "Function" dir s
+ with e -> raise (ToShow e)
+
+let jmeq () =
+ try
+ (Coqlib.check_required_library ["Coq";"Logic";"JMeq"];
+ init_constant ["Logic";"JMeq"] "JMeq")
+ with e -> raise (ToShow e)
+
+let jmeq_rec () =
+ try
+ Coqlib.check_required_library ["Coq";"Logic";"JMeq"];
+ init_constant ["Logic";"JMeq"] "JMeq_rec"
+ with e -> raise (ToShow e)
+
+let jmeq_refl () =
+ try
+ Coqlib.check_required_library ["Coq";"Logic";"JMeq"];
+ init_constant ["Logic";"JMeq"] "JMeq_refl"
+ with e -> raise (ToShow e)
diff --git a/contrib/funind/indfun_common.mli b/contrib/funind/indfun_common.mli
index 2d741f0b3..e9aa692b6 100644
--- a/contrib/funind/indfun_common.mli
+++ b/contrib/funind/indfun_common.mli
@@ -45,7 +45,8 @@ val def_of_const : Term.constr -> Term.constr
val eq : Term.constr Lazy.t
val refl_equal : Term.constr Lazy.t
val const_of_id: identifier -> constant
-
+val jmeq : unit -> Term.constr
+val jmeq_refl : unit -> Term.constr
(* [save_named] is a copy of [Command.save_named] but uses
[nf_betaiotazeta] instead of [nf_betaiotaevar_preserving_vm_cast]
@@ -114,5 +115,6 @@ val do_observe : unit -> bool
(* To localize pb *)
exception Building_graph of exn
exception Defining_principle of exn
+exception ToShow of exn
val is_strict_tcc : unit -> bool
diff --git a/contrib/funind/rawterm_to_relation.ml b/contrib/funind/rawterm_to_relation.ml
index 75f6207fc..d54aca4e6 100644
--- a/contrib/funind/rawterm_to_relation.ml
+++ b/contrib/funind/rawterm_to_relation.ml
@@ -25,7 +25,6 @@ type binder_type =
type raw_context = (binder_type*rawconstr) list
-
(*
compose_raw_context [(bt_1,n_1,t_1);......] rt returns
b_1(n_1,t_1,.....,bn(n_k,t_k,rt)) where the b_i's are the
@@ -712,20 +711,25 @@ and build_entry_lc_from_case env funname make_discr
el
(mk_result [] [] avoid)
in
- (****** The next works only if the match is not dependent ****)
let types =
List.map (fun (case_arg,_) ->
let case_arg_as_constr = Pretyping.Default.understand Evd.empty env case_arg in
Typing.type_of env Evd.empty case_arg_as_constr
) el
in
+ (****** The next works only if the match is not dependent ****)
let results =
List.map
- (build_entry_lc_from_case_term
+ (fun ca ->
+ let res = build_entry_lc_from_case_term
env types
- funname (make_discr (* (List.map fst el) *))
+ funname (make_discr)
[] brl
- case_resl.to_avoid)
+ case_resl.to_avoid
+ ca
+ in
+ res
+ )
case_resl.result
in
{
@@ -754,14 +758,17 @@ and build_entry_lc_from_case_term env types funname make_discr patterns_to_preve
let pat_ids = get_pattern_id renamed_pat in
let env_with_pat_ids = add_pat_variables pat typ new_env in
List.fold_right
- (fun id acc ->
- let typ_of_id = Typing.type_of env_with_pat_ids Evd.empty (mkVar id) in
- let raw_typ_of_id =
- Detyping.detype false [] (Termops.names_of_rel_context env_with_pat_ids) typ_of_id
- in
- mkRProd (Name id,raw_typ_of_id,acc))
- pat_ids
- (raw_make_neq pat'_as_term (pattern_to_term renamed_pat))
+ (fun id acc ->
+ let typ_of_id =
+ Typing.type_of env_with_pat_ids Evd.empty (mkVar id)
+ in
+ let raw_typ_of_id =
+ Detyping.detype false []
+ (Termops.names_of_rel_context env_with_pat_ids) typ_of_id
+ in
+ mkRProd (Name id,raw_typ_of_id,acc))
+ pat_ids
+ (raw_make_neq pat'_as_term (pattern_to_term renamed_pat))
)
patl
types
@@ -790,7 +797,6 @@ and build_entry_lc_from_case_term env types funname make_discr patterns_to_preve
matched_expr
in
(* We now create the precondition of this branch i.e.
-
1- the list of variable appearing in the different patterns of this branch and
the list of equation stating than el = patl (List.flatten ...)
2- If there exists a previous branch which pattern unify with the one of this branch
@@ -815,7 +821,6 @@ and build_entry_lc_from_case_term env types funname make_discr patterns_to_preve
raw_typ_of_id
)::acc
else acc
-
)
idl
[(Prod Anonymous,raw_make_eq ~typ pat_as_term e)]
@@ -863,7 +868,9 @@ let is_res id =
rebuild the raw constructors expression.
eliminates some meaningless equalities, applies some rewrites......
*)
-let rec rebuild_cons nb_args relname args crossed_types depth rt =
+let rec rebuild_cons env nb_args relname args crossed_types depth rt =
+ observe (str "rebuilding : " ++ pr_rawconstr rt);
+
match rt with
| RProd(_,n,k,t,b) ->
let not_free_in_t id = not (is_free_in id t) in
@@ -874,50 +881,147 @@ let rec rebuild_cons nb_args relname args crossed_types depth rt =
begin
match args' with
| (RVar(_,this_relname))::args' ->
- let new_b,id_to_exclude =
- rebuild_cons
- nb_args relname
- args new_crossed_types
- (depth + 1) b
- in
- (*i The next call to mk_rel_id is valid since we are constructing the graph
+ (*i The next call to mk_rel_id is
+ valid since we are constructing the graph
Ensures by: obvious
i*)
let new_t =
mkRApp(mkRVar(mk_rel_id this_relname),args'@[res_rt])
- in mkRProd(n,new_t,new_b),
+ in
+ let t' = Pretyping.Default.understand Evd.empty env new_t in
+ let new_env = Environ.push_rel (n,None,t') env in
+ let new_b,id_to_exclude =
+ rebuild_cons new_env
+ nb_args relname
+ args new_crossed_types
+ (depth + 1) b
+ in
+ mkRProd(n,new_t,new_b),
Idset.filter not_free_in_t id_to_exclude
| _ -> (* the first args is the name of the function! *)
assert false
end
- | RApp(_,RRef(_,eq_as_ref),[_;RVar(_,id);rt])
+ | RApp(loc1,RRef(loc2,eq_as_ref),[ty;RVar(loc3,id);rt])
when eq_as_ref = Lazy.force Coqlib.coq_eq_ref && n = Anonymous
->
- let is_in_b = is_free_in id b in
- let _keep_eq =
- not (List.exists (is_free_in id) args) || is_in_b ||
- List.exists (is_free_in id) crossed_types
- in
- let new_args = List.map (replace_var_by_term id rt) args in
- let subst_b =
- if is_in_b then b else replace_var_by_term id rt b
- in
- let new_b,id_to_exclude =
- rebuild_cons
- nb_args relname
- new_args new_crossed_types
- (depth + 1) subst_b
- in
- mkRProd(n,t,new_b),id_to_exclude
+ begin
+ try
+ observe (str "computing new type for eq : " ++ pr_rawconstr rt);
+ let t' = Pretyping.Default.understand Evd.empty env t in
+ let is_in_b = is_free_in id b in
+ let _keep_eq =
+ not (List.exists (is_free_in id) args) || is_in_b ||
+ List.exists (is_free_in id) crossed_types
+ in
+ let new_args = List.map (replace_var_by_term id rt) args in
+ let subst_b =
+ if is_in_b then b else replace_var_by_term id rt b
+ in
+ let new_env = Environ.push_rel (n,None,t') env in
+ let new_b,id_to_exclude =
+ rebuild_cons
+ new_env
+ nb_args relname
+ new_args new_crossed_types
+ (depth + 1) subst_b
+ in
+ mkRProd(n,t,new_b),id_to_exclude
+ with _ ->
+ let jmeq = Libnames.IndRef (destInd (jmeq ())) in
+ let ty' = Pretyping.Default.understand Evd.empty env ty in
+ let ind,args' = Inductive.find_inductive env ty' in
+ let mib,_ = Global.lookup_inductive ind in
+ let nparam = mib.Declarations.mind_nparams in
+ let params,arg' =
+ ((Util.list_chop nparam args'))
+ in
+ let rt_typ =
+ RApp(Util.dummy_loc,
+ RRef (Util.dummy_loc,Libnames.IndRef ind),
+ (List.map
+ (fun p -> Detyping.detype false []
+ (Termops.names_of_rel_context env)
+ p) params)@(Array.to_list
+ (Array.make
+ (List.length args' - nparam)
+ (mkRHole ()))))
+ in
+ let eq' =
+ RApp(loc1,RRef(loc2,jmeq),[ty;RVar(loc3,id);rt_typ;rt])
+ in
+ observe (str "computing new type for jmeq : " ++ pr_rawconstr eq');
+ let eq'_as_constr = Pretyping.Default.understand Evd.empty env eq' in
+ observe (str " computing new type for jmeq : done") ;
+ let new_args =
+ match kind_of_term eq'_as_constr with
+ | App(_,[|_;_;ty;_|]) ->
+ let ty = Array.to_list (snd (destApp ty)) in
+ let ty' = snd (Util.list_chop nparam ty) in
+ List.fold_left2
+ (fun acc var_as_constr arg ->
+ if isRel var_as_constr
+ then
+ let (na,_,_) =
+ Environ.lookup_rel (destRel var_as_constr) env
+ in
+ match na with
+ | Anonymous -> acc
+ | Name id' ->
+ (id',Detyping.detype false []
+ (Termops.names_of_rel_context env)
+ arg)::acc
+ else if isVar var_as_constr
+ then (destVar var_as_constr,Detyping.detype false []
+ (Termops.names_of_rel_context env)
+ arg)::acc
+ else acc
+ )
+ []
+ arg'
+ ty'
+ | _ -> assert false
+ in
+ let is_in_b = is_free_in id b in
+ let _keep_eq =
+ not (List.exists (is_free_in id) args) || is_in_b ||
+ List.exists (is_free_in id) crossed_types
+ in
+ let new_args =
+ List.fold_left
+ (fun args (id,rt) ->
+ List.map (replace_var_by_term id rt) args
+ )
+ args
+ ((id,rt)::new_args)
+ in
+ let subst_b =
+ if is_in_b then b else replace_var_by_term id rt b
+ in
+ let new_env =
+ let t' = Pretyping.Default.understand Evd.empty env eq' in
+ Environ.push_rel (n,None,t') env
+ in
+ let new_b,id_to_exclude =
+ rebuild_cons
+ new_env
+ nb_args relname
+ new_args new_crossed_types
+ (depth + 1) subst_b
+ in
+ mkRProd(n,eq',new_b),id_to_exclude
+ end
(* J.F:. keep this comment it explain how to remove some meaningless equalities
if keep_eq then
mkRProd(n,t,new_b),id_to_exclude
else new_b, Idset.add id id_to_exclude
*)
| _ ->
+ observe (str "computing new type for prod : " ++ pr_rawconstr rt);
+ let t' = Pretyping.Default.understand Evd.empty env t in
+ let new_env = Environ.push_rel (n,None,t') env in
let new_b,id_to_exclude =
- rebuild_cons
+ rebuild_cons new_env
nb_args relname
args new_crossed_types
(depth + 1) b
@@ -932,10 +1036,13 @@ let rec rebuild_cons nb_args relname args crossed_types depth rt =
begin
let not_free_in_t id = not (is_free_in id t) in
let new_crossed_types = t :: crossed_types in
+ observe (str "computing new type for lambda : " ++ pr_rawconstr rt);
+ let t' = Pretyping.Default.understand Evd.empty env t in
match n with
| Name id ->
+ let new_env = Environ.push_rel (n,None,t') env in
let new_b,id_to_exclude =
- rebuild_cons
+ rebuild_cons new_env
nb_args relname
(args@[mkRVar id])new_crossed_types
(depth + 1 ) b
@@ -952,8 +1059,11 @@ let rec rebuild_cons nb_args relname args crossed_types depth rt =
| RLetIn(_,n,t,b) ->
begin
let not_free_in_t id = not (is_free_in id t) in
+ let t' = Pretyping.Default.understand Evd.empty env t in
+ let type_t' = Typing.type_of env Evd.empty t' in
+ let new_env = Environ.push_rel (n,Some t',type_t') env in
let new_b,id_to_exclude =
- rebuild_cons
+ rebuild_cons new_env
nb_args relname
args (t::crossed_types)
(depth + 1 ) b in
@@ -968,14 +1078,16 @@ let rec rebuild_cons nb_args relname args crossed_types depth rt =
begin
let not_free_in_t id = not (is_free_in id t) in
let new_t,id_to_exclude' =
- rebuild_cons
+ rebuild_cons env
nb_args
relname
args (crossed_types)
depth t
in
+ let t' = Pretyping.Default.understand Evd.empty env new_t in
+ let new_env = Environ.push_rel (na,None,t') env in
let new_b,id_to_exclude =
- rebuild_cons
+ rebuild_cons new_env
nb_args relname
args (t::crossed_types)
(depth + 1) b
@@ -993,11 +1105,11 @@ let rec rebuild_cons nb_args relname args crossed_types depth rt =
(* debuging wrapper *)
-let rebuild_cons nb_args relname args crossed_types rt =
+let rebuild_cons env nb_args relname args crossed_types rt =
(* observennl (str "rebuild_cons : rt := "++ pr_rawconstr rt ++ *)
(* str "nb_args := " ++ str (string_of_int nb_args)); *)
let res =
- rebuild_cons nb_args relname args crossed_types 0 rt
+ rebuild_cons env nb_args relname args crossed_types 0 rt
in
(* observe (str " leads to "++ pr_rawconstr (fst res)); *)
res
@@ -1103,6 +1215,35 @@ let do_build_inductive
(Global.env ())
in
let resa = Array.map (build_entry_lc env funnames_as_set []) rta in
+ let env_with_graphs =
+ let rel_arity i funargs = (* Reduilding arities (with parameters) *)
+ let rel_first_args :(Names.name * Rawterm.rawconstr * bool ) list =
+ funargs
+ in
+ List.fold_right
+ (fun (n,t,is_defined) acc ->
+ if is_defined
+ then
+ Topconstr.CLetIn(dummy_loc,(dummy_loc, n),Constrextern.extern_rawconstr Idset.empty t,
+ acc)
+ else
+ Topconstr.CProdN
+ (dummy_loc,
+ [[(dummy_loc,n)],Topconstr.default_binder_kind,Constrextern.extern_rawconstr Idset.empty t],
+ acc
+ )
+ )
+ rel_first_args
+ (rebuild_return_type returned_types.(i))
+ in
+ (* We need to lift back our work topconstr but only with all information
+ We mimick a Set Printing All.
+ Then save the graphs and reset Printing options to their primitive values
+ *)
+ let rel_arities = Array.mapi rel_arity funsargs in
+ Util.array_fold_left2 (fun env rel_name rel_ar ->
+ Environ.push_named (rel_name,None, Constrintern.interp_constr Evd.empty env rel_ar) env) env relnames rel_arities
+ in
(* and of the real constructors*)
let constr i res =
List.map
@@ -1111,7 +1252,7 @@ let do_build_inductive
let nb_args = List.length funsargs.(i) in
(* with_full_print (fun rt -> Pp.msgnl (str "raw constr " ++ pr_rawconstr rt)) rt; *)
fst (
- rebuild_cons nb_args relnames.(i)
+ rebuild_cons env_with_graphs nb_args relnames.(i)
[]
[]
rt