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) *)
(************************************************************************)
The type bool is defined in the prelude as
Inductive bool : Set := true : bool | false : bool
Most of the lemmas in this file are trivial after breaking all booleans
Ltac destr_bool :=
intros; destruct_all bool; simpl in *; trivial; try discriminate.
Interpretation of booleans as propositions
Definition Is_true (b:bool) := match b with | true => True | false => False end. (*******************)
(*******************)forall b1 b2 : bool, {b1 = b2} + {b1 <> b2}decide equality. Defined. (*********************)forall b1 b2 : bool, {b1 = b2} + {b1 <> b2}
(*********************)true <> falsediscriminate. Qed. Hint Resolve diff_true_false : bool.true <> falsefalse <> truediscriminate. Qed. Hint Resolve diff_false_true : bool. Hint Extern 1 (false <> true) => exact diff_false_true : core.false <> trueforall b : bool, b = true -> b = false -> Falsedestr_bool. Qed.forall b : bool, b = true -> b = false -> Falseforall b : bool, b <> true -> b = falsedestr_bool; intuition. Qed.forall b : bool, b <> true -> b = falseforall b : bool, b <> false -> b = truedestr_bool; intuition. Qed.forall b : bool, b <> false -> b = trueforall b : bool, b <> true <-> b = falsedestr_bool; intuition. Qed.forall b : bool, b <> true <-> b = falseforall b : bool, b <> false <-> b = truedestr_bool; intuition. Qed. (**********************)forall b : bool, b <> false <-> b = true
(**********************) Definition leb (b1 b2:bool) := match b1 with | true => b2 = true | false => True end. Hint Unfold leb: bool.forall b1 b2 : bool, leb b1 b2 <-> implb b1 b2 = truedestr_bool; intuition. Qed. (* Infix "<=" := leb : bool_scope. *) (*************)forall b1 b2 : bool, leb b1 b2 <-> implb b1 b2 = true
(*************) Definition eqb (b1 b2:bool) : bool := match b1, b2 with | true, true => true | true, false => false | false, true => false | false, false => true end.forall (P : bool -> Prop) (b1 b2 : bool), eqb b1 b2 = true -> P b1 -> P b2destr_bool. Qed.forall (P : bool -> Prop) (b1 b2 : bool), eqb b1 b2 = true -> P b1 -> P b2forall b : bool, eqb b b = truedestr_bool. Qed.forall b : bool, eqb b b = trueforall a b : bool, eqb a b = true -> a = bdestr_bool. Qed.forall a b : bool, eqb a b = true -> a = bforall a b : bool, eqb a b = true <-> a = bdestr_bool; intuition. Qed.forall a b : bool, eqb a b = true <-> a = bforall a b : bool, eqb a b = false <-> a <> bdestr_bool; intuition. Qed. (************************)forall a b : bool, eqb a b = false <-> a <> b
(************************) Definition ifb (b1 b2 b3:bool) : bool := match b1 with | true => b2 | false => b3 end. Open Scope bool_scope. (****************************)
(****************************)forall b1 b2 : bool, negb (b1 || b2) = negb b1 && negb b2destr_bool. Qed.forall b1 b2 : bool, negb (b1 || b2) = negb b1 && negb b2forall b1 b2 : bool, negb (b1 && b2) = negb b1 || negb b2destr_bool. Qed. (********************************)forall b1 b2 : bool, negb (b1 && b2) = negb b1 || negb b2
(********************************)forall b : bool, negb (negb b) = bdestr_bool. Qed.forall b : bool, negb (negb b) = bforall b : bool, b = negb (negb b)destr_bool. Qed. Notation negb_elim := negb_involutive (only parsing). Notation negb_intro := negb_involutive_reverse (only parsing).forall b : bool, b = negb (negb b)forall b b' : bool, b' = negb b -> b = negb b'destr_bool. Qed.forall b b' : bool, b' = negb b -> b = negb b'forall b : bool, negb b <> bdestr_bool. Qed.forall b : bool, negb b <> bforall b : bool, eqb (negb b) b = falsedestr_bool. Qed.forall b : bool, eqb (negb b) b = falseforall b : bool, eqb b (negb b) = falsedestr_bool. Qed.forall b : bool, eqb b (negb b) = falseforall (A : Type) (b : bool) (x y : A), (if negb b then x else y) = (if b then y else x)destr_bool. Qed.forall (A : Type) (b : bool) (x y : A), (if negb b then x else y) = (if b then y else x)forall b : bool, negb b = true <-> b = falsedestr_bool; intuition. Qed.forall b : bool, negb b = true <-> b = falseforall b : bool, negb b = false <-> b = truedestr_bool; intuition. Qed. (********************************)forall b : bool, negb b = false <-> b = true
(********************************)forall b1 b2 : bool, b1 || b2 = true <-> b1 = true \/ b2 = truedestr_bool; intuition. Qed.forall b1 b2 : bool, b1 || b2 = true <-> b1 = true \/ b2 = trueforall b1 b2 : bool, b1 || b2 = false <-> b1 = false /\ b2 = falsedestr_bool; intuition. Qed.forall b1 b2 : bool, b1 || b2 = false <-> b1 = false /\ b2 = falseforall b1 b2 : bool, b1 || b2 = true -> {b1 = true} + {b2 = true}destruct b1; simpl; auto. Defined.forall b1 b2 : bool, b1 || b2 = true -> {b1 = true} + {b2 = true}forall a b : bool, a || b = true -> a = true \/ b = trueintros; apply orb_true_iff; trivial. Qed.forall a b : bool, a || b = true -> a = true \/ b = trueforall b1 b2 : bool, b1 = true \/ b2 = true -> b1 || b2 = trueintros; apply orb_true_iff; trivial. Qed. Hint Resolve orb_true_intro: bool.forall b1 b2 : bool, b1 = true \/ b2 = true -> b1 || b2 = trueforall b1 b2 : bool, b1 = false -> b2 = false -> b1 || b2 = falseforall b1 b2 : bool, b1 = false -> b2 = false -> b1 || b2 = falseb1, b2:boolH:b1 = falseH0:b2 = falseb1 || b2 = falsereflexivity. Qed. Hint Resolve orb_false_intro: bool.false || false = falseforall b1 b2 : bool, b1 || b2 = false -> b1 = false /\ b2 = falseforall b1 b2 : bool, b1 || b2 = false -> b1 = false /\ b2 = falseapply orb_false_iff; trivial. Qed.b1, b2:boolH:b1 || b2 = falseb1 = false /\ b2 = falseforall b : bool, b || b = bdestr_bool. Qed.forall b : bool, b || b = b
true is a zero for orb
forall b : bool, b || true = truedestr_bool. Qed. Hint Resolve orb_true_r: bool.forall b : bool, b || true = trueforall b : bool, true || b = truereflexivity. Qed. Notation orb_b_true := orb_true_r (only parsing). Notation orb_true_b := orb_true_l (only parsing).forall b : bool, true || b = true
false is neutral for orb
forall b : bool, b || false = bdestr_bool. Qed. Hint Resolve orb_false_r: bool.forall b : bool, b || false = bforall b : bool, false || b = bdestr_bool. Qed. Hint Resolve orb_false_l: bool. Notation orb_b_false := orb_false_r (only parsing). Notation orb_false_b := orb_false_l (only parsing).forall b : bool, false || b = b
Complementation
forall b : bool, b || negb b = truedestr_bool. Qed. Hint Resolve orb_negb_r: bool. Notation orb_neg_b := orb_negb_r (only parsing).forall b : bool, b || negb b = true
Commutativity
forall b1 b2 : bool, b1 || b2 = b2 || b1destr_bool. Qed.forall b1 b2 : bool, b1 || b2 = b2 || b1
Associativity
forall b1 b2 b3 : bool, b1 || (b2 || b3) = b1 || b2 || b3destr_bool. Qed. Hint Resolve orb_comm orb_assoc: bool. (*******************************)forall b1 b2 b3 : bool, b1 || (b2 || b3) = b1 || b2 || b3
(*******************************)forall b1 b2 : bool, b1 && b2 = true <-> b1 = true /\ b2 = truedestr_bool; intuition. Qed.forall b1 b2 : bool, b1 && b2 = true <-> b1 = true /\ b2 = trueforall b1 b2 : bool, b1 && b2 = false <-> b1 = false \/ b2 = falsedestr_bool; intuition. Qed.forall b1 b2 : bool, b1 && b2 = false <-> b1 = false \/ b2 = falseforall a b : bool, true = a && b -> true = a /\ true = bforall a b : bool, true = a && b -> true = a /\ true = bauto. Defined.H:true = truetrue = true /\ true = trueforall b1 b2 : bool, b1 = false -> b1 && b2 = falseforall b1 b2 : bool, b1 = false -> b1 && b2 = falseb1, b2:boolH:b1 = falseb1 && b2 = falseauto. Qed.b1, b2:boolH:b1 = falseb1 = false \/ b2 = falseforall b1 b2 : bool, b2 = false -> b1 && b2 = falseforall b1 b2 : bool, b2 = false -> b1 && b2 = falseb1, b2:boolH:b2 = falseb1 && b2 = falseauto. Qed.b1, b2:boolH:b2 = falseb1 = false \/ b2 = false
false is a zero for andb
forall b : bool, b && false = falsedestr_bool. Qed.forall b : bool, b && false = falseforall b : bool, false && b = falsereflexivity. Qed. Notation andb_b_false := andb_false_r (only parsing). Notation andb_false_b := andb_false_l (only parsing).forall b : bool, false && b = falseforall b : bool, b && b = bdestr_bool. Qed.forall b : bool, b && b = b
true is neutral for andb
forall b : bool, b && true = bdestr_bool. Qed.forall b : bool, b && true = bforall b : bool, true && b = breflexivity. Qed. Notation andb_b_true := andb_true_r (only parsing). Notation andb_true_b := andb_true_l (only parsing).forall b : bool, true && b = bforall b1 b2 : bool, b1 && b2 = false -> {b1 = false} + {b2 = false}destruct b1; simpl; auto. Defined. Hint Resolve andb_false_elim: bool.forall b1 b2 : bool, b1 && b2 = false -> {b1 = false} + {b2 = false}
Complementation
forall b : bool, b && negb b = falsedestr_bool. Qed. Hint Resolve andb_negb_r: bool. Notation andb_neg_b := andb_negb_r (only parsing).forall b : bool, b && negb b = false
Commutativity
forall b1 b2 : bool, b1 && b2 = b2 && b1destr_bool. Qed.forall b1 b2 : bool, b1 && b2 = b2 && b1
Associativity
forall b1 b2 b3 : bool, b1 && (b2 && b3) = b1 && b2 && b3destr_bool. Qed. Hint Resolve andb_comm andb_assoc: bool. (*******************************************)forall b1 b2 b3 : bool, b1 && (b2 && b3) = b1 && b2 && b3
(*******************************************)
Distributivity
forall b1 b2 b3 : bool, b1 && (b2 || b3) = b1 && b2 || b1 && b3destr_bool. Qed.forall b1 b2 b3 : bool, b1 && (b2 || b3) = b1 && b2 || b1 && b3forall b1 b2 b3 : bool, (b1 || b2) && b3 = b1 && b3 || b2 && b3destr_bool. Qed.forall b1 b2 b3 : bool, (b1 || b2) && b3 = b1 && b3 || b2 && b3forall b1 b2 b3 : bool, b1 || b2 && b3 = (b1 || b2) && (b1 || b3)destr_bool. Qed.forall b1 b2 b3 : bool, b1 || b2 && b3 = (b1 || b2) && (b1 || b3)forall b1 b2 b3 : bool, b1 && b2 || b3 = (b1 || b3) && (b2 || b3)destr_bool. Qed. (* Compatibility *) Notation demorgan1 := andb_orb_distrib_r (only parsing). Notation demorgan2 := andb_orb_distrib_l (only parsing). Notation demorgan3 := orb_andb_distrib_r (only parsing). Notation demorgan4 := orb_andb_distrib_l (only parsing).forall b1 b2 b3 : bool, b1 && b2 || b3 = (b1 || b3) && (b2 || b3)
Absorption
forall b1 b2 : bool, b1 && (b1 || b2) = b1destr_bool. Qed.forall b1 b2 : bool, b1 && (b1 || b2) = b1forall b1 b2 : bool, b1 || b1 && b2 = b1destr_bool. Qed. (* begin hide *) (* Compatibility *) Notation absoption_andb := absorption_andb (only parsing). Notation absoption_orb := absorption_orb (only parsing). (* end hide *) (*********************************)forall b1 b2 : bool, b1 || b1 && b2 = b1
(*********************************)
false is neutral for xorb
forall b : bool, xorb b false = bdestr_bool. Qed.forall b : bool, xorb b false = bforall b : bool, xorb false b = bdestr_bool. Qed. Notation xorb_false := xorb_false_r (only parsing). Notation false_xorb := xorb_false_l (only parsing).forall b : bool, xorb false b = b
true is "complementing" for xorb
forall b : bool, xorb b true = negb breflexivity. Qed.forall b : bool, xorb b true = negb bforall b : bool, xorb true b = negb breflexivity. Qed. Notation xorb_true := xorb_true_r (only parsing). Notation true_xorb := xorb_true_l (only parsing).forall b : bool, xorb true b = negb b
Nilpotency (alternatively: identity is a inverse for xorb)
forall b : bool, xorb b b = falsedestr_bool. Qed.forall b : bool, xorb b b = false
Commutativity
forall b b' : bool, xorb b b' = xorb b' bdestr_bool. Qed.forall b b' : bool, xorb b b' = xorb b' b
Associativity
forall b b' b'' : bool, xorb (xorb b b') b'' = xorb b (xorb b' b'')destr_bool. Qed. Notation xorb_assoc := xorb_assoc_reverse (only parsing). (* Compatibility *)forall b b' b'' : bool, xorb (xorb b b') b'' = xorb b (xorb b' b'')forall b b' : bool, xorb b b' = false -> b = b'destr_bool. Qed.forall b b' : bool, xorb b b' = false -> b = b'forall b b' b'' : bool, xorb b b' = b'' -> b' = xorb b b''destr_bool. Qed.forall b b' b'' : bool, xorb b b' = b'' -> b' = xorb b b''forall b b' b'' : bool, xorb b b' = b'' -> b = xorb b'' b'destr_bool. Qed.forall b b' b'' : bool, xorb b b' = b'' -> b = xorb b'' b'forall b b' b'' : bool, b = xorb b' b'' -> xorb b' b = b''destr_bool. Qed.forall b b' b'' : bool, b = xorb b' b'' -> xorb b' b = b''forall b b' b'' : bool, b = xorb b' b'' -> xorb b b'' = b'destr_bool. Qed.forall b b' b'' : bool, b = xorb b' b'' -> xorb b b'' = b'forall b b' : bool, negb (xorb b b') = xorb (negb b) b'destruct b,b'; trivial. Qed.forall b b' : bool, negb (xorb b b') = xorb (negb b) b'forall b b' : bool, negb (xorb b b') = xorb b (negb b')destruct b,b'; trivial. Qed.forall b b' : bool, negb (xorb b b') = xorb b (negb b')forall b b' : bool, xorb (negb b) (negb b') = xorb b b'destruct b,b'; trivial. Qed.forall b b' : bool, xorb (negb b) (negb b') = xorb b b'
Lemmas about the b = true embedding of bool to Prop
forall b1 b2 : bool, b1 = b2 <-> (b1 = true <-> b2 = true)destr_bool; intuition. Qed.forall b1 b2 : bool, b1 = b2 <-> (b1 = true <-> b2 = true)forall b1 b2 : bool, b1 = true <-> b2 = true -> b1 = b2apply eq_iff_eq_true. Qed. Notation bool_1 := eq_true_iff_eq (only parsing). (* Compatibility *)forall b1 b2 : bool, b1 = true <-> b2 = true -> b1 = b2forall b : bool, negb b <> true -> b = truedestr_bool; intuition. Qed. Notation bool_3 := eq_true_negb_classical (only parsing). (* Compatibility *)forall b : bool, negb b <> true -> b = trueforall b : bool, b <> true -> negb b = truedestr_bool; intuition. Qed. Notation bool_6 := eq_true_not_negb (only parsing). (* Compatibility *) Hint Resolve eq_true_not_negb : bool. (* An interesting lemma for auto but too strong to keep compatibility *)forall b : bool, b <> true -> negb b = trueforall b b' : bool, False -> b = b'contradiction. Qed. (* A more specific one that preserves compatibility with old hint bool_3 *)forall b b' : bool, False -> b = b'forall b : bool, False -> b = truecontradiction. Qed. Hint Resolve absurd_eq_true : core. (* A specific instance of eq_trans that preserves compatibility with old hint bool_2 *)forall b : bool, False -> b = trueforall x y z : bool, x = y -> y = z -> x = zapply eq_trans. Qed. Hint Resolve trans_eq_bool : core. (*****************************************)forall x y z : bool, x = y -> y = z -> x = z
(*****************************************)
Is_true and equality
Hint Unfold Is_true: bool.forall x : bool, Is_true x -> x = truedestr_bool; tauto. Qed.forall x : bool, Is_true x -> x = trueforall x : bool, x = true -> Is_true xintros; subst; auto with bool. Qed.forall x : bool, x = true -> Is_true xforall x : bool, true = x -> Is_true xintros; subst; auto with bool. Qed. Notation Is_true_eq_true2 := Is_true_eq_right (only parsing). Hint Immediate Is_true_eq_right Is_true_eq_left: bool.forall x : bool, true = x -> Is_true xforall x : bool, Is_true (eqb x x)destr_bool. Qed.forall x : bool, Is_true (eqb x x)forall x y : bool, Is_true (eqb x y) -> x = ydestr_bool; tauto. Qed.forall x y : bool, Is_true (eqb x y) -> x = y
Is_true and connectives
forall a b : bool, Is_true (a || b) -> Is_true a \/ Is_true bdestr_bool; tauto. Qed. Notation orb_prop2 := orb_prop_elim (only parsing).forall a b : bool, Is_true (a || b) -> Is_true a \/ Is_true bforall a b : bool, Is_true a \/ Is_true b -> Is_true (a || b)destr_bool; tauto. Qed.forall a b : bool, Is_true a \/ Is_true b -> Is_true (a || b)forall b1 b2 : bool, Is_true b1 /\ Is_true b2 -> Is_true (b1 && b2)destr_bool; tauto. Qed. Hint Resolve andb_prop_intro: bool. Notation andb_true_intro2 := (fun b1 b2 H1 H2 => andb_prop_intro b1 b2 (conj H1 H2)) (only parsing).forall b1 b2 : bool, Is_true b1 /\ Is_true b2 -> Is_true (b1 && b2)forall a b : bool, Is_true (a && b) -> Is_true a /\ Is_true bdestr_bool; auto. Qed. Hint Resolve andb_prop_elim: bool. Notation andb_prop2 := andb_prop_elim (only parsing).forall a b : bool, Is_true (a && b) -> Is_true a /\ Is_true bforall b1 b2 : bool, Is_true b1 <-> Is_true b2 -> b1 = b2destr_bool; tauto. Qed.forall b1 b2 : bool, Is_true b1 <-> Is_true b2 -> b1 = b2forall b1 b2 : bool, b1 = b2 -> Is_true b1 <-> Is_true b2destr_bool; tauto. Qed.forall b1 b2 : bool, b1 = b2 -> Is_true b1 <-> Is_true b2forall b : bool, Is_true (negb b) -> ~ Is_true bdestr_bool; tauto. Qed.forall b : bool, Is_true (negb b) -> ~ Is_true bforall b : bool, ~ Is_true b -> Is_true (negb b)destr_bool; tauto. Qed.forall b : bool, ~ Is_true b -> Is_true (negb b)forall b : bool, ~ Is_true (negb b) -> Is_true bdestr_bool; tauto. Qed.forall b : bool, ~ Is_true (negb b) -> Is_true bforall b : bool, Is_true b -> ~ Is_true (negb b)destr_bool; tauto. Qed.forall b : bool, Is_true b -> ~ Is_true (negb b)
Rewrite rules about andb, orb and if (used in romega)
forall (A : Type) (a a' : A) (b b' : bool), (if b && b' then a else a') = (if b then if b' then a else a' else a')destr_bool. Qed.forall (A : Type) (a a' : A) (b b' : bool), (if b && b' then a else a') = (if b then if b' then a else a' else a')forall (A : Type) (a a' : A) (b : bool), (if negb b then a else a') = (if b then a' else a)destr_bool. Qed. (*****************************************)forall (A : Type) (a a' : A) (b : bool), (if negb b then a else a') = (if b then a' else a)
(*****************************************) Declare Scope lazy_bool_scope. Notation "a &&& b" := (if a then b else false) (at level 40, left associativity) : lazy_bool_scope. Notation "a ||| b" := (if a then true else b) (at level 50, left associativity) : lazy_bool_scope. Local Open Scope lazy_bool_scope.forall a b : bool, a && b = a &&& breflexivity. Qed.forall a b : bool, a && b = a &&& bforall a b : bool, a || b = a ||| breflexivity. Qed. (*****************************************)forall a b : bool, a || b = a ||| b
Reflect: a specialized inductive type for
relating propositions and booleans, as popularized by the Ssreflect library.(*****************************************) Inductive reflect (P : Prop) : bool -> Set := | ReflectT : P -> reflect P true | ReflectF : ~ P -> reflect P false. Hint Constructors reflect : bool.
Interest: a case on a reflect lemma or hyp performs clever
unification, and leave the goal in a convenient shape
(a bit like case_eq).
Relation with iff :
forall (P : Prop) (b : bool), reflect P b -> P <-> b = truedestruct 1; intuition; discriminate. Qed.forall (P : Prop) (b : bool), reflect P b -> P <-> b = trueforall (P : Prop) (b : bool), P <-> b = true -> reflect P bdestr_bool; intuition. Defined.forall (P : Prop) (b : bool), P <-> b = true -> reflect P b
It would be nice to join reflect_iff and iff_reflect
in a unique iff statement, but this isn't allowed since
iff is in Prop.
Reflect implies decidability of the proposition
forall (P : Prop) (b : bool), reflect P b -> {P} + {~ P}destruct 1; auto. Defined.forall (P : Prop) (b : bool), reflect P b -> {P} + {~ P}
Reciprocally, from a decidability, we could state a
reflect as soon as we have a bool_of_sumbool.
For instance, we could state the correctness of Bool.eqb via reflect:
b, b':boolreflect (b = b') (eqb b b')destruct b, b'; now constructor. Defined.b, b':boolreflect (b = b') (eqb b b')