Zulip Chat Archive
Stream: lean4
Topic: applying a function definition inside a proof
Michael (Jan 26 2024 at 10:46):
I want to complete a proof that for any function of three variables f : α × β × γ → δ, there is a function of a single variable f' : α → β → γ → δ that does the same thing, satisfying (((f' a) b) g) = f ⟨a,b,g⟩ for all a,b,g of types α, β, γ. This feels like it should be straightforward.
I can define the function I want, or I think I can:
let witness := fun a : α => fun b : β => fun g : γ => f ⟨a,b,g⟩
with that and some intro
s and an invocation of exists
, lean tells me my goal is to prove that witness a b g = f (a, b, g)
. witness exists in the context like so:
witness: α → β → γ → δ := fun a b g => f (a, b, g)
Should I be able to use this in a rewrite somehow? What's going wrong? How do I apply the definition of witness?
Eric Rodriguez (Jan 26 2024 at 10:50):
Can you put in the full code that is failing for you?
Eric Rodriguez (Jan 26 2024 at 10:50):
(#mwe)
Michael (Jan 26 2024 at 10:54):
I'm working inside a MIL installation, so for total completeness I'll include the file header:
import Mathlib.Data.Set.Lattice
import Mathlib.Data.Nat.Prime
import Mathlib.Data.Nat.Parity
import MIL.Common
section
variable {α β γ δ: Type*}
example : ∀ f : α × β × γ → δ,
∃ g : α → β → γ → δ,
∀ x : α, ∀ y : β, ∀ z : γ,
(((g x) y) z) = f ⟨x,y,z⟩ := by
intro f
let f_prime := fun x : α => (fun y : β => (fun z : γ => f ⟨x,y,z⟩))
exists f_prime
intro x y z
-- where do I go from here?
done
end
Eric Rodriguez (Jan 26 2024 at 10:55):
rfl
will close it! it's true by definition. if you want to unfold the let you can use unfold_let(s) f_prime
or simp only [f_prime]
Michael (Jan 26 2024 at 10:59):
Thanks!
I feel that rfl
is doing some work behind the scenes there that I'd like to know how to do manually. Can I manipulate this into a state where it tells me my goal is f (x, y, z) = f (x, y, z)
?
Eric Rodriguez (Jan 26 2024 at 11:03):
Do the unfold_let
or simp
calls I mentioned above work? This is a specific rule of equality called zeta-reduction.
Michael (Jan 26 2024 at 11:08):
simp only [f_prime]
closes the goal, just likerfl
unfold_lets f_prime
complains thatunfold_lets
is an unknown tacticunfold_let f_prime
sets the goal to(fun x y z => f (x, y, z)) x y z = f (x, y, z)
, which is a painfully obvious thing to have to prove, but hasn't quite gotten all the way tof (x, y, z) = f (x, y, z)
Eric Rodriguez (Jan 26 2024 at 11:16):
I'm surprised the first one closes the goal! simp
clearly did not obey the only
...
For the second two (sorry, I forgot whether there was an s
on the tactic or not): what you then need to do is called eta-reduction. Again, there is a tactic for this somewhere if you want to have control about it, but in most real-life cases you'll use simp
and it will eta reduce most things that you can. The correct tactic is eta_reduce
in this case.
here are some tactics that do the same sorts of things
Michael (Jan 26 2024 at 11:18):
Thanks again!
Ruben Van de Velde (Jan 26 2024 at 11:33):
If you use set
rather than let
, you can have it create a hypothesis that you can rewrite with
Yury G. Kudryashov (Jan 26 2024 at 17:41):
Eric Rodriguez said:
I'm surprised the first one closes the goal!
simp
clearly did not obey theonly
...
Currently, simp
unfolds local definitions unconditionally. See lean4#2682 for a discussion.
Last updated: May 02 2025 at 03:31 UTC