Zulip Chat Archive
Stream: new members
Topic: How to not forget definition when unpacking pair?
Jakub Nowak (Aug 28 2025 at 22:36):
I have this weird problem. I have a function that returns Sigma, and I have a theorem that proves something about return value. The problem is, I don't know how I should use that function and the theorem.
Here's a short mwe, that demonstrates my problem, I used pair instead of Sigma, but its the same problem:
import Mathlib
def foo (n : ℕ) : ℕ × ℕ :=
⟨n, 2*n⟩
theorem foo_snd_even (n : ℕ) : Even (foo n).snd := by
unfold foo
simp_all
example := by
let ⟨a, b⟩ := foo 3
have : Even b := by
unfold b
-- Now, I can't prove `Even b`, because b "forgot" its value.
Kyle Miller (Aug 28 2025 at 22:40):
Options:
- If applicable, don't return a sigma, have multiple declarations. (Maybe this is related your walk+property question?)
- Use
let v := foo 3and work withv.1andv.2instead of destructuring. - Similar, but use
let a := v.1andlet b := v.2. - Use
let (eq := h) ⟨a, b⟩ := foo 3.
Jakub Nowak (Aug 28 2025 at 22:48):
Kyle Miller said:
Options:
- If applicable, don't return a sigma, have multiple declarations. (Maybe this is related your walk+property question?)
Yes, it's the function from that other question. I don't know how to avoid Sigma there. I've made mwe with sigma, as this should better represent my problem:
import Mathlib
def foo (n : ℕ) : Σ n, Vector ℕ (n + 1) := ⟨n+42, .replicate (n + 43) n⟩
theorem foo_snd_head (n : ℕ) : (foo n).snd.head = n := by
unfold foo
unfold Vector.head
simp_all
example := by
let ⟨n, vec⟩ := foo 3
-- I want to have this context:
-- n : ℕ
-- vec : Vector ℕ (n + 1)
-- h : vec.head = 3
have : vec.head = n := by
unfold vec
Jakub Nowak (Aug 28 2025 at 22:50):
For context, the functions mentioned are:
def odd_cycle_of_odd_walk [DecidableEq V] (p : G.Walk u u) : Σ v : V, G.Walk v v
theorem odd_cycle_of_odd_walk.isCycle [DecidableEq V]
(p : G.Walk u u) (hOdd : p.length.bodd) :
(odd_cycle_of_odd_walk p).snd.IsCycle
Should I declare them differently to avoid Sigma?
Kyle Miller (Aug 28 2025 at 22:52):
No, I'd stick with that sigma type. I just didn't know if you were using "sigma" loosely in a way that also encompassed subtypes.
Jakub Nowak (Aug 28 2025 at 22:56):
I've tried like this, but set created a new variable named vec, while this still refers to the old variable:
import Mathlib
def foo (n : ℕ) : Σ n, Vector ℕ (n + 1) := ⟨n+42, .replicate (n + 43) n⟩
theorem foo_snd_head (n : ℕ) : (foo n).snd.head = n := by
unfold foo
unfold Vector.head
simp_all
example := by
let vec := (foo 3).snd
have : vec.head = 3 := by
unfold vec
exact foo_snd_head 3
clear_value vec
set n := (foo 3).fst
-- I want to have this context:
-- n : ℕ
-- vec : Vector ℕ (n + 1)
-- h : vec.head = 3
Jakub Nowak (Aug 28 2025 at 22:58):
Kyle Miller said:
- Use
let v := foo 3and work withv.1andv.2instead of destructuring.- Similar, but use
let a := v.1andlet b := v.2.
I kinda don't like this solution, because it forces me to somehow name the pair.
Though, I guess I could do
let := foo 3
let a := this.1
let b := this.2
Jakub Nowak (Aug 28 2025 at 23:30):
Well, I finally got it, after like 4 different ideas failing. .-.
import Mathlib
def foo (n : ℕ) : Σ n, Vector ℕ (n + 1) := ⟨n+42, .replicate (n + 43) n⟩
theorem foo_snd_head (n : ℕ) : (foo n).snd.head = n := by
unfold foo
unfold Vector.head
simp_all
example := by
let (eq := eq) ⟨n, vec⟩ := foo 3
have h : (foo 3).snd.head = 3 := foo_snd_head 3
rw [eq] at h
simp only at h
clear eq
But that's way too convoluted for something that should be much simpler. ;_;
Isn't there something simpler?
Kyle Miller (Aug 28 2025 at 23:57):
Is destructuring foo 3 worth it? Do you save much by not writing foo 3?
Or, what's wrong with let loop := odd_cycle_of_odd_walk p and then working with loop?
If (eq := ...) works for you, that's pretty much the best you can do with let destructuring. I've been thinking about adding a feature to preserve the definitional equalities, but it's relatively low priority. It'd be neat though. People ask your question at least once a month. At least we have this eq syntax, which is just two months old.
Last updated: Dec 20 2025 at 21:32 UTC