(********************************************************************)
(** * Datatypes with zero and one element *)

(** [Empty_set] is a datatype with no inhabitant *)

Inductive Empty_set : Set :=.(** [unit] is a singleton datatype with sole inhabitant [tt] *)

Inductive unit : Set :=
    tt : unit.(** [unit] is a singleton datatype with sole inhabitant [tt] *)

Inductive unit : Set :=
    tt : unit.(********************************************************************)
(** * The boolean datatype *)

(** [bool] is the datatype of the boolean values [true] and [false] *)

Inductive bool : Set :=
  | true : bool
  | false : bool.(********************************************************************)
(** * The boolean datatype *)

(** [bool] is the datatype of the boolean values [true] and [false] *)

Inductive bool : Set :=
  | true : bool
  | false : bool.(********************************************************************)
(** * The boolean datatype *)

(** [bool] is the datatype of the boolean values [true] and [false] *)

Inductive bool : Set :=
  | true : bool
  | false : bool.(************************************************)
(** * 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.(************************************************)
(** * 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.(************************************************)
(** * 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.(** 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). *)

(** Basic boolean operators *)

Definition andb (b1 b2:bool) : bool := if b1 then b2 else false.Definition orb (b1 b2:bool) : bool := if b1 then true else b2.Definition implb (b1 b2:bool) : bool := if b1 then b2 else true.Definition xorb (b1 b2:bool) : bool :=
  if b1 then
    if b2 then false else true
  else b2.Definition negb (b:bool) := if b then false else true.Infix "||" := orb : bool_scope.Infix "&&" := andb : bool_scope.

(* Specifications: *)
Lemma andb_prop (a b:bool) : andb a b = true -> a = true /\ b = true.
Lemma andb_true_intro (b1 b2:bool) : b1 = true /\ b2 = true -> andb b1 b2 = true.