Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Properties of decidable propositions
Definition decidable (P:Prop) := P \/ ~ P.forall P : Prop, decidable P -> (~ P -> False) -> Punfold decidable; tauto. Qed.forall P : Prop, decidable P -> (~ P -> False) -> Pdecidable Trueunfold decidable; auto. Qed.decidable Truedecidable Falseunfold decidable, not; auto. Qed.decidable Falseforall A B : Prop, decidable A -> decidable B -> decidable (A \/ B)unfold decidable; tauto. Qed.forall A B : Prop, decidable A -> decidable B -> decidable (A \/ B)forall A B : Prop, decidable A -> decidable B -> decidable (A /\ B)unfold decidable; tauto. Qed.forall A B : Prop, decidable A -> decidable B -> decidable (A /\ B)forall A : Prop, decidable A -> decidable (~ A)unfold decidable; tauto. Qed.forall A : Prop, decidable A -> decidable (~ A)forall A B : Prop, decidable A -> decidable B -> decidable (A -> B)unfold decidable; tauto. Qed.forall A B : Prop, decidable A -> decidable B -> decidable (A -> B)forall A B : Prop, decidable A -> decidable B -> decidable (A <-> B)forall A B : Prop, decidable A -> decidable B -> decidable (A <-> B)tauto. Qed.forall A B : Prop, A \/ ~ A -> B \/ ~ B -> (A <-> B) \/ ~ (A <-> B)forall P : Prop, decidable P -> ~ ~ P -> Punfold decidable; tauto. Qed.forall P : Prop, decidable P -> ~ ~ P -> Pforall A B : Prop, ~ (A \/ B) -> ~ A /\ ~ Btauto. Qed.forall A B : Prop, ~ (A \/ B) -> ~ A /\ ~ Bforall A B : Prop, decidable A -> ~ (A /\ B) -> ~ A \/ ~ Bunfold decidable; tauto. Qed.forall A B : Prop, decidable A -> ~ (A /\ B) -> ~ A \/ ~ Bforall A B : Prop, decidable A -> ~ (A -> B) -> A /\ ~ Bunfold decidable; tauto. Qed.forall A B : Prop, decidable A -> ~ (A -> B) -> A /\ ~ Bforall A B : Prop, decidable A -> (A -> B) -> ~ A \/ Bunfold decidable; tauto. Qed.forall A B : Prop, decidable A -> (A -> B) -> ~ A \/ Bforall A B : Prop, decidable A -> decidable B -> ~ (A <-> B) -> A /\ ~ B \/ ~ A /\ Bunfold decidable; tauto. Qed. Register dec_True as core.dec.True. Register dec_False as core.dec.False. Register dec_or as core.dec.or. Register dec_and as core.dec.and. Register dec_not as core.dec.not. Register dec_imp as core.dec.imp. Register dec_iff as core.dec.iff. Register dec_not_not as core.dec.not_not. Register not_not as core.dec.dec_not_not. Register not_or as core.dec.not_or. Register not_and as core.dec.not_and. Register not_imp as core.dec.not_imp. Register imp_simp as core.dec.imp_simp. Register not_iff as core.dec.not_iff.forall A B : Prop, decidable A -> decidable B -> ~ (A <-> B) -> A /\ ~ B \/ ~ A /\ B
Results formulated with iff, used in FSetDecide.
Negation are expanded since it is unclear whether setoid rewrite
will always perform conversion.
We begin with lemmas that, when read from left to right,
can be understood as ways to eliminate uses of not.
(True -> False) <-> Falsetauto. Qed.(True -> False) <-> False(False -> False) <-> Truetauto. Qed.(False -> False) <-> Trueforall A : Prop, decidable A -> ((A -> False) -> False) <-> Aunfold decidable; tauto. Qed.forall A : Prop, decidable A -> ((A -> False) -> False) <-> Aforall A B : Prop, decidable A -> ((A -> False) -> B -> False) <-> (B -> A)unfold decidable; tauto. Qed.forall A B : Prop, decidable A -> ((A -> False) -> B -> False) <-> (B -> A)forall A B : Prop, decidable A -> (A -> False) \/ B <-> (A -> B)forall A B : Prop, decidable A -> (A -> False) \/ B <-> (A -> B)tauto. Qed.forall A B : Prop, A \/ ~ A -> (A -> False) \/ B <-> (A -> B)forall A B : Prop, decidable B -> (A -> False) \/ B <-> (A -> B)forall A B : Prop, decidable B -> (A -> False) \/ B <-> (A -> B)tauto. Qed.forall A B : Prop, B \/ ~ B -> (A -> False) \/ B <-> (A -> B)forall A B : Prop, decidable A -> A \/ (B -> False) <-> (B -> A)forall A B : Prop, decidable A -> A \/ (B -> False) <-> (B -> A)tauto. Qed.forall A B : Prop, A \/ ~ A -> A \/ (B -> False) <-> (B -> A)forall A B : Prop, decidable B -> A \/ (B -> False) <-> (B -> A)forall A B : Prop, decidable B -> A \/ (B -> False) <-> (B -> A)tauto. Qed.forall A B : Prop, B \/ ~ B -> A \/ (B -> False) <-> (B -> A)forall A B : Prop, decidable A -> ((A -> False) -> B) <-> A \/ Bforall A B : Prop, decidable A -> ((A -> False) -> B) <-> A \/ Btauto. Qed.forall A B : Prop, A \/ ~ A -> ((A -> False) -> B) <-> A \/ B
Moving Negations Around:
We have four lemmas that, when read from left to right,
describe how to push negations toward the leaves of a
proposition and, when read from right to left, describe
how to pull negations toward the top of a proposition.
forall A B : Prop, (A \/ B -> False) <-> (A -> False) /\ (B -> False)tauto. Qed.forall A B : Prop, (A \/ B -> False) <-> (A -> False) /\ (B -> False)forall A B : Prop, (A /\ B -> False) <-> (A -> B -> False)tauto. Qed.forall A B : Prop, (A /\ B -> False) <-> (A -> B -> False)forall A B : Prop, decidable A -> ((A -> B) -> False) <-> A /\ (B -> False)forall A B : Prop, decidable A -> ((A -> B) -> False) <-> A /\ (B -> False)tauto. Qed.forall A B : Prop, A \/ ~ A -> ((A -> B) -> False) <-> A /\ (B -> False)forall A B : Prop, decidable A -> ((A -> B) -> False) <-> (B -> False) /\ Aforall A B : Prop, decidable A -> ((A -> B) -> False) <-> (B -> False) /\ Atauto. Qed. (* Functional relations on decidable co-domains are decidable *)forall A B : Prop, A \/ ~ A -> ((A -> B) -> False) <-> (B -> False) /\ Aforall (X Y : Type) (A : X -> Y -> Prop), (forall y y' : Y, decidable (y = y')) -> (forall x : X, exists ! y : Y, A x y) -> forall (x : X) (y : Y), decidable (A x y)forall (X Y : Type) (A : X -> Y -> Prop), (forall y y' : Y, decidable (y = y')) -> (forall x : X, exists ! y : Y, A x y) -> forall (x : X) (y : Y), decidable (A x y)X, Y:TypeA:X -> Y -> PropHdec:forall y0 y' : Y, decidable (y0 = y')H:forall x0 : X, exists ! y0 : Y, A x0 y0x:Xy:Ydecidable (A x y)destruct (Hdec y y') as [->|Hnot]; firstorder. Qed.X, Y:TypeA:X -> Y -> PropHdec:forall y0 y'0 : Y, decidable (y0 = y'0)H:forall x0 : X, exists ! y0 : Y, A x0 y0x:Xy, y':YHex:A x y'Huniq:forall x' : Y, A x x' -> y' = x'decidable (A x y)
With the following hint database, we can leverage auto to check
decidability of propositions.
Hint Resolve dec_True dec_False dec_or dec_and dec_imp dec_not dec_iff
: decidable_prop.
solve_decidable using lib will solve goals about the
decidability of a proposition, assisted by an auxiliary
database of lemmas. The database is intended to contain
lemmas stating the decidability of base propositions,
(e.g., the decidability of equality on a particular
inductive type).
Tactic Notation "solve_decidable" "using" ident(db) := match goal with | |- decidable _ => solve [ auto 100 with decidable_prop db ] end. Tactic Notation "solve_decidable" := solve_decidable using core.