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.
(** * Bounded Search *)

(** The main result of this file is [minimal_n], which say that if [P : nat -> Type] is a family such that each [P n] is decidable and [{n & P n}] is merely inhabited, then [{n & P n}] is inhabited.  Since [P n] is decidable, it is sufficient to prove [{n & merely (P n)}], and to do this, we prove the stronger claim that there is a *minimal* [n] satisfying [merely (P n)].  This stronger claim is a proposition, which is what makes the argument work.  Along the way, we also prove that [{ l : nat & (l <= n) * P l }] is decidable for each [n]. *)

[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Types.Sigma Types.Prod. Require Import Truncations.Core. Require Import Spaces.Nat.Core. Section bounded_search. Context (P : nat -> Type) (P_dec : forall n, Decidable (P n)). (** We open [type_scope] again after [nat_scope] in order to use the product type notation. *) Local Open Scope nat_scope. Local Open Scope type_scope. Local Definition minimal (n : nat) : Type := forall m : nat, P m -> n <= m. (** If we assume [Funext], then [minimal n] is a proposition. But to avoid needing [Funext], we propositionally truncate it. *) Local Definition min_n_Type : Type := { n : nat & merely (P n) * merely (minimal n) }.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)

IsHProp min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)

IsHProp min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)

forall x y : nat, merely (P x) * merely (minimal x) -> merely (P y) * merely (minimal y) -> x = y
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, n': nat
p: merely (P n)
m: merely (minimal n)
p': merely (P n')
m': merely (minimal n')

n = n'
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, n': nat
m': minimal n'
p': P n'
m: minimal n
p: P n

n = n'
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, n': nat
m': minimal n'
p': P n'
m: minimal n
p: P n

n <= n'
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, n': nat
m': minimal n'
p': P n'
m: minimal n
p: P n
n' <= n
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, n': nat
m': minimal n'
p': P n'
m: minimal n
p: P n

n <= n'
exact (m n' p').
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, n': nat
m': minimal n'
p': P n'
m: minimal n
p: P n

