(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \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 *)

(** Note: the following definition of [decidable] can be used to
    express the notion of decidability in computability theory only in
    an axiom-free Coq (since a proof of [forall n, decidable (P n)],
    for [P] a countable class of problems, induces by extraction the
    existence of a (total) recursive algorithm [f] such that [f(n)]
    evaluates to [true] iff [P n], and since, conversely, a Coq proof
    of termination of a recursive algorithm deciding [P n] can be
    extracted in turn into a proof of [forall n, decidable (P n)]). In
    the presence of axioms such as [Classical_prop.classic], it would
    take a different meaning. *)

Definition decidable (P:Prop) := P \/ ~ P.

(* Specifications: *)
Theorem dec_not_not : forall P:Prop, decidable P -> (~ P -> False) -> P.
Theorem dec_True : decidable True.
Theorem dec_False : decidable False.
Theorem dec_or : forall A B:Prop, decidable A -> decidable B -> decidable (A \/ B).
Theorem dec_and : forall A B:Prop, decidable A -> decidable B -> decidable (A /\ B).
Theorem dec_not : forall A:Prop, decidable A -> decidable (~ A).
Theorem dec_imp : forall A B:Prop, decidable A -> decidable B -> decidable (A -> B).
Theorem dec_iff : forall A B:Prop, decidable A -> decidable B -> decidable (A<->B).
Theorem not_not : forall P:Prop, decidable P -> ~ ~ P -> P.
Theorem not_or : forall A B:Prop, ~ (A \/ B) -> ~ A /\ ~ B.
Theorem not_and : forall A B:Prop, decidable A -> ~ (A /\ B) -> ~ A \/ ~ B.
Theorem not_imp : forall A B:Prop, decidable A -> ~ (A -> B) -> A /\ ~ B.
Theorem imp_simp : forall A B:Prop, decidable A -> (A -> B) -> ~ A \/ B.
Theorem not_iff : forall A B:Prop, decidable A -> decidable B -> ~ (A <-> B) -> (A /\ ~ B) \/ (~ A /\ B).
Theorem not_true_iff : (True -> False) <-> False.
Theorem not_false_iff : (False -> False) <-> True.
Theorem not_not_iff : forall A:Prop, decidable A -> (((A -> False) -> False) <-> A).
Theorem contrapositive : forall A B:Prop, decidable A -> (((A -> False) -> (B -> False)) <-> (B -> A)).
Lemma or_not_l_iff_1 : forall A B: Prop, decidable A -> ((A -> False) \/ B <-> (A -> B)).
Lemma or_not_l_iff_2 : forall A B: Prop, decidable B -> ((A -> False) \/ B <-> (A -> B)).
Lemma or_not_r_iff_1 : forall A B: Prop, decidable A -> (A \/ (B -> False) <-> (B -> A)).
Lemma or_not_r_iff_2 : forall A B: Prop, decidable B -> (A \/ (B -> False) <-> (B -> A)).
Lemma imp_not_l : forall A B: Prop, decidable A -> (((A -> False) -> B) <-> (A \/ B)).
Theorem not_or_iff : forall A B:Prop, (A \/ B -> False) <-> (A -> False) /\ (B -> False).
Lemma not_and_iff : forall A B:Prop, (A /\ B -> False) <-> (A -> B -> False).
Lemma not_imp_iff : forall A B:Prop, decidable A -> (((A -> B) -> False) <-> A /\ (B -> False)).
Lemma not_imp_rev_iff : forall A B : Prop, decidable A -> (((A -> B) -> False) <-> (B -> False) /\ A).
Theorem dec_functional_relation : forall (X Y : Type) (A:X->Y->Prop), (forall y y' : Y, decidable (y=y')) -> (forall x, exists! y, A x y) -> forall x y, decidable (A x y).