diff options
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | pretyping/pretype_errors.ml | 2 | ||||
-rw-r--r-- | pretyping/pretype_errors.mli | 2 | ||||
-rw-r--r-- | pretyping/unification.ml | 29 | ||||
-rw-r--r-- | pretyping/unification.mli | 1 | ||||
-rw-r--r-- | proofs/clenvtac.ml | 1 | ||||
-rw-r--r-- | tactics/auto.ml | 3 | ||||
-rw-r--r-- | tactics/class_tactics.ml4 | 130 | ||||
-rw-r--r-- | tactics/equality.ml | 24 | ||||
-rw-r--r-- | tactics/setoid_replace.ml | 8 | ||||
-rw-r--r-- | tactics/tactics.ml | 1 | ||||
-rw-r--r-- | test-suite/bugs/closed/shouldsucceed/121.v | 17 | ||||
-rw-r--r-- | test-suite/bugs/closed/shouldsucceed/1425.v | 13 | ||||
-rw-r--r-- | test-suite/bugs/closed/shouldsucceed/1604.v | 7 | ||||
-rw-r--r-- | test-suite/bugs/closed/shouldsucceed/1683.v | 42 | ||||
-rw-r--r-- | test-suite/bugs/closed/shouldsucceed/1696.v | 16 | ||||
-rw-r--r-- | test-suite/bugs/closed/shouldsucceed/1738.v | 30 | ||||
-rw-r--r-- | test-suite/bugs/opened/shouldnotfail/1596.v | 242 | ||||
-rw-r--r-- | test-suite/bugs/opened/shouldnotfail/1811.v | 9 | ||||
-rw-r--r-- | theories/Classes/Morphisms.v | 6 | ||||
-rw-r--r-- | toplevel/himsg.ml | 9 |
21 files changed, 508 insertions, 86 deletions
@@ -209,7 +209,7 @@ Setoid rewriting and declare morphisms. - "-->", "++>" and "==>" are now right associative notations - declared at level 55 in scope signature_scope. + declared at level 90 in scope signature_scope. Their introduction may break existing scripts that defined them as notations with different levels. diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml index f19dd1f97..cd32ac450 100644 --- a/pretyping/pretype_errors.ml +++ b/pretyping/pretype_errors.ml @@ -31,7 +31,7 @@ type pretype_error = | CannotUnifyLocal of constr * constr * constr | CannotUnifyBindingType of constr * constr | CannotGeneralize of constr - | NoOccurrenceFound of constr + | NoOccurrenceFound of constr * identifier option (* Pretyping *) | VarNotFound of identifier | UnexpectedType of constr * constr diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli index fbee6e04d..c6527f337 100644 --- a/pretyping/pretype_errors.mli +++ b/pretyping/pretype_errors.mli @@ -33,7 +33,7 @@ type pretype_error = | CannotUnifyLocal of constr * constr * constr | CannotUnifyBindingType of constr * constr | CannotGeneralize of constr - | NoOccurrenceFound of constr + | NoOccurrenceFound of constr * identifier option (* Pretyping *) | VarNotFound of identifier | UnexpectedType of constr * constr diff --git a/pretyping/unification.ml b/pretyping/unification.ml index b1a4c3b8c..f11ed36da 100644 --- a/pretyping/unification.ml +++ b/pretyping/unification.ml @@ -96,13 +96,6 @@ let solve_pattern_eqn_array env f l c (metasubst,evarsubst) = metasubst,(ev,solve_pattern_eqn env (Array.to_list l) c)::evarsubst | _ -> assert false -let expand_constant env predcst c = - let (ids,csts) = Conv_oracle.freeze() in - match kind_of_term c with - | Const cst when Cpred.mem cst csts && Cpred.mem cst predcst -> constant_opt_value env cst - | Var id when Idpred.mem id ids -> named_body id env - | _ -> None - (*******************************) (* Unification à l'ordre 0 de m et n: [unify_0 env sigma cv_pb m n] @@ -127,20 +120,30 @@ type unify_flags = { modulo_conv_on_closed_terms : bool; use_metas_eagerly : bool; modulo_delta : Cpred.t; + modulo_zeta : bool; } let default_unify_flags = { modulo_conv_on_closed_terms = true; use_metas_eagerly = true; modulo_delta = Cpred.full; + modulo_zeta = true; } let default_no_delta_unify_flags = { modulo_conv_on_closed_terms = true; use_metas_eagerly = true; modulo_delta = Cpred.empty; + modulo_zeta = true; } +let expand_constant env flags c = + let (ids,csts) = Conv_oracle.freeze() in + match kind_of_term c with + | Const cst when Cpred.mem cst csts && Cpred.mem cst flags.modulo_delta -> constant_opt_value env cst + | Var id when flags.modulo_zeta && Idpred.mem id ids -> named_body id env + | _ -> None + let unify_0_with_initial_metas metas conv_at_top env sigma cv_pb flags m n = let nb = nb_rel env in let trivial_unify pb (metasubst,_) m n = @@ -222,11 +225,11 @@ let unify_0_with_initial_metas metas conv_at_top env sigma cv_pb flags m n = and expand curenv pb b substn cM f1 l1 cN f2 l2 = if trivial_unify pb substn cM cN then substn else if b & not (Cpred.is_empty flags.modulo_delta) then - match expand_constant curenv flags.modulo_delta f1 with + match expand_constant curenv flags f1 with | Some c -> unirec_rec curenv pb b substn (whd_betaiotazeta (mkApp(c,l1))) cN | None -> - match expand_constant curenv flags.modulo_delta f2 with + match expand_constant curenv flags f2 with | Some c -> unirec_rec curenv pb b substn cM (whd_betaiotazeta (mkApp(c,l2))) | None -> @@ -608,7 +611,7 @@ let w_unify_to_subterm env ?(flags=default_unify_flags) (op,cl) evd = in try matchrec cl with ex when precatchable_exception ex -> - raise (PretypeError (env,NoOccurrenceFound op)) + raise (PretypeError (env,NoOccurrenceFound (op, None))) let w_unify_to_subterm_list env flags allow_K oplist t evd = List.fold_right @@ -628,7 +631,7 @@ let w_unify_to_subterm_list env flags allow_K oplist t evd = (evd,op::l) else (* This is not up to delta ... *) - raise (PretypeError (env,NoOccurrenceFound op))) + raise (PretypeError (env,NoOccurrenceFound (op, None)))) oplist (evd,[]) @@ -693,7 +696,7 @@ let w_unify allow_K env cv_pb ?(flags=default_unify_flags) ty1 ty2 evd = with ex when precatchable_exception ex -> try w_unify2 env flags allow_K cv_pb ty1 ty2 evd - with PretypeError (env,NoOccurrenceFound c) as e -> raise e + with PretypeError (env,NoOccurrenceFound _) as e -> raise e | ex when precatchable_exception ex -> error "Cannot solve a second-order unification problem") @@ -701,7 +704,7 @@ let w_unify allow_K env cv_pb ?(flags=default_unify_flags) ty1 ty2 evd = | (Meta _, true, _, _ | _, _, Meta _, true) -> (try w_unify2 env flags allow_K cv_pb ty1 ty2 evd - with PretypeError (env,NoOccurrenceFound c) as e -> raise e + with PretypeError (env,NoOccurrenceFound _) as e -> raise e | ex when precatchable_exception ex -> try w_typed_unify env cv_pb flags ty1 ty2 evd diff --git a/pretyping/unification.mli b/pretyping/unification.mli index e0551b625..8e8168e5c 100644 --- a/pretyping/unification.mli +++ b/pretyping/unification.mli @@ -18,6 +18,7 @@ type unify_flags = { modulo_conv_on_closed_terms : bool; use_metas_eagerly : bool; modulo_delta : Names.Cpred.t; + modulo_zeta : bool; } val default_unify_flags : unify_flags diff --git a/proofs/clenvtac.ml b/proofs/clenvtac.ml index 60abc5d66..c966e876f 100644 --- a/proofs/clenvtac.ml +++ b/proofs/clenvtac.ml @@ -99,6 +99,7 @@ let fail_quick_unif_flags = { modulo_conv_on_closed_terms = true; use_metas_eagerly = false; modulo_delta = Cpred.empty; + modulo_zeta = true; } (* let unifyTerms m n = walking (fun wc -> fst (w_Unify CONV m n [] wc)) *) diff --git a/tactics/auto.ml b/tactics/auto.ml index 52c483771..00d7b8cb4 100644 --- a/tactics/auto.ml +++ b/tactics/auto.ml @@ -567,7 +567,8 @@ open Unification let auto_unif_flags = { modulo_conv_on_closed_terms = true; use_metas_eagerly = false; - modulo_delta = Cpred.empty; + modulo_delta = Cpred.empty; + modulo_zeta = true; } (* Try unification with the precompiled clause, then use registered Apply *) diff --git a/tactics/class_tactics.ml4 b/tactics/class_tactics.ml4 index 685f11d47..f56089b1e 100644 --- a/tactics/class_tactics.ml4 +++ b/tactics/class_tactics.ml4 @@ -40,6 +40,19 @@ open Command open Libnames open Evd +let check_required_library d = + let d' = List.map id_of_string d in + let dir = make_dirpath (List.rev d') in + if (* not (Library.library_is_opened dir) || *)not (Library.library_is_loaded dir) then + error ("Library "^(list_last d)^" has to be required first") + +let classes_dirpath = + make_dirpath (List.map id_of_string ["Classes";"Coq"]) + +let init_setoid () = + if is_dirpath_prefix_of classes_dirpath (Lib.cwd ()) then () + else check_required_library ["Coq";"Setoids";"Setoid"] + (** Typeclasses instance search tactic / eauto *) open Auto @@ -58,6 +71,7 @@ let auto_unif_flags = ref { modulo_conv_on_closed_terms = true; use_metas_eagerly = true; modulo_delta = Cpred.empty; + modulo_zeta = true; } let unify_e_resolve (c,clenv) gls = @@ -409,6 +423,7 @@ let init () = modulo_conv_on_closed_terms = true; use_metas_eagerly = true; modulo_delta = Cpred.empty; + modulo_zeta = true; } let _ = @@ -642,6 +657,7 @@ let resolve_morphism env sigma oldt m ?(fnewt=fun x -> x) args args' cstr evars type hypinfo = { cl : clausenv; prf : constr; + car : constr; rel : constr; l2r : bool; c1 : constr; @@ -650,31 +666,44 @@ type hypinfo = { abs : (constr * types) option; } +let convertible env evd x y = + try ignore(Evarconv.the_conv_x env x y evd); true + with _ -> false + (* ignore(Reduction.conv env x y) *) + let decompose_setoid_eqhyp env sigma c left2right = let ctype = Typing.type_of env sigma c in - let eqclause = Clenv.mk_clenv_from_env env sigma None (c,ctype) in + let eqclause = Clenv.mk_clenv_from_env env sigma None (c,ctype) in let (equiv, args) = decompose_app (Clenv.clenv_type eqclause) in let rec split_last_two = function | [c1;c2] -> [],(c1, c2) | x::y::z -> let l,res = split_last_two (y::z) in x::l, res | _ -> error "The term provided is not an applied relation" in - let others, (c1,c2) = split_last_two args in - { cl=eqclause; prf=(Clenv.clenv_value eqclause); - rel=mkApp (equiv, Array.of_list others); - l2r=left2right; c1=c1; c2=c2; c=Some c; abs=None } + let others,(c1,c2) = split_last_two args in + let ty1, ty2 = + Typing.mtype_of env eqclause.evd c1, Typing.mtype_of env eqclause.evd c2 + in + if not (convertible env eqclause.evd ty1 ty2) then + error "The term does not end with an applied homogeneous relation" + else + { cl=eqclause; prf=(Clenv.clenv_value eqclause); + car=ty1; rel=mkApp (equiv, Array.of_list others); + l2r=left2right; c1=c1; c2=c2; c=Some c; abs=None } let rewrite_unif_flags = { Unification.modulo_conv_on_closed_terms = false; Unification.use_metas_eagerly = true; - Unification.modulo_delta = Cpred.empty + Unification.modulo_delta = Cpred.empty; + Unification.modulo_zeta = false; } let rewrite2_unif_flags = { Unification.modulo_conv_on_closed_terms = true; Unification.use_metas_eagerly = true; - Unification.modulo_delta = Cpred.empty - } + Unification.modulo_delta = Cpred.empty; + Unification.modulo_zeta = false; +} (* let unification_rewrite c1 c2 cl but gl = *) (* let (env',c1) = *) @@ -707,27 +736,39 @@ let refresh_hypinfo env sigma hypinfo = | _ -> () else () -let convertible env x y = - ignore(Reduction.conv env x y) - let unify_eqn env sigma hypinfo t = try - let {cl=cl; prf=prf; rel=rel; l2r=l2r; c1=c1; c2=c2; c=c; abs=abs} = !hypinfo in - let env' = + let {cl=cl; prf=prf; car=car; rel=rel; l2r=l2r; c1=c1; c2=c2; c=c; abs=abs} = !hypinfo in + let env', c1, c2, car, rel = match abs with - Some _ -> convertible env (if l2r then c1 else c2) t; cl + Some _ -> + if convertible env cl.evd (if l2r then c1 else c2) t then + cl, c1, c2, car, rel + else raise Not_found | None -> - try clenv_unify allowK ~flags:rewrite_unif_flags - CONV (if l2r then c1 else c2) t cl - with Pretype_errors.PretypeError _ -> - (* For Ring essentially, only when doing setoid_rewrite *) - clenv_unify allowK ~flags:rewrite2_unif_flags + let env' = + try clenv_unify allowK ~flags:rewrite_unif_flags CONV (if l2r then c1 else c2) t cl + with Pretype_errors.PretypeError _ -> + (* For Ring essentially, only when doing setoid_rewrite *) + clenv_unify allowK ~flags:rewrite2_unif_flags + CONV (if l2r then c1 else c2) t cl + in + let env' = + let mvs = clenv_dependent false env' in + clenv_pose_metas_as_evars env' mvs + in + let c1 = Clenv.clenv_nf_meta env' c1 + and c2 = Clenv.clenv_nf_meta env' c2 + and car = Clenv.clenv_nf_meta env' car + and rel = Clenv.clenv_nf_meta env' rel in + let ty1 = Typing.mtype_of env'.env env'.evd c1 + and ty2 = Typing.mtype_of env'.env env'.evd c2 + in + if convertible env env'.evd ty1 ty2 then + env', c1, c2, car, rel + else raise Not_found in - let c1 = Clenv.clenv_nf_meta env' c1 - and c2 = Clenv.clenv_nf_meta env' c2 - and rel = Clenv.clenv_nf_meta env' rel in - let car = Typing.type_of env'.env (Evd.evars_of env'.evd) c1 in let prf = if abs = None then (* let (rel, args) = destApp typ in *) @@ -747,7 +788,7 @@ let unify_eqn env sigma hypinfo t = in Some (env', res) with _ -> None -let unfold_impl t = +let unfold_impl t = match kind_of_term t with | App (arrow, [| a; b |])(* when eq_constr arrow (Lazy.force impl) *) -> mkProd (Anonymous, a, b) @@ -813,7 +854,7 @@ let build_new gl env sigma flags occs hypinfo concl cstr evars = let rec aux env t occ cstr = match unify_eqn env sigma hypinfo t with | Some (env', (prf, hypinfo as x)) -> - if is_occ occ then ( + if is_occ occ then ( evars := Evd.evar_merge !evars (Evd.evars_of (Evd.undefined_evars env'.evd)); match cstr with None -> Some x, succ occ @@ -971,16 +1012,19 @@ let cl_rewrite_clause_aux ?(flags=default_flags) hypinfo goal_meta occs clause g in tclTHENLIST [evartac; rewtac] gl with | TypeClassError (env, (UnsatisfiableConstraints _ as e)) -> - tclFAIL 0 (str" setoid rewrite failed: unable to satisfy the rewriting constraints." - ++ Himsg.explain_typeclass_error env e) gl - | Not_found -> - tclFAIL 0 (str" setoid rewrite failed: unable to satisfy the rewriting constraints.") gl) + tclFAIL 0 (str" setoid rewrite failed: unable to satisfy the rewriting constraints." + ++ fnl () ++ Himsg.explain_typeclass_error env e) gl) +(* | Not_found -> *) +(* tclFAIL 0 (str" setoid rewrite failed: unable to satisfy the rewriting constraints.") gl) *) | None -> let {l2r=l2r; c1=x; c2=y} = !hypinfo in - raise (Pretype_errors.PretypeError (pf_env gl, Pretype_errors.NoOccurrenceFound (if l2r then x else y))) + raise (Pretype_errors.PretypeError + (pf_env gl, + Pretype_errors.NoOccurrenceFound ((if l2r then x else y), is_hyp))) (* tclFAIL 1 (str"setoid rewrite failed") gl *) let cl_rewrite_clause c left2right occs clause gl = + init_setoid (); let meta = Evarutil.new_meta() in let hypinfo = ref (decompose_setoid_eqhyp (pf_env gl) (project gl) c left2right) in cl_rewrite_clause_aux hypinfo meta occs clause gl @@ -1114,15 +1158,6 @@ let require_library dirpath = let qualid = (dummy_loc, Libnames.qualid_of_dirpath (Libnames.dirpath_of_string dirpath)) in Library.require_library [qualid] (Some false) -let check_required_library d = - let d' = List.map id_of_string d in - let dir = make_dirpath (List.rev d') in - if (* not (Library.library_is_opened dir) || *)not (Library.library_is_loaded dir) then - error ("Library "^(list_last d)^" has to be required first") - -let init_setoid () = - check_required_library ["Coq";"Setoids";"Setoid"] - let declare_instance_refl binders a aeq n lemma = let instance = declare_instance a aeq (add_suffix n "_Reflexive") "Coq.Classes.RelationClasses.Reflexive" in anew_instance binders instance @@ -1435,7 +1470,7 @@ let check_evar_map_of_evars_defs evd = check_freemetas_is_empty rebus2 freemetas2 ) metas -let unification_rewrite l2r c1 c2 cl rel but gl = +let unification_rewrite l2r c1 c2 cl car rel but gl = let (env',c') = try (* ~flags:(false,true) to allow to mark occurrences that must not be @@ -1456,7 +1491,7 @@ let unification_rewrite l2r c1 c2 cl rel but gl = let prf = Clenv.clenv_value cl' in let prfty = Clenv.clenv_type cl' in let cl' = { cl' with templval = mk_freelisted prf ; templtyp = mk_freelisted prfty } in - {cl=cl'; prf=(mkRel 1); rel=rel; l2r=l2r; c1=c1; c2=c2; c=None; abs=Some (prf, prfty)} + {cl=cl'; prf=(mkRel 1); car=car; rel=rel; l2r=l2r; c1=c1; c2=c2; c=None; abs=Some (prf, prfty)} (* if occur_meta prf then *) (* else *) (* {cl=cl'; prf=prf; rel=rel; l2r=l2r; c1=c1; c2=c2; c=None; abs=None} *) @@ -1466,7 +1501,7 @@ let get_hyp gl c clause l2r = Prod _ -> let hi = decompose_setoid_eqhyp (pf_env gl) (project gl) c l2r in let but = match clause with Some id -> pf_get_hyp_typ gl id | None -> pf_concl gl in - unification_rewrite hi.l2r hi.c1 hi.c2 hi.cl hi.rel but gl + unification_rewrite hi.l2r hi.c1 hi.c2 hi.cl hi.car hi.rel but gl | _ -> decompose_setoid_eqhyp (pf_env gl) (project gl) c l2r let general_rewrite_flags = { under_lambdas = false; on_morphisms = false } @@ -1481,15 +1516,8 @@ let general_s_rewrite_in id l2r occs c ~new_goals gl = let hypinfo = ref (get_hyp gl c (Some id) l2r) in cl_rewrite_clause_aux ~flags:general_rewrite_flags hypinfo meta occs (Some (([],id), [])) gl -let classes_dirpath = - make_dirpath (List.map id_of_string ["Classes";"Coq"]) - -let init_rewrite () = - if is_dirpath_prefix_of classes_dirpath (Lib.cwd ()) then () - else check_required_library ["Coq";"Setoids";"Setoid"] - let general_s_rewrite_clause x = - init_rewrite (); + init_setoid (); match x with | None -> general_s_rewrite | Some id -> general_s_rewrite_in id @@ -1511,7 +1539,7 @@ let is_loaded d = Library.library_is_loaded dir let try_loaded f gl = - if is_loaded ["Coq";"Classes";"RelationClasses"] then f gl + if is_loaded ["Coq";"Classes";"RelationClasses"] then f gl else tclFAIL 0 (str"You need to require Coq.Classes.RelationClasses first") gl let setoid_reflexivity gl = diff --git a/tactics/equality.ml b/tactics/equality.ml index f91845a5c..b8e868f37 100644 --- a/tactics/equality.ml +++ b/tactics/equality.ml @@ -52,15 +52,21 @@ open Indrec *) (* Ad hoc asymmetric general_elim_clause *) -let general_elim_clause with_evars cls c elim = match cls with - | None -> - (* was tclWEAK_PROGRESS which only fails for tactics generating one - subgoal and did not fail for useless conditional rewritings generating - an extra condition *) - tclNOTSAMEGOAL (general_elim with_evars c elim ~allow_K:false) - | Some id -> - general_elim_in with_evars id c elim - +let general_elim_clause with_evars cls c elim = + try + (match cls with + | None -> + (* was tclWEAK_PROGRESS which only fails for tactics generating one + subgoal and did not fail for useless conditional rewritings generating + an extra condition *) + tclNOTSAMEGOAL (general_elim with_evars c elim ~allow_K:false) + | Some id -> + general_elim_in with_evars id c elim) + with Pretype_errors.PretypeError (env, + (Pretype_errors.NoOccurrenceFound (c', _))) -> + raise (Pretype_errors.PretypeError + (env, (Pretype_errors.NoOccurrenceFound (c', cls)))) + let elimination_sort_of_clause = function | None -> elimination_sort_of_goal | Some id -> elimination_sort_of_hyp id diff --git a/tactics/setoid_replace.ml b/tactics/setoid_replace.ml index 69840f85c..e3c4e2649 100644 --- a/tactics/setoid_replace.ml +++ b/tactics/setoid_replace.ml @@ -1734,14 +1734,16 @@ let check_evar_map_of_evars_defs evd = let rewrite_unif_flags = { modulo_conv_on_closed_terms = false; use_metas_eagerly = true; - modulo_delta = Cpred.empty + modulo_delta = Cpred.empty; + modulo_zeta = false; } let rewrite2_unif_flags = { modulo_conv_on_closed_terms = true; use_metas_eagerly = true; - modulo_delta = Cpred.empty - } + modulo_delta = Cpred.empty; + modulo_zeta = false; +} let unification_rewrite c1 c2 cl but gl = let (env',c1) = diff --git a/tactics/tactics.ml b/tactics/tactics.ml index c3f9c37e9..9eec0c064 100644 --- a/tactics/tactics.ml +++ b/tactics/tactics.ml @@ -552,6 +552,7 @@ let elim_flags = { modulo_conv_on_closed_terms = true; use_metas_eagerly = true; modulo_delta = Cpred.empty; + modulo_zeta = true; } let elimination_clause_scheme with_evars allow_K elimclause indclause gl = diff --git a/test-suite/bugs/closed/shouldsucceed/121.v b/test-suite/bugs/closed/shouldsucceed/121.v new file mode 100644 index 000000000..d193aa73f --- /dev/null +++ b/test-suite/bugs/closed/shouldsucceed/121.v @@ -0,0 +1,17 @@ +Require Import Setoid. + +Section Setoid_Bug. + +Variable X:Type -> Type. +Variable Xeq : forall A, (X A) -> (X A) -> Prop. +Hypothesis Xst : forall A, Equivalence (X A) (Xeq A). + +Variable map : forall A B, (A -> B) -> X A -> X B. + +Implicit Arguments map [A B]. + +Goal forall A B (a b:X (B -> A)) (c:X A) (f:A -> B -> A), Xeq _ a b -> Xeq _ b (map f c) -> Xeq _ a (map f c). +intros A B a b c f Hab Hbc. +rewrite Hab. +assumption. +Qed. diff --git a/test-suite/bugs/closed/shouldsucceed/1425.v b/test-suite/bugs/closed/shouldsucceed/1425.v new file mode 100644 index 000000000..f5fbb8a2a --- /dev/null +++ b/test-suite/bugs/closed/shouldsucceed/1425.v @@ -0,0 +1,13 @@ +Require Import Setoid. + +Parameter recursion : forall A : Set, A -> (nat -> A -> A) -> nat -> A. + +Axiom recursion_S : + forall (A : Set) (EA : relation A) (a : A) (f : nat -> A -> A) (n : nat), + EA (recursion A a f (S n)) (f n (recursion A a f n)). + +Goal forall n : nat, recursion nat 0 (fun _ _ => 1) (S n) = 1. +intro n. +setoid_rewrite recursion_S. +reflexivity. +Qed.
\ No newline at end of file diff --git a/test-suite/bugs/closed/shouldsucceed/1604.v b/test-suite/bugs/closed/shouldsucceed/1604.v new file mode 100644 index 000000000..2d0991cb1 --- /dev/null +++ b/test-suite/bugs/closed/shouldsucceed/1604.v @@ -0,0 +1,7 @@ +Require Import Setoid. + +Parameter F : nat -> nat. +Axiom F_id : forall n : nat, n = F n. +Goal forall n : nat, F n = n. +intro n. setoid_rewrite F_id at 2. reflexivity. +Qed. diff --git a/test-suite/bugs/closed/shouldsucceed/1683.v b/test-suite/bugs/closed/shouldsucceed/1683.v new file mode 100644 index 000000000..1571ee20e --- /dev/null +++ b/test-suite/bugs/closed/shouldsucceed/1683.v @@ -0,0 +1,42 @@ +Require Import Setoid. + +Section SetoidBug. + +Variable ms : Type. +Variable ms_type : ms -> Type. +Variable ms_eq : forall (A:ms), relation (ms_type A). + +Variable CR : ms. + +Record Ring : Type := +{Ring_type : Type}. + +Variable foo : forall (A:Ring), nat -> Ring_type A. +Variable IR : Ring. +Variable IRasCR : Ring_type IR -> ms_type CR. + +Definition CRasCRing : Ring := Build_Ring (ms_type CR). + +Hypothesis ms_refl : forall A x, ms_eq A x x. +Hypothesis ms_sym : forall A x y, ms_eq A x y -> ms_eq A y x. +Hypothesis ms_trans : forall A x y z, ms_eq A x y -> ms_eq A y z -> ms_eq A x z. + +Add Parametric Relation A : (ms_type A) (ms_eq A) + reflexivity proved by (ms_refl A) + symmetry proved by (ms_sym A) + transitivity proved by (ms_trans A) + as ms_Setoid. + +Hypothesis foobar : forall n, ms_eq CR (IRasCR (foo IR n)) (foo CRasCRing n). + +Goal forall (b:ms_type CR), + ms_eq CR (IRasCR (foo IR O)) b -> + ms_eq CR (IRasCR (foo IR O)) b. +intros b H. +rewrite foobar. +rewrite foobar in H. +assumption. +Qed. + + + diff --git a/test-suite/bugs/closed/shouldsucceed/1696.v b/test-suite/bugs/closed/shouldsucceed/1696.v new file mode 100644 index 000000000..0826428a3 --- /dev/null +++ b/test-suite/bugs/closed/shouldsucceed/1696.v @@ -0,0 +1,16 @@ +Require Import Setoid. + +Inductive mynat := z : mynat | s : mynat -> mynat. + +Parameter E : mynat -> mynat -> Prop. +Axiom E_equiv : equiv mynat E. + +Add Relation mynat E + reflexivity proved by (proj1 E_equiv) + symmetry proved by (proj2 (proj2 E_equiv)) + transitivity proved by (proj1 (proj2 E_equiv)) +as E_rel. + +Notation "x == y" := (E x y) (at level 70). + +Goal z == s z -> s z == z. intros H. setoid_rewrite H at 2. reflexivity. Qed. diff --git a/test-suite/bugs/closed/shouldsucceed/1738.v b/test-suite/bugs/closed/shouldsucceed/1738.v new file mode 100644 index 000000000..0deed3663 --- /dev/null +++ b/test-suite/bugs/closed/shouldsucceed/1738.v @@ -0,0 +1,30 @@ +Require Import FSets. + +Module SomeSetoids (Import M:FSetInterface.S). + +Lemma Equal_refl : forall s, s[=]s. +Proof. red; split; auto. Qed. + +Add Relation t Equal + reflexivity proved by Equal_refl + symmetry proved by eq_sym + transitivity proved by eq_trans + as EqualSetoid. + +Add Morphism Empty with signature Equal ==> iff as Empty_m. +Proof. +unfold Equal, Empty; firstorder. +Qed. + +End SomeSetoids. + +Module Test (Import M:FSetInterface.S). + Module A:=SomeSetoids M. + Module B:=SomeSetoids M. (* lots of warning *) + + Lemma Test : forall s s', s[=]s' -> Empty s -> Empty s'. + intros. + rewrite H in H0. + assumption. +Qed. +End Test.
\ No newline at end of file diff --git a/test-suite/bugs/opened/shouldnotfail/1596.v b/test-suite/bugs/opened/shouldnotfail/1596.v new file mode 100644 index 000000000..766bf524c --- /dev/null +++ b/test-suite/bugs/opened/shouldnotfail/1596.v @@ -0,0 +1,242 @@ + +Require Import Relations. +Require Import FSets. +Require Import Arith. + +Lemma Bool_elim_bool : forall (b:bool),b=true \/ b=false. + destruct b;try tauto. +Qed. + +Module OrderedPair (X:OrderedType) (Y:OrderedType) <: OrderedType with +Definition t := (X.t * Y.t)%type. + Definition t := (X.t * Y.t)%type. + + Definition eq (xy1:t) (xy2:t) := + let (x1,y1) := xy1 in + let (x2,y2) := xy2 in + (X.eq x1 x2) /\ (Y.eq y1 y2). + + Definition lt (xy1:t) (xy2:t) := + let (x1,y1) := xy1 in + let (x2,y2) := xy2 in + (X.lt x1 x2) \/ ((X.eq x1 x2) /\ (Y.lt y1 y2)). + + Lemma eq_refl : forall (x:t),(eq x x). + destruct x. + unfold eq. + split;[apply X.eq_refl | apply Y.eq_refl]. + Qed. + + Lemma eq_sym : forall (x y:t),(eq x y)->(eq y x). + destruct x;destruct y;unfold eq;intro. + elim H;clear H;intros. + split;[apply X.eq_sym | apply Y.eq_sym];trivial. + Qed. + + Lemma eq_trans : forall (x y z:t),(eq x y)->(eq y z)->(eq x z). + unfold eq;destruct x;destruct y;destruct z;intros. + elim H;clear H;intros. + elim H0;clear H0;intros. + split;[eapply X.eq_trans | eapply Y.eq_trans];eauto. + Qed. + + Lemma lt_trans : forall (x y z:t),(lt x y)->(lt y z)->(lt x z). + unfold lt;destruct x;destruct y;destruct z;intros. + case H;clear H;intro. + case H0;clear H0;intro. + left. + eapply X.lt_trans;eauto. + elim H0;clear H0;intros. + left. + case (X.compare t0 t4);trivial;intros. + generalize (X.eq_sym H0);intro. + generalize (X.eq_trans e H2);intro. + elim (X.lt_not_eq H H3). + generalize (X.lt_trans l H);intro. + generalize (X.eq_sym H0);intro. + elim (X.lt_not_eq H2 H3). + elim H;clear H;intros. + case H0;clear H0;intro. + left. + case (X.compare t0 t4);trivial;intros. + generalize (X.eq_sym H);intro. + generalize (X.eq_trans H2 e);intro. + elim (X.lt_not_eq H0 H3). + generalize (X.lt_trans H0 l);intro. + generalize (X.eq_sym H);intro. + elim (X.lt_not_eq H2 H3). + elim H0;clear H0;intros. + right. + split. + eauto. + eauto. + Qed. + + Lemma lt_not_eq : forall (x y:t),(lt x y)->~(eq x y). + unfold lt, eq;destruct x;destruct y;intro;intro. + elim H0;clear H0;intros. + case H. + intro. + apply (X.lt_not_eq H2 H0). + intro. + elim H2;clear H2;intros. + apply (Y.lt_not_eq H3 H1). + Qed. + + Definition compare : forall (x y:t),(Compare lt eq x y). + destruct x;destruct y. + case (X.compare t0 t2);intro. + apply LT. + left;trivial. + case (Y.compare t1 t3);intro. + apply LT. + right. + tauto. + apply EQ. + split;trivial. + apply GT. + right;auto. + apply GT. + left;trivial. + Defined. + + Hint Immediate eq_sym. + Hint Resolve eq_refl eq_trans lt_not_eq lt_trans. +End OrderedPair. + +Module MessageSpi. + Inductive message : Set := + | MNam : nat -> message. + + Definition t := message. + + Fixpoint message_lt (m n:message) {struct m} : Prop := + match (m,n) with + | (MNam n1,MNam n2) => n1 < n2 + end. + + Module Ord <: OrderedType with Definition t := message with Definition eq := +@eq message. + Definition t := message. + Definition eq := @eq message. + Definition lt := message_lt. + + Lemma eq_refl : forall (x:t),eq x x. + unfold eq;auto. + Qed. + + Lemma eq_sym : forall (x y:t),(eq x y )->(eq y x). + unfold eq;auto. + Qed. + + Lemma eq_trans : forall (x y z:t),(eq x y)->(eq y z)->(eq x z). + unfold eq;auto;intros;congruence. + Qed. + + Lemma lt_trans : forall (x y z:t),(lt x y)->(lt y z)->(lt x z). + unfold lt. + induction x;destruct y;simpl;try tauto;destruct z;try tauto;intros. + omega. + Qed. + + Lemma lt_not_eq : forall (x y:t),(lt x y)->~(eq x y). + unfold eq;unfold lt. + induction x;destruct y;simpl;try tauto;intro;red;intro;try (discriminate +H0);injection H0;intros. + elim (lt_irrefl n);try omega. + Qed. + + Definition compare : forall (x y:t),(Compare lt eq x y). + unfold lt, eq. + induction x;destruct y;intros;try (apply LT;simpl;trivial;fail);try +(apply +GT;simpl;trivial;fail). + case (lt_eq_lt_dec n n0);intros;try (case s;clear s;intros). + apply LT;trivial. + apply EQ;trivial. + rewrite e;trivial. + apply GT;trivial. + Defined. + + Hint Immediate eq_sym. + Hint Resolve eq_refl eq_trans lt_not_eq lt_trans. + End Ord. + + Theorem eq_dec : forall (m n:message),{m=n}+{~(m=n)}. + intros. + case (Ord.compare m n);intro;[right | left | right];try (red;intro). + elim (Ord.lt_not_eq m n);auto. + rewrite e;auto. + elim (Ord.lt_not_eq n m);auto. + Defined. +End MessageSpi. + +Module MessagePair := OrderedPair MessageSpi.Ord MessageSpi.Ord. + +Module Type Hedge := FSetInterface.S with Module E := MessagePair. + +Module A (H:Hedge). + Definition hedge := H.t. + + Definition message_relation := relation MessageSpi.message. + + Definition relation_of_hedge (h:hedge) (m n:MessageSpi.message) := H.In (m,n) +h. + + Inductive hedge_synthesis_relation (h:message_relation) : message_relation := + | SynInc : forall (m n:MessageSpi.message),(h m +n)->(hedge_synthesis_relation h m n). + + Fixpoint hedge_in_synthesis (h:hedge) (m:MessageSpi.message) +(n:MessageSpi.message) {struct m} : bool := + if H.mem (m,n) h + then true + else false. + + Definition hedge_synthesis_spec (h:hedge) := hedge_synthesis_relation +(relation_of_hedge h). + + Lemma hedge_in_synthesis_impl_hedge_synthesis_spec : forall (h:hedge),forall +(m n:MessageSpi.message),(hedge_in_synthesis h m n)=true->(hedge_synthesis_spec +h m n). + unfold hedge_synthesis_spec;unfold relation_of_hedge. + induction m;simpl;intro. + elim (Bool_elim_bool (H.mem (MessageSpi.MNam n,n0) h));intros. + apply SynInc;apply H.mem_2;trivial. + rewrite H in H0. (* !! possible here !! *) + discriminate H0. + Qed. +End A. + +Module B (H:Hedge). + Definition hedge := H.t. + + Definition message_relation := relation MessageSpi.t. + + Definition relation_of_hedge (h:hedge) (m n:MessageSpi.t) := H.In (m,n) h. + + Inductive hedge_synthesis_relation (h:message_relation) : message_relation := + | SynInc : forall (m n:MessageSpi.t),(h m n)->(hedge_synthesis_relation h m +n). + + Fixpoint hedge_in_synthesis (h:hedge) (m:MessageSpi.t) (n:MessageSpi.t) +{struct m} : bool := + if H.mem (m,n) h + then true + else false. + + Definition hedge_synthesis_spec (h:hedge) := hedge_synthesis_relation +(relation_of_hedge h). + + Lemma hedge_in_synthesis_impl_hedge_synthesis_spec : forall (h:hedge),forall +(m n:MessageSpi.t),(hedge_in_synthesis h m n)=true->(hedge_synthesis_spec h m +n). + unfold hedge_synthesis_spec;unfold relation_of_hedge. + induction m;simpl;intro. + elim (Bool_elim_bool (H.mem (MessageSpi.MNam n,n0) h));intros. + apply SynInc;apply H.mem_2;trivial. + + rewrite H in H0. (* !! impossible here !! *) + discriminate H0. + Qed. +End B.
\ No newline at end of file diff --git a/test-suite/bugs/opened/shouldnotfail/1811.v b/test-suite/bugs/opened/shouldnotfail/1811.v new file mode 100644 index 000000000..037b7cb2d --- /dev/null +++ b/test-suite/bugs/opened/shouldnotfail/1811.v @@ -0,0 +1,9 @@ +Require Export Bool. + +Lemma neg2xor : forall b, xorb true b = negb b. +Proof. auto. Qed. + +Goal forall b1 b2, (negb b1 = b2) -> xorb true b1 = b2. +Proof. + intros b1 b2. + rewrite neg2xor.
\ No newline at end of file diff --git a/theories/Classes/Morphisms.v b/theories/Classes/Morphisms.v index e2d3f21c7..295d7d1a6 100644 --- a/theories/Classes/Morphisms.v +++ b/theories/Classes/Morphisms.v @@ -50,13 +50,13 @@ Definition respectful (A B : Type) (R : relation A) (R' : relation B) : relation Delimit Scope signature_scope with signature. Notation " R ++> R' " := (@respectful _ _ (R%signature) (R'%signature)) - (right associativity, at level 55) : signature_scope. + (right associativity, at level 90) : signature_scope. Notation " R ==> R' " := (@respectful _ _ (R%signature) (R'%signature)) - (right associativity, at level 55) : signature_scope. + (right associativity, at level 90) : signature_scope. Notation " R --> R' " := (@respectful _ _ (inverse (R%signature)) (R'%signature)) - (right associativity, at level 55) : signature_scope. + (right associativity, at level 90) : signature_scope. Arguments Scope respectful [type_scope type_scope signature_scope signature_scope]. diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml index 505f456db..4950f4064 100644 --- a/toplevel/himsg.ml +++ b/toplevel/himsg.ml @@ -406,9 +406,12 @@ let explain_refiner_cannot_generalize env ty = str "Cannot find a well-typed generalisation of the goal with type : " ++ pr_lconstr_env env ty -let explain_no_occurrence_found env c = +let explain_no_occurrence_found env c id = str "Found no subterm matching " ++ pr_lconstr_env env c ++ - str " in the current goal" + str " in " ++ + (match id with + | Some id -> pr_id id + | None -> str"the current goal") let explain_cannot_unify_binding_type env m n = let pm = pr_lconstr_env env m in @@ -465,7 +468,7 @@ let explain_pretype_error env err = | CannotUnify (m,n) -> explain_cannot_unify env m n | CannotUnifyLocal (m,n,sn) -> explain_cannot_unify_local env m n sn | CannotGeneralize ty -> explain_refiner_cannot_generalize env ty - | NoOccurrenceFound c -> explain_no_occurrence_found env c + | NoOccurrenceFound (c, id) -> explain_no_occurrence_found env c id | CannotUnifyBindingType (m,n) -> explain_cannot_unify_binding_type env m n |