Zulip Chat Archive
Stream: new members
Topic: Definite description operator
Patrick Johnson (Nov 16 2021 at 09:07):
Is there something like
def the {P : α → Prop} : (∃! (x : α), P x) → α := ...
to obtain the unique element for which a predicate is true? In Isabelle, there exists axiomatically defined function THE which does exactly this. In Lean, destructuring an existential quantifier works only if the goal is a proposition.
Kevin Buzzard (Nov 16 2021 at 09:09):
There's docs#classical.some. Uniqueness isn't necessary (and doesn't help in Lean's type theory, you still need to apply a classical axiom).
Patrick Johnson (Nov 16 2021 at 09:35):
I'm trying to implement something like this:
universes u v
variable {α : Sort u}
variable {β : Sort v}
def func (P : α → Prop) (f : α → β) (z : β) : β :=
/-
If exists unique `(x : α)` such that `P x`
then return `f x`
else return `z`
-/
Ruben Van de Velde (Nov 16 2021 at 09:46):
Something like
def func (P : α → Prop) (f : α → β) (z : β) : β :=
if h : (∃! (x : α), P x) then classical.choice h else z
(untested since it wasn't a #mwe)
Scott Morrison (Nov 16 2021 at 09:47):
import tactic.basic
variables {α β : Type*}
open_locale classical
noncomputable def func (P : α → Prop) (f : α → β) (z : β) : β :=
if h : ∃ x, P x then f (classical.some h) else z
Sebastien Gouezel (Nov 16 2021 at 10:04):
Also called docs#classical.epsilon
Stuart Presnell (Nov 16 2021 at 11:13):
Do you know about Martin Escardo's work on "searchable sets"? https://www.cs.bham.ac.uk/~mhe/papers/omniscient-journal-revised.pdf
By his definition, a set X is searchable if it has a function ε : (X → 2) → X such that for any p : (X → 2), iff p has a root (i.e. a value x ∈ X such that p x = 0) then ε p ∈ X is a root of p.
He's formalised this in Agda (https://www.cs.bham.ac.uk/~mhe/agda/CantorSearch.html) and shown, for example, that the one-point compactification of ℕ is searchable.
I don't know if any of this has been done in Lean yet. I made a bit of progress with it a couple of months ago.
Mario Carneiro (Nov 16 2021 at 11:24):
This notion kind of falls apart if the ambient logic is classical - every set is searchable
Eric Wieser (Nov 16 2021 at 11:34):
What is the type 2 there? is it fin 2 or something isomorphic like bool?
Stuart Presnell (Nov 16 2021 at 11:39):
It's defined here: https://www.cs.bham.ac.uk/~mhe/agda/Two.html
Mario Carneiro (Nov 16 2021 at 11:44):
it's bool
Stuart Presnell (Nov 16 2021 at 11:49):
Is it possible to work in a constructive setting in Lean and mathlib?
Mario Carneiro (Nov 16 2021 at 11:53):
it's possible, but I don't think these results hold. I am very suspicious of the claim that 2^N_infty has decidable equality by lean's interpretation
Eric Wieser (Nov 16 2021 at 12:04):
Stuart Presnell said:
Is it possible to work in a constructive setting in Lean and mathlib?
Yes, search for a post on Zulip that defines the @[intuit] attribute that requires a theorem to be constructive
Reid Barton (Nov 16 2021 at 12:14):
Mario Carneiro said:
it's possible, but I don't think these results hold. I am very suspicious of the claim that 2^N_infty has decidable equality by lean's interpretation
I think this one is okay (only needs funext), but the one about searching the Cantor set requires internalizing some Brouwerian uniform continuity hypothesis
Reid Barton (Nov 16 2021 at 12:15):
(I don't know if it's required, but that's what the Agda formalization does)
Mario Carneiro (Nov 16 2021 at 12:49):
I think you're right:
import data.bool data.nat.basic
def enat' := { x : ℕ → bool // ∀ i, x (i+1) → x i }
def inf : enat' := ⟨λ i, tt, λ _, id⟩
theorem enat'.ext (x : enat') (H : ∀ i, x.1 i) : x = inf :=
subtype.ext $ funext H
theorem enat'.mono (x : enat') (i j) (h : i ≤ j) : x.1 j → x.1 i :=
nat.le_induction id (λ n _ h h', h (x.2 _ h')) j h
instance : has_coe ℕ enat' :=
⟨λ n, ⟨λ i, i < n, λ i, by simp; exact lt_trans (lt_add_one i)⟩⟩
theorem enat'.eq_nat (x : enat') (n) (H : ¬ x.1 n) : ∃ i:ℕ, i ≤ n ∧ x = ↑i :=
begin
let m := nat.find ⟨n, H⟩,
refine ⟨m, nat.find_min' _ H, subtype.ext $ funext $ λ i, bool.coe_bool_iff.1 _⟩,
refine iff.trans _ (to_bool_iff _).symm,
by_cases h : i < m; simp [h],
{ exact decidable.not_not.1 ((@nat.find_min _ _ ⟨n, H⟩) _ h) },
{ simp at h,
rcases h with ⟨j, h₁, h₂⟩,
have := mt (enat'.mono x j i h₁),
simp at this,
exact this h₂ },
end
def selection (α : Type) :=
{ ε : (α → bool) → α // ∀ p : α → bool, p (ε p) → ∀ x, p x }
def eps (p : enat' → bool) : enat' :=
⟨λ n, to_bool $ ∀ k ≤ n, p k,
λ n, by simp; exact λ H k h, H _ (nat.le_succ_of_le h)⟩
def has_sel : selection enat' :=
⟨eps, λ p H n, begin
have : eps p = inf,
{ refine enat'.ext _ (λ n, _),
by_contra H',
rcases enat'.eq_nat _ _ H' with ⟨n, -, h⟩,
rw h at H,
have : ∀ i:ℕ, to_bool (∀ k ≤ i, p k) = to_bool (i < n) := λ i, congr_arg (λ x:enat', x.1 i) h,
have A := this n,
simp at A,
rcases A with ⟨i, h₁, h₂⟩,
rw ← eq_ff_eq_not_eq_tt at h₂,
rcases lt_or_eq_of_le h₁ with h₁ | rfl,
{ have B := this i,
simp [h₁] at B,
exact h₂ (B _ (le_refl _)) },
{ exact h₂ H } },
rw this at H,
by_contra h, apply h,
suffices : n = inf, { rwa this },
refine enat'.ext _ (λ i, _),
by_contra H',
rcases enat'.eq_nat _ _ H' with ⟨n, -, rfl⟩,
apply h,
have := congr_arg (λ x:enat', x.1 n) this,
simp [inf, eps] at this,
exact this _ (le_refl _)
end⟩
instance : decidable_eq (enat' → bool) :=
λ p q,
let x := eps (λ i, p i = q i) in
decidable_of_iff (p x = q x) ⟨λ H, begin
have : to_bool (p x = q x) → ∀ i, to_bool (p i = q i) := has_sel.2 (λ i, p i = q i),
simp at this,
exact funext (this H)
end, λ H, congr_fun H x⟩
Last updated: May 02 2025 at 03:31 UTC