aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorErik Martin-Dorel2019-04-26 13:00:38 +0200
committerErik Martin-Dorel2019-08-06 15:30:35 +0200
commit75f93e90e95f049ae23023f39add16a861ae114b (patch)
tree57980dc1d2c96b7770eb2118a438cca43e428d4d /plugins
parent4e285a5d21633ecc47543c543043c31cd3be0a18 (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.v93
-rw-r--r--plugins/ssr/ssrfwd.ml30
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