n' <= n
exact (m' n p). Defined. Local Definition smaller (n : nat) := { l : nat & P l * minimal l * (l <= n) }.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
k: smaller n

smaller n.+1
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
k: smaller n

smaller n.+1
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
p: P l
m: minimal l
z: l <= n

smaller n.+1
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
p: P l
m: minimal l
z: l <= n

P l * minimal l * (l <= n.+1)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
p: P l
m: minimal l
z: l <= n

P l
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
p: P l
m: minimal l
z: l <= n
minimal l
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
p: P l
m: minimal l
z: l <= n
l <= n.+1
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
p: P l
m: minimal l
z: l <= n

l <= n.+1
exact _. Defined.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat

smaller n + (forall l : nat, l <= n -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat

smaller n + (forall l : nat, l <= n -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)

smaller 0 + (forall l : nat, l <= 0 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
IHn: smaller n + (forall l : nat, l <= n -> ~ P l)
smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)

smaller 0 + (forall l : nat, l <= 0 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
h: P 0

smaller 0 + (forall l : nat, l <= 0 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: ~ P 0
smaller 0 + (forall l : nat, l <= 0 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
h: P 0

smaller 0 + (forall l : nat, l <= 0 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
h: P 0

smaller 0
exact (0; (h, fun _ _ => _, _)).
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: ~ P 0

smaller 0 + (forall l : nat, l <= 0 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: ~ P 0

forall l : nat, l <= 0 -> ~ P l
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: ~ P 0
l: nat
lleq0: l <= 0

~ P l
by rewrite (leq_antisym lleq0 _ : l = 0).
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
IHn: smaller n + (forall l : nat, l <= n -> ~ P l)

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
s: smaller n

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
s: smaller n

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
left; by apply smaller_S.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
nP: ~ P n.+1
smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1

smaller n.+1
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1

minimal n.+1
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1
m: nat
pm: P m

n.+1 <= m
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1
m: nat
pm: P m

~ (n.+1 > m)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1
m: nat
pm: P m
leq_Sm_Sn: m.+1 <= n.+1

Empty
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
h: P n.+1
m: nat
pm: P m
leq_Sm_Sn: m <= n

Empty
destruct (n0 m leq_Sm_Sn pm).
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
nP: ~ P n.+1

smaller n.+1 + (forall l : nat, l <= n.+1 -> ~ P l)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
n0: forall l : nat, l <= n -> ~ P l
nP: ~ P n.+1

forall l : nat, l <= n.+1 -> ~ P l
by apply leq_ind_l. Defined.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
Pn: P n

min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
Pn: P n

min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
Pn: P n
l: nat
Pl: P l
ml: minimal l

min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
Pn: P n
none: forall l : nat, l <= n -> ~ P l
min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
Pn: P n
l: nat
Pl: P l
ml: minimal l

min_n_Type
exact (l; (tr Pl, tr ml)).
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
Pn: P n
none: forall l : nat, l <= n -> ~ P l

min_n_Type
destruct (none n (leq_refl n) Pn). Defined.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
P_inhab: hexists P

min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
P_inhab: hexists P

min_n_Type
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
P_inhab: {x : _ & P x}

min_n_Type
exact (n_to_min_n (P_inhab.1) (P_inhab.2)). Defined.
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
P_inhab: hexists P

{n : nat & P n}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
P_inhab: hexists P

{n : nat & P n}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
P_inhab: hexists P
n: nat
p: merely (P n)

{n : nat & P n}
exact (n; fst merely_inhabited_iff_inhabited_stable p). Defined. (** As a consequence of [bounded_search] we deduce that bounded existence is decidable. See also [decidable_exists_bounded_nat] in Spaces/Lists/Theory.v for a similar result with different dependencies. *)
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat

Decidable {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat

Decidable {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
s: smaller n

Decidable {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
no_l: forall l : nat, l <= n -> ~ P l
Decidable {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
s: smaller n

Decidable {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n, l: nat
Pl: P l
min: minimal l
l_leq_n: l <= n

Decidable {l : nat & (l <= n) * P l}
exact (inl (l; (l_leq_n, Pl))).
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
no_l: forall l : nat, l <= n -> ~ P l

Decidable {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
no_l: forall l : nat, l <= n -> ~ P l

~ {l : nat & (l <= n) * P l}
P: nat -> Type
P_dec: forall n : nat, Decidable (P n)
n: nat
no_l: forall l : nat, l <= n -> ~ P l
l: nat
l_leq_n: l <= n
Pl: P l

Empty
exact (no_l l l_leq_n Pl). Defined. End bounded_search. Section bounded_search_alt_type. Context (X : Type) (e : nat <~> X) (P : X -> Type) (P_dec : forall x, Decidable (P x)) (P_inhab : hexists P). (** Bounded search works for types equivalent to the naturals even without full univalence. *)
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P

{x : X & P x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P

{x : X & P x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type

{x : X & P x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)

{x : X & P x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)

hexists P'
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P'_inhab: hexists P'
{x : X & P x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)

hexists P'
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P_inhab: {x : _ & P x}

hexists P'
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P_inhab: {x : _ & P x}

{x : _ & P' x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P_inhab: {x : _ & P x}
x: X
p: P x

{x : _ & P' x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P_inhab: {x : _ & P x}
x: X
p: P x

P' (e^-1 x)
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P_inhab: {x : _ & P x}
x: X
p: P x

P (e (e^-1 x))
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P_inhab: {x : _ & P x}
x: X
p: P x

P x
exact p.
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P'_inhab: hexists P'

{x : X & P x}
X: Type
e: nat <~> X
P: X -> Type
P_dec: forall x : X, Decidable (P x)
P_inhab: hexists P
P':= fun n : nat => P (e n): nat -> Type
P'_dec:= fun n : nat => P_dec (e n) : Decidable (P' n): forall n : nat, Decidable (P' n)
P'_inhab: hexists P'
n: nat
p': P' n

{x : X & P x}
exact ((e n); p'). Defined. End bounded_search_alt_type.