diff options
| author | Erik Martin-Dorel | 2019-04-26 13:00:38 +0200 |
|---|---|---|
| committer | Erik Martin-Dorel | 2019-08-06 15:30:35 +0200 |
| commit | 75f93e90e95f049ae23023f39add16a861ae114b (patch) | |
| tree | 57980dc1d2c96b7770eb2118a438cca43e428d4d /plugins | |
| parent | 4e285a5d21633ecc47543c543043c31cd3be0a18 (diff) | |
[ssr] under: extend ssreflect.v to generalize iff to any setoid eq
* Add an extra test with an Equivalence.
* Update the doc accordingly.
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/ssr/ssreflect.v | 93 | ||||
| -rw-r--r-- | plugins/ssr/ssrfwd.ml | 30 |
2 files changed, 74 insertions, 49 deletions
diff --git a/plugins/ssr/ssreflect.v b/plugins/ssr/ssreflect.v index 71abafc22f..bd95feacd8 100644 --- a/plugins/ssr/ssreflect.v +++ b/plugins/ssr/ssreflect.v @@ -531,7 +531,7 @@ Lemma abstract_context T (P : T -> Type) x : Proof. by move=> /(_ P); apply. Qed. (*****************************************************************************) -(* Constants for under, to rewrite under binders using "Leibniz eta lemmas". *) +(* Constants for under/over, to rewrite under binders using "context lemmas" *) Module Type UNDER_EQ. Parameter Under_eq : @@ -576,54 +576,69 @@ Lemma under_eq_done : Proof. by []. Qed. End Under_eq. -Register Under_eq as plugins.ssreflect.Under_eq. -Register Under_eq_from_eq as plugins.ssreflect.Under_eq_from_eq. - -Module Type UNDER_IFF. -Parameter Under_iff : Prop -> Prop -> Prop. -Parameter Under_iff_from_iff : forall x y : Prop, @Under_iff x y -> x <-> y. - -(** [Over_iff, over_iff, over_iff_done]: for "by rewrite over_iff" *) -Parameter Over_iff : Prop -> Prop -> Prop. -Parameter over_iff : - forall (x : Prop) (y : Prop), @Under_iff x y = @Over_iff x y. -Parameter over_iff_done : - forall (x : Prop), @Over_iff x x. -Hint Extern 0 (@Over_iff _ _) => solve [ apply over_iff_done ] : core. -Hint Resolve over_iff_done : core. - -(** [under_iff_done]: for Ltac-style over *) -Parameter under_iff_done : - forall (x : Prop), @Under_iff x x. -Notation "''Under[' x ]" := (@Under_iff x _) +Register Under_eq.Under_eq as plugins.ssreflect.Under_eq. +Register Under_eq.Under_eq_from_eq as plugins.ssreflect.Under_eq_from_eq. + +Require Import Coq.Relations.Relation_Definitions. +Require Import RelationClasses. + +Module Type UNDER_REL. +Parameter Under_rel : + forall (A : Type) (eqA : relation A), Reflexive eqA -> relation A. +Parameter Under_rel_from_rel : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x y : A), + @Under_rel A eqA EeqA x y -> eqA x y. + +(** [Over_rel, over_rel, over_rel_done]: for "by rewrite over_rel" *) +Parameter Over_rel : + forall (A : Type) (eqA : relation A), Reflexive eqA -> relation A. +Parameter over_rel : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x y : A), + @Under_rel A eqA EeqA x y = @Over_rel A eqA EeqA x y. +Parameter over_rel_done : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x : A), + @Over_rel A eqA EeqA x x. +Hint Extern 0 (@Over_rel _ _ _ _ _) => solve [ apply over_rel_done ] : core. +Hint Resolve over_rel_done : core. + +(** [under_rel_done]: for Ltac-style over *) +Parameter under_rel_done : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x : A), + @Under_rel A eqA EeqA x x. +Notation "''Under[' x ]" := (@Under_rel _ _ _ x _) (at level 8, format "''Under[' x ]", only printing). -End UNDER_IFF. - -Module Export Under_iff : UNDER_IFF. -Definition Under_iff := iff. -Lemma Under_iff_from_iff (x y : Prop) : - @Under_iff x y -> x <-> y. +End UNDER_REL. + +Module Export Under_rel : UNDER_REL. +Definition Under_rel (A : Type) (eqA : relation A) (_ : Reflexive eqA) := + eqA. +Lemma Under_rel_from_rel : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x y : A), + @Under_rel A eqA EeqA x y -> eqA x y. Proof. by []. Qed. -Definition Over_iff := Under_iff. -Lemma over_iff : - forall (x : Prop) (y : Prop), @Under_iff x y = @Over_iff x y. +Definition Over_rel := Under_rel. +Lemma over_rel : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x y : A), + @Under_rel A eqA EeqA x y = @Over_rel A eqA EeqA x y. Proof. by []. Qed. -Lemma over_iff_done : - forall (x : Prop), @Over_iff x x. +Lemma over_rel_done : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x : A), + @Over_rel A eqA EeqA x x. Proof. by []. Qed. -Lemma under_iff_done : - forall (x : Prop), @Under_iff x x. +Lemma under_rel_done : + forall (A : Type) (eqA : relation A) (EeqA : Reflexive eqA) (x : A), + @Under_rel A eqA EeqA x x. Proof. by []. Qed. -End Under_iff. +End Under_rel. -Register Under_iff as plugins.ssreflect.Under_iff. -Register Under_iff_from_iff as plugins.ssreflect.Under_iff_from_iff. +Register Under_rel.Under_rel as plugins.ssreflect.Under_rel. +Register Under_rel.Under_rel_from_rel as plugins.ssreflect.Under_rel_from_rel. -Definition over := (over_eq, over_iff). +Definition over := (over_eq, over_rel). Ltac over := by [ apply: Under_eq.under_eq_done - | apply: Under_iff.under_iff_done + | apply: Under_rel.under_rel_done | rewrite over ]. diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml index cca94c8c9b..f67051eeb7 100644 --- a/plugins/ssr/ssrfwd.ml +++ b/plugins/ssr/ssrfwd.ml @@ -10,6 +10,7 @@ (* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *) +open Ltac_plugin open Pp open Names open Constr @@ -349,16 +350,25 @@ let intro_lock ipats = let env = Proofview.Goal.env gl in match EConstr.kind_of_type sigma c with | Term.AtomicType(hd, args) when - Ssrcommon.is_const_ref sigma hd (Coqlib.lib_ref "core.iff.type") && - Array.length args = 2 && is_app_evar sigma args.(1) -> - Tactics.New.refine ~typecheck:true (fun sigma -> - let sigma, under_iff = - Ssrcommon.mkSsrConst "Under_iff" env sigma in - let sigma, under_from_iff = - Ssrcommon.mkSsrConst "Under_iff_from_iff" env sigma in - let ty = EConstr.mkApp (under_iff,args) in - let sigma, t = Evarutil.new_evar env sigma ty in - sigma, EConstr.mkApp(under_from_iff,Array.append args [|t|])) + Array.length args >= 2 && is_app_evar sigma (Array.last args) && + Ssrequality.ssr_is_setoid env sigma hd args -> + Tactics.New.refine ~typecheck:true (fun sigma -> + let lm2 = Array.length args - 2 in + let sigma, carrier = + Typing.type_of env sigma args.(lm2) in + let rel = EConstr.mkApp (hd, Array.sub args 0 lm2) in + let rel_args = Array.sub args lm2 2 in + let sigma, refl = + (* could raise Not_found in theory *) + Rewrite.get_reflexive_proof env sigma carrier rel in + let sigma, under_rel = + Ssrcommon.mkSsrConst "Under_rel" env sigma in + let sigma, under_from_rel = + Ssrcommon.mkSsrConst "Under_rel_from_rel" env sigma in + let under_rel_args = Array.append [|carrier; rel; refl|] rel_args in + let ty = EConstr.mkApp (under_rel, under_rel_args) in + let sigma, t = Evarutil.new_evar env sigma ty in + sigma, EConstr.mkApp(under_from_rel,Array.append under_rel_args [|t|])) | _ -> let t = Reductionops.whd_all env sigma c in match EConstr.kind_of_type sigma t with |
