Library FinSet.Lib.DProp
Require Coq.Logic.EqdepFacts.
Require Import Coq.Classes.RelationClasses.
Require Import Coq.Classes.Morphisms.
Require Coq.Setoids.Setoid.
Require Coq.Bool.Sumbool.
Record DProp := {
Holds :> Prop;
Denies : Prop;
dec :> { Holds } + { Denies };
contradictory : Holds → Denies → False
}.
Require Import Coq.Classes.RelationClasses.
Require Import Coq.Classes.Morphisms.
Require Coq.Setoids.Setoid.
Require Coq.Bool.Sumbool.
Record DProp := {
Holds :> Prop;
Denies : Prop;
dec :> { Holds } + { Denies };
contradictory : Holds → Denies → False
}.
Lemma denies_spec : ∀ (A:DProp), Denies A ↔ ¬A.
Ltac contradictory :=
solve [
contradiction |
elimtype False ; eauto using contradictory
]
.
Obligation Tactic :=
try solve [intuition eauto using contradictory].
This should probably in Coq's sumbool files. This notation
coerces a proof p:{A}+{B} into a proof of {A´}+{B´} with the
proof obligations A→A´ and B→B´.
DProp are decidable propositions in the usual sense.
Equality
In vanilla Coq, the appropriate notion of equality for DProp is
equivalence of the Holds field (equivalently, of the Denies
field).
The rewrite tactics needs some instances defined to work properly
with strongly decidable propositions as drop-in replacement of
regular propositions. Following the setoid rewrite library in
Coq.Classes.RelationClasses, there should be a series of lemma,
but as part of this library, we shall be content with the case of
equivalence relations (which is derived from more basic lemmas in
the case of regular propositions).
Instance dprop_proper A (R:A→A→DProp) (_:Equivalence R) :
Proper (R ==> R ==> eq_dprop) R.
Instance holds_proper : Proper (eq_dprop==>iff) Holds.
Instance denies_proper : Proper (eq_dprop==>iff) Denies.
Proper (R ==> R ==> eq_dprop) R.
Instance holds_proper : Proper (eq_dprop==>iff) Holds.
Instance denies_proper : Proper (eq_dprop==>iff) Denies.
Program Definition DTrue : DProp := {|
Holds := True ;
Denies := False ;
dec := left I
|}.
Program Definition DFalse : DProp := {|
Holds := False ;
Denies := True ;
dec := right I
|}.
Program Definition DAnd (A B:DProp) : DProp := {|
dec := Sumbool.sumbool_and _ _ _ _ (dec A) (dec B)
|}.
Notation "A && B" := (DAnd A B).
Program Definition DOr (A B:DProp) : DProp := {|
dec := Sumbool.sumbool_or _ _ _ _ (dec A) (dec B)
|}.
Notation "A || B" := (DOr A B).
Program Definition DNot (A:DProp) : DProp := {|
dec := Sumbool.sumbool_not _ _ (dec A)
|}.
Lemma dnot_spec : ∀ A, DNot A ↔ ¬A.
Instance dand_proper : Proper (eq_dprop ==> eq_dprop ==> eq_dprop) DAnd.
Instance dor_proper : Proper (eq_dprop ==> eq_dprop ==> eq_dprop) DOr.
Instance dnot_proper : Proper (eq_dprop ==> eq_dprop) DNot.
dec := Sumbool.sumbool_not _ _ (dec A)
|}.
Lemma dnot_spec : ∀ A, DNot A ↔ ¬A.
Instance dand_proper : Proper (eq_dprop ==> eq_dprop ==> eq_dprop) DAnd.
Instance dor_proper : Proper (eq_dprop ==> eq_dprop ==> eq_dprop) DOr.
Instance dnot_proper : Proper (eq_dprop ==> eq_dprop) DNot.
Proof irrelevance
Definition Canonize (P:DProp) : Prop := if (dec P) then True else False.
Lemma canonize_spec (P:DProp) : Canonize P ↔ P.
Lemma irrelevant_canonize (P:DProp) : ∀ x y:Canonize P, x=y.
Lemma canonize_spec (P:DProp) : Canonize P ↔ P.
Lemma irrelevant_canonize (P:DProp) : ∀ x y:Canonize P, x=y.
Booleans
Inductive Is_true : bool → Prop :=
| true_is_true : Is_true true.
Definition elim_is_true_false A (f:Is_true false) : A :=
match f with end.
| true_is_true : Is_true true.
Definition elim_is_true_false A (f:Is_true false) : A :=
match f with end.
This proof is a simplified variant of Hedberg's proof of
irrelevance of decidable equality.
Remark irrelevant_is_true : ∀ b (x y:Is_true b), x = y.
Proof.
set (ν := fun b ⇒
match b with
| true ⇒ fun _ ⇒ true_is_true
| false ⇒ elim_is_true_false _
end).
intros ×.
transitivity (ν b x).
+ destruct x. reflexivity.
+ destruct y. reflexivity.
Qed.
Proof.
set (ν := fun b ⇒
match b with
| true ⇒ fun _ ⇒ true_is_true
| false ⇒ elim_is_true_false _
end).
intros ×.
transitivity (ν b x).
+ destruct x. reflexivity.
+ destruct y. reflexivity.
Qed.
Program Definition dprop_of_bool (b:bool) : DProp := {| Holds := Is_true b ; Denies := ¬Is_true b |}.
Coercion dprop_of_bool : bool >-> DProp.
Coercion dprop_of_bool : bool >-> DProp.