/- Copyright (c) 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ module prelude public import Init.Data.Function public import Init.Classical public section namespace Lean.Grind open Function theorem _root_.Function.Injective.leftInverse {α β} (f : α → β) (hf : Injective f) [hα : Nonempty α] : ∃ g : β → α, LeftInverse g f := by classical cases hα; next a0 => let g : β → α := fun b => if h : ∃ a, f a = b then Classical.choose h else a0 exists g intro a have h : ∃ a', f a' = f a := ⟨a, rfl⟩ have hfa : f (Classical.choose h) = f a := Classical.choose_spec h have : Classical.choose h = a := hf hfa simp [g, h, this] noncomputable def leftInv {α : Sort u} {β : Sort v} (f : α → β) (hf : Injective f) [Nonempty α] : β → α := Classical.choose (hf.leftInverse f) theorem leftInv_eq {α : Sort u} {β : Sort v} (f : α → β) (hf : Injective f) [Nonempty α] (a : α) : leftInv f hf (f a) = a := Classical.choose_spec (hf.leftInverse f) a @[app_unexpander leftInv] meta def leftInvUnexpander : PrettyPrinter.Unexpander := fun stx => do match stx with | `($_ $f:term $_) => `($f⁻¹) | `($_ $f:term $_ $a:term) => `($f⁻¹ $a) | _ => throw () end Lean.Grind