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: Dec 20 2023 at 11:08 UTC