Zulip Chat Archive

Stream: new members

Topic: How to use Set.image and have prop that says elem is of Set


An Qi Zhang (Jun 01 2025 at 00:16):

Hello! When using Set.image to map from a Set "x" to another Set "y" with a function "f", I was wondering if there's a way to get a prop that says the element f works on is of x?

Here's a MWE to illustrate:

import Mathlib

namespace MWE

inductive Nats
| order : Nat  Nat  Nats
| one : Nat  Nats

abbrev SetNats := Set Nats

def Nats.before : Nats  Nat  Prop
| ns, n =>
  match ns with
  | order _ n₂ => n = n₂
  | one _ => false

def SetNats.before (x : SetNats) (n : Nat) : SetNats := {nats  x | nats.before n}

lemma SetNats.mem_before (x : SetNats) (n : Nat) :  m  x.before n, m  x  m.before n := by
  simp [SetNats.before]

def Nats.pred (nats : Nats) (n : Nat) : (nats_is_order : nats.before n)  Nat
| nats_is_order =>
  match nats with
  | .order n₁ n₂ =>
    if h : n₂ = n then n₁
    /- Is this a good approach? Or is there a better approach, that will let lean eliminate
    the other branch (else) automatically? -/
    else absurd nats_is_order (by simp_all [Nats.before])

def SetNats.predecessor (x : SetNats) (n : Nat) : Set Nat :=
  let ordered := x.before n
  /- Need to state variable `nats` is in `ordered` somehow?
  Or is there a better approach? -/
  ordered.image (λ nats => nats.pred n ((ordered.mem_before n) nats))

Kenny Lau (Jun 01 2025 at 00:29):

import Mathlib

namespace MWE

inductive Nats
| order : Nat  Nat  Nats
| one : Nat  Nats

abbrev SetNats := Set Nats

def Nats.before : Nats  Nat  Prop
| ns, n =>
  match ns with
  | order _ n₂ => n = n₂
  | one _ => false

def SetNats.before (x : SetNats) (n : Nat) : SetNats := {nats  x | nats.before n}

lemma SetNats.mem_before (x : SetNats) (n : Nat) :  m  x.before n, m  x  m.before n := by
  simp [SetNats.before]

/-
def Nats.pred : Π (nats : Nats) (n : Nat) (nats_is_order : nats.before n), Nat
| (order n₁ _), _, rfl => n₁
-/

def Nats.pred : Π (nats : Nats) (n : Nat), Nat
| (order n₁ n₂), n₃ => n₁
| (one n₁), n₃ => n₁

def SetNats.predecessor (x : SetNats) (n : Nat) : Set Nat :=
  let ordered := x.before n
  /- Need to state variable `nats` is in `ordered` somehow?
  Or is there a better approach? -/
  ordered.image (λ nats => nats.pred n)

@An Qi Zhang just for the first question, the answer is to include the variables to the right of the colon, i.e. I changed (nats : Nats) (n : Nat) : (nats_is_order : nats.before n) → Nat to Π (nats : Nats) (n : Nat) (nats_is_order : nats.before n), Nat.

But you'll notice that I commented that solution out, because for your next question, the philosophy is that it's always better to define a full function with junk values than to define a partial function, because then you wouldn't have to supply proofs. This is why in Lean, 1 / 0 = 0:

import Mathlib

example : (1 / 0 : ) = 0 := by rw [Rat.div_def, Rat.inv_zero, one_mul]

Kenny Lau (Jun 01 2025 at 00:30):

"full function with junk values" means a function that does not take in any proofs as the input

Kenny Lau (Jun 01 2025 at 00:30):

and returns incorrect result outside the "domain" specified


Last updated: Dec 20 2025 at 21:32 UTC