Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Local Set Universe Minimization ToSet. (** * If and only if *) (** ** Definition *) (** [iff A B], written [A <-> B], expresses the logical equivalence of [A] and [B] *) Definition iff (A B : Type) := prod (A -> B) (B -> A). Notation "A <-> B" := (iff A B) : type_scope. (** ** Basic Properties *) (** Everything is logically equivalent to itself. *) Definition iff_refl {A} : A <-> A := (idmap , idmap). (** [iff] is a reflexive relation. *) Instance iff_reflexive : Reflexive iff | 1 := @iff_refl. (** Logical equivalences can be inverted. *) Definition iff_inverse {A B} : (A <-> B) -> (B <-> A) := fun f => (snd f , fst f). (** [iff] is a symmetric relation. *) Instance symmetric_iff : Symmetric iff | 1 := @iff_inverse. (** Logical equivalences can be composed. *) Definition iff_compose {A B C} (f : A <-> B) (g : B <-> C) : A <-> C := (fst g o fst f , snd f o snd g). (** [iff] is a transitive relation. *) Instance transitive_iff : Transitive iff | 1 := @iff_compose. (** Any equivalence can be considered a logical equivalence by discarding everything but the maps. We make this a coercion so that equivalences can be used in place of logical equivalences. *) Coercion iff_equiv {A B : Type} (f : A <~> B) : A <-> B := (equiv_fun f, f^-1). (** ** Logical Laws *) (** One of De Morgan's Laws. The dual statement about negating a product appears in Decidable.v due to decidability requirements. *)
A, B: Type

~ (A + B) <-> ~ A * ~ B
A, B: Type

~ (A + B) <-> ~ A * ~ B
A, B: Type

~ (A + B) -> ~ A * ~ B
A, B: Type
~ A * ~ B -> ~ (A + B)
A, B: Type

~ (A + B) -> ~ A * ~ B
A, B: Type
ns: ~ (A + B)

~ A * ~ B
exact (ns o inl, ns o inr).
A, B: Type

~ A * ~ B -> ~ (A + B)
by intros []; snapply sum_ind. Defined.
A: Type

A * ~ A <-> Empty
A: Type

A * ~ A <-> Empty
A: Type

A * ~ A -> Empty
A: Type
Empty -> A * ~ A
A: Type

A * ~ A -> Empty
intros [a na]; exact (na a).
A: Type

Empty -> A * ~ A
intros e; exact (Empty_rec _ e). Defined.