(** * Decidability and Enumerability *)
Require Export Shared.Prelim.
(* ** Definitions *)
Definition compl X p := fun x : X => ~ p x.
Definition decidable {X} (p : X -> Prop) := exists f, forall x, p x <-> f x = true.
Definition enumerable {X} (p : X -> Prop) := exists f, forall x, p x <-> exists n : nat, f n = Some x.
Definition discrete X := decidable (fun '(x,y) => x = y :> X).
Definition enumerable__T X := exists f : nat -> option X, forall x, exists n, f n = Some x.
(* *** more practical type-theoretic characterisations *)

(* Specifications: *)
Lemma dec_decidable' X p :
(forall x : X, dec (p x)) -> { f : _ | forall x, p x <-> f x = true}.
Lemma decidable_iff X p :
decidable p <-> inhabited (forall x : X, dec (p x)).
Lemma discrete_iff X :
discrete X <-> inhabited (eq_dec X).