Skip to content

Commit d64301b

Browse files
committed
custom eliminator for reflect
1 parent 4de6881 commit d64301b

File tree

4 files changed

+83
-30
lines changed

4 files changed

+83
-30
lines changed

theories/Corelib/Classes/Morphisms.v

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,25 @@ Ltac f_equiv :=
224224
| _ => idtac
225225
end.
226226

227+
Global Instance forget_proper {T U : Type} {R : relation T} {S : relation U}
228+
(y : U) `{Proper _ S y} : Proper (R ==> S) (fun x => y).
229+
Proof. firstorder. Qed.
230+
231+
Global Instance trans_proper {T U V : Type}
232+
{RT : relation T} {RU : relation U} {RV : relation V}
233+
(F : U -> V) (G : T -> U)
234+
`{Proper _ (RU ==> RV) F} `{Proper _ (RT ==> RU) G} :
235+
Proper (RT ==> RV) (fun x => F (G x)).
236+
Proof. firstorder. Qed.
237+
238+
Global Instance trans2_proper {T U1 U2 V : Type}
239+
{RT : relation T} {RU1 : relation U1} {RU2 : relation U2} {RV : relation V}
240+
(F : U1 -> U2 -> V) (G1 : T -> U1) (G2 : T -> U2)
241+
`{Proper _ (RU1 ==> RU2 ==> RV) F}
242+
`{Proper _ (RT ==> RU1) G1} `{Proper _ (RT ==> RU2) G2} :
243+
Proper (RT ==> RV) (fun x => F (G1 x) (G2 x)).
244+
Proof. intros x y xy; apply H; [apply H0|apply H1]; exact xy. Qed.
245+
227246
Section Relations.
228247
Let U := Type.
229248
Context {A B : U} (P : A -> U).
@@ -247,6 +266,9 @@ Section Relations.
247266
Global Instance subrelation_id_proper `(subrelation A RA RA') : Proper (RA ==> RA') id.
248267
Proof. firstorder. Qed.
249268

269+
Global Instance subrelation_id_proper' `(subrelation A RA RA') : Proper (RA ==> RA') (fun x => x).
270+
Proof. firstorder. Qed.
271+
250272
(** The subrelation property goes through products as usual. *)
251273

252274
Lemma subrelation_respectful `(subl : subrelation A RA' RA, subr : subrelation B RB RB') :
@@ -805,3 +827,9 @@ Register RewriteRelation as rewrite.prop.RewriteRelation.
805827
Register Proper as rewrite.prop.Proper.
806828
Register proper_prf as rewrite.prop.proper_prf.
807829
Register ProperProxy as rewrite.prop.ProperProxy.
830+
831+
#[global]
832+
Instance Proper_ReflectRw (P : Prop -> Prop) : Proper (iff ==> iff) P -> Datatypes.ReflectRw P.
833+
Proof.
834+
intros PP A B AB; rewrite AB; apply iff_refl.
835+
Qed.

theories/Corelib/Classes/Morphisms_Prop.v

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ Program Instance or_iff_morphism :
5757
#[global]
5858
Program Instance iff_iff_iff_impl_morphism : Proper (iff ==> iff ==> iff) impl.
5959

60+
#[global]
61+
Instance iff_iff_morphism :
62+
Morphisms.Proper (Morphisms.respectful iff (Morphisms.respectful iff iff)) iff.
63+
Proof.
64+
intros Pl Pr [Plr Prl] Ql Qr [Qlr Qrl]; split; intros [PQ QP]; split; auto.
65+
Qed.
66+
67+
#[global]
68+
Instance impl_iff_morphism {T : Type} {RT : Relation_Definitions.relation T}
69+
(F1 : T -> Prop) (F2 : T -> Prop)
70+
`{Proper _ (RT ==> iff) F1} `{Proper _ (RT ==> iff) F2} :
71+
Proper (RT ==> iff) (fun x => F1 x -> F2 x).
72+
Proof. intros x y xy; generalize (H _ _ xy) (H0 _ _ xy); firstorder. Qed.
73+
6074
(** Morphisms for quantifiers *)
6175

6276
#[global]

theories/Corelib/Init/Datatypes.v

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,30 @@ Register false as core.bool.false.
5656
as popularized by the Ssreflect library. *)
5757
(************************************************)
5858

59-
Inductive reflect (P : Prop) : bool -> Set :=
59+
Variant reflect (P : Prop) : bool -> Set :=
6060
| ReflectT : P -> reflect P true
6161
| ReflectF : ~ P -> reflect P false.
6262

63+
(* A specialized copy of Proper because the latter does not yet exist. *)
64+
Definition ReflectRw (P : Prop -> Prop) := forall (A B : Prop), A <-> B -> P A <-> P B.
65+
Existing Class ReflectRw.
66+
67+
Definition reflect_ind (P : Prop)
68+
(Q : forall (b : bool), Prop -> reflect P b -> Prop)
69+
(ReflectT : forall p : P, Q true True (ReflectT p))
70+
(ReflectF : forall p : ~ P, Q false False (ReflectF p))
71+
(QRw : forall b p, ReflectRw (fun P => Q b P p))
72+
(b : bool) (p : reflect P b)
73+
:=
74+
match
75+
p as p0 in reflect _ b0 return Q b0 P p0
76+
with
77+
| Datatypes.ReflectT p0 => (proj2 (QRw _ _ _ _ (conj (fun _ => I) (fun _ => p0)))) (ReflectT p0)
78+
| Datatypes.ReflectF p0 => (proj2 (QRw _ _ _ _ (conj (fun p1 => p0 p1) (fun f => False_ind _ f)))) (ReflectF p0)
79+
end.
80+
81+
Register Scheme reflect_ind as ind_dep for reflect.
82+
6383
#[global]
6484
Create HintDb bool.
6585

theories/Corelib/ssr/ssrbool.v

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
(** #<style> .doc { font-family: monospace; white-space: pre; } </style># **)
1414

15-
Require Import Setoid.
15+
Require Import Setoid Morphisms.
1616
Require Import ssreflect ssrfun.
1717

1818
(**
@@ -1272,8 +1272,7 @@ Proof. by split=> // -[]. Qed.
12721272

12731273
Lemma reflectP (P Q : decProp) : (P <-> Q) <-> (? P = ? Q).
12741274
Proof.
1275-
by case: (propbP P) => [/iffT|/iffF] ->;
1276-
case: (propbP Q) => [/iffT|/iffF] -> //; split=> // -[]//.
1275+
by elim: (propbP P) => _; elim: (propbP Q) => _ //; split=> // -[].
12771276
Qed.
12781277

12791278
Lemma propbE (P Q : decProp) {RP RQ : Prop} `{@Unfold_prop Prop (prop P) RP} `{@Unfold_prop Prop (prop Q) RQ} : (P <-> Q) -> (? (reverse_coercion P RP) = ? (reverse_coercion Q RQ)).
@@ -1354,7 +1353,7 @@ Lemma andNp P : ~ (~ P /\ P).
13541353
Proof. by move=> [] /[apply]. Qed.
13551354

13561355
Lemma orpN (P : decProp) : P \/ ~ P.
1357-
Proof. by case: (propbP P) => p; [left|right]. Qed.
1356+
Proof. by elim: (propbP P) => _; [left|right]. Qed.
13581357

13591358
Lemma orNp (P : decProp) : ~ P \/ P.
13601359
Proof. by rewrite orpC (iffT (orpN _)). Qed.
@@ -1389,18 +1388,15 @@ Lemma orp_idl P Q : (Q -> P) -> P \/ Q <-> P.
13891388
Proof. by move=> QP; split=> [[|/QP]//|]?; left. Qed.
13901389
Lemma orp_idr P Q : (P -> Q) -> P \/ Q <-> Q.
13911390
Proof. by rewrite orpC (iffT (@orp_idl _ _)). Qed.
1391+
13921392
Lemma orp_id2l (P : decProp) Q R :
13931393
(~ P -> Q <-> R) -> P \/ Q <-> P \/ R.
1394-
Proof. by move=> PQR; case: (propbP P) => [|/PQR -> //]; split; left. Qed.
1394+
Proof. by elim: (propbP P) => [_ _|_ /(_ id) -> //]; split; left. Qed.
13951395
Lemma orp_id2r P (Q : decProp) R : (~ Q -> P <-> R) -> P \/ Q <-> R \/ Q.
13961396
Proof. by rewrite ![_ \/ Q]orpC (iffT (@orp_id2l _ _ _)). Qed.
13971397

13981398
Lemma negp_and (P Q : decProp) : ~ (P /\ Q) <-> ~ P \/ ~ Q.
1399-
Proof.
1400-
by case: (propbP P) => [/iffT|/iffF] ->;
1401-
case: (propbP Q) => [/iffT|/iffF] ->;
1402-
apply/propbP.
1403-
Qed.
1399+
Proof. by elim: (propbP P) => _; elim: (propbP Q) => _; apply/propbP. Qed.
14041400

14051401
Lemma negp_or P Q : ~ (P \/ Q) <-> (~ P) /\ ~ Q.
14061402
Proof. by split=> [pq|[]p q [/p|/q]//]; split=> ?; apply: pq; [left|right]. Qed.
@@ -1425,7 +1421,7 @@ Lemma implypp P : P -> P. Proof. by []. Qed.
14251421
Lemma negp_imply (P : decProp) Q : ~ (P -> Q) <-> P /\ ~ Q.
14261422
Proof.
14271423
split=> [|[]p q /(_ p)/q//] pq; split=> [|q]; last exact: pq.
1428-
by case: (propbP P) => // p; elim: pq => /p.
1424+
by elim: (propbP P) pq => _ //; apply.
14291425
Qed.
14301426

14311427
Lemma implypE (P : decProp) Q : (P -> Q) <-> ~ P \/ Q.
@@ -1445,20 +1441,18 @@ Proof. by rewrite /iff !implypNN ![(Q -> _) /\ _]andpC. Qed.
14451441

14461442
Lemma implyp_idl (P : decProp) Q : (~ P -> Q) -> (P -> Q) <-> Q.
14471443
Proof. by move=> npq; split=> // pq; case: (propbP P) => [/pq|/npq]. Qed.
1448-
Lemma implyp_idr (P : decProp) Q : (Q -> ~ P) -> (P -> Q) <-> ~ P.
1444+
Lemma implyp_idr P Q : (Q -> ~ P) -> (P -> Q) <-> ~ P.
14491445
Proof.
1450-
by move=> qnp; split=> [pq|/[apply]//]; case: (propbP P) => [/pq/qnp|].
1446+
by move=> qnp; split=> [pq p|/[apply]//]; apply: qnp => //; apply: pq.
14511447
Qed.
14521448
Lemma implyp_id2l T P Q : (forall x : T, P x <-> Q x) -> (forall x, P x) <-> (forall x, Q x).
14531449
Proof.
14541450
move=> xqr; split=> + x.
1455-
(* FIXME: This looks like a bug either in setoid_rewrite or in ssrmatching. *)
14561451
by rewrite -(xqr x); apply.
14571452
by rewrite (xqr x); apply.
14581453
Qed.
14591454

1460-
Definition xor (P Q : Prop) :=
1461-
(P \/ Q) /\ ~ (P /\ Q).
1455+
Definition xor (P Q : Prop) := (P \/ Q) /\ ~ (P /\ Q).
14621456

14631457
Instance xor_iff_morphism : Morphisms.Proper (iff ==> iff ==> iff) xor.
14641458
Proof. by move=> P Q PQ R S RS; rewrite /xor PQ RS. Qed.
@@ -1478,13 +1472,13 @@ Proof. by rewrite /xor (iffT (orTp _)) !andTp. Qed.
14781472
Lemma xorpT P : xor P True <-> ~ P.
14791473
Proof. by rewrite xorpC xorTp. Qed.
14801474

1475+
Lemma xorpp P : ~ (xor P P).
1476+
Proof. by move=> [] /orpp p; rewrite andpp; apply. Qed.
1477+
14811478
Lemma xorP (P Q : decProp) : reflect (xor P Q) (addb P Q).
14821479
Proof.
1483-
case: (propbP P) => [/iffT|/iffF] p.
1484-
apply: (@equivP (~ Q)); first exact: negPP.
1485-
by rewrite p xorTp.
1486-
apply: (@equivP Q); first exact: propbP.
1487-
by rewrite p xorFp.
1480+
by apply: (iffP idP); elim: (propbP P); elim: (propbP Q) => //= _ _;
1481+
rewrite ?(iffF (@xorpp _))// ?xorTp ?xorpT => _.
14881482
Qed.
14891483

14901484
Canonical xor_decProp (P Q : decProp) := {|
@@ -1493,23 +1487,20 @@ Canonical xor_decProp (P Q : decProp) := {|
14931487
propbP := xorP P Q
14941488
|}.
14951489

1496-
Lemma xorpp P : ~ (xor P P).
1497-
Proof. by move=> [] /orpp p; rewrite andpp; apply. Qed.
1498-
14991490
Lemma xorpN (P : decProp) Q : xor P (~ Q) <-> ~ (xor P Q).
1500-
Proof. by case: (propbP P) => [/iffT|/iffF] ->; rewrite ?xorTp ?xorFp. Qed.
1491+
Proof. by elim: (propbP P); rewrite ?xorTp ?xorFp. Qed.
15011492

15021493
Lemma xorNp P (Q : decProp) : xor (~ P) Q <-> ~ (xor P Q).
15031494
Proof. by rewrite xorpC xorpN xorpC. Qed.
15041495

15051496
Lemma xorpA (P : decProp) Q (R : decProp) : xor P (xor Q R) <-> xor (xor P Q) R.
15061497
Proof.
1507-
by case: (propbP P) => [/iffT|/iffF] ->; rewrite ?xorFp// !xorTp xorNp.
1498+
by elim: (propbP P); rewrite ?xorFp// !xorTp xorNp.
15081499
Qed.
15091500

15101501
Lemma xorpCA (P Q : decProp) R : xor P (xor Q R) <-> xor Q (xor P R).
15111502
Proof.
1512-
by case: (propbP P) => [/iffT|/iffF] ->; rewrite ?xorFp// !xorTp xorpN.
1503+
by elim: (propbP P); rewrite ?xorFp// !xorTp xorpN.
15131504
Qed.
15141505

15151506
Lemma xorpAC P (Q R : decProp) : xor (xor P Q) R <-> xor (xor P R) Q.
@@ -1530,15 +1521,15 @@ Proof. by rewrite andpC andp_xorl !(andpC P). Qed.
15301521

15311522
Lemma xorKp (P Q : decProp) : xor P (xor P Q) <-> Q.
15321523
Proof.
1533-
by case: (propbP P) => [/iffT|/iffF] ->; rewrite ?xorFp// !xorTp negpK.
1524+
by elim: (propbP P); rewrite ?xorFp// !xorTp negpK.
15341525
Qed.
15351526

15361527
Lemma xorpK (P Q : decProp) : xor (xor Q P) P <-> Q.
15371528
Proof. by rewrite ![xor _ P]xorpC xorKp. Qed.
15381529

15391530
Lemma xorpP (P : decProp) Q : xor P Q <-> (~ P <-> Q).
15401531
Proof.
1541-
case: (propbP P) => [/iffT|/iffF] ->.
1532+
elim: (propbP P).
15421533
by rewrite xorTp (iffF (_ : ~ ~ True))// iffFp.
15431534
by rewrite xorFp (iffT negpF) iffTp.
15441535
Qed.

0 commit comments

Comments
 (0)