Zulip Chat Archive
Stream: new members
Topic: How to define the set of all functions between two sets?
Justus Willbad (Dec 07 2024 at 16:50):
I want to do algebra in Lean for formulating some simple new mathematical theorems. But I don't yet know the syntax and commands of Lean.
How can I formulate the following mathematical objects, the theorem and its proof in Lean?
Let
sets,
,
,
the set of all functions out of into ,
.
Theorem:
Until now, I have only
import Mathlib
variable (X : Type*)
variable (Y : Type*)
variable (X1 : Set X)
variable (Y1 : Set Y)
but don't know how to proceed.
Daniel Weber (Dec 07 2024 at 16:54):
Is F1 docs#Set.MapsTo ?
Justus Willbad (Dec 07 2024 at 17:04):
I don't know how to use things like X x Y, Set.MapsTo and Set.powerset.
Eric Wieser (Dec 07 2024 at 17:07):
What exactly does "A function in " mean?
Eric Wieser (Dec 07 2024 at 17:07):
Does it mean functions from to ? Or functions from to ?
Daniel Weber (Dec 07 2024 at 17:07):
What is ? Isn't that always ?
Eric Wieser (Dec 07 2024 at 17:08):
(deleted)
Daniel Weber (Dec 07 2024 at 17:10):
Is this what you want?
import Mathlib
variable (X : Type*)
variable (Y : Type*)
variable (X₁ : Set X)
variable (Y₁ : Set Y)
example (f : X → Y) (h : ∃ x₀ ∈ X₁, f x₀ ∉ Y₁) : ¬Set.MapsTo f X₁ Y₁ := by
intro hf
obtain ⟨x, hx⟩ := h
exact hx.2 <| hf hx.1
Justus Willbad (Dec 07 2024 at 17:25):
I corrected it: it is the set of all functions out of the set into the set .
Justus Willbad (Dec 07 2024 at 17:45):
Does
f : X → Y
mean , or ?
Notification Bot (Dec 07 2024 at 18:00):
This topic was moved here from #maths > How to use cross product and power set and make my proof? by Oliver Nash.
Oliver Nash (Dec 07 2024 at 18:01):
I'm afraid I don't quite know what is being asked but perhaps this may help:
import Mathlib
variable (X Y : Type*)
-- The type of functions `X → Y`
#check X → Y
-- The Cartesian product of two types:
#check X × Y
Oliver Nash (Dec 07 2024 at 18:04):
We also have a great resource which should help: https://leanprover-community.github.io/mathematics_in_lean/C01_Introduction.html
Dan Velleman (Dec 07 2024 at 18:30):
@Justus Willbad Note that in Lean, functions are not sets of ordered pairs. So you'll have to decide whether you want to state your theorem as a theorem about a function from to , in which case you can't treat as a set of ordered pairs, or as a theorem about a set of ordered pairs, in which case you can't treat as a function from to .
Dan Velleman (Dec 07 2024 at 18:35):
In response to one of your questions: f : X → Y
means that f
is a function from X
to Y
. It is not a function from a subset of X
to a subset of Y
. If a
has type X
, then f a
has type Y
. But f
is not a set of ordered pairs, so you can't say that (a, f a)
is an element of f
.
Justus Willbad (Dec 07 2024 at 18:51):
How can I define the set of all functions for all ?
Dan Velleman (Dec 07 2024 at 19:02):
You could do this:
def part_func_graphs (X Y : Type) : Set (Set (X × Y)) :=
{f : Set (X × Y) | ∀ (x : X) (y1 y2 : Y),
(x, y1) ∈ f ∧ (x, y2) ∈ f → y1 = y1}
According to this definition, if f ∈ part_func_graphs X Y
then f
is a set of ordered pairs, and in set theory it would be considered to be a function from a subset of X
to a subset of Y
. But in Lean, it is not a function, so you can't use function notation with f
. So, for example, if a
has type X
and b
has type Y
then you can write (a, b) ∈ f
, and you might think of that as meaning that b
is the result of applying f
to a
, but you can't write b = f(a)
, because Lean will not recognize f
as a function.
Edward van de Meent (Dec 07 2024 at 19:16):
Justus Willbad said:
How can I define the set of all functions for all ?
here's another approach:
import Mathlib
set_option autoImplicit false
variable {X Y ι: Type*} (X' : ι → Set X) (Y' : ι → Set Y)
def subset_funs := (i:ι) × (X' i → Y' i) -- it's actually a type rather than set, but to get a set out of this you can just use `Set.univ`
Matt Diamond (Dec 07 2024 at 21:33):
Justus Willbad said:
How can I define the set of all functions for all ?
import Mathlib
variable {X Y : Type*} {X_ : ℕ → Set X} {Y_ : ℕ → Set Y}
-- the type of all functions from X_i to Y_i
def f (i : ℕ) := X_ i → Y_ i
-- the set of all functions from X_i to Y_i
def f' (i : ℕ) := @Set.univ (X_ i → Y_ i)
(This uses ℕ as the index type, but you could also use a generic type as in Edward's solution above.)
Edit: I wonder if some of the confusion here is around trying to represent a function with an ambiguous domain. There's no need for a function in Lean (outside of partial functions) because the domain is guaranteed by the function's type. Are you trying to prove something about partial functions?
This feels like it might be an #xy problem...
Edit 2: This is closer to the wording of your question but I'm still not sure this is actually what you want:
import Mathlib
set_option autoImplicit false
variable {X Y : Type*} (X_ : ℕ → Set X) (Y_ : ℕ → Set Y)
-- a family of partial functions from X_i to Y_i
def F (i : ℕ) := { f : X →. Y | f.Dom = X_ i ∧ f.ran = Y_ i}
example
(i : ℕ) (f : X →. Y)
(x : X) (hx : x ∈ f.Dom)
(hy : (f x).get hx ∉ Y_ i)
: f ∉ F X_ Y_ i :=
by
rw [F, Set.nmem_setOf_iff, not_and_or]
right
contrapose! hy
rw [← hy, PFun.ran, Set.mem_setOf]
use x
exact Part.get_mem _
Justus Willbad (Dec 07 2024 at 23:40):
Matt Diamond schrieb:
I wonder if some of the confusion here is around trying to represent a function with an ambiguous domain. There's no need for a function in Lean (outside of partial functions) because the domain is guaranteed by the function's type. Are you trying to prove something about partial functions?
A set of functions with individual domains from is meant. Because the individual domain of a considered single function isn't known, I used the term .
I had expected that Lean can translate nearly all terms and concepts of basic pure mathematics, that means also the identity of functions and sets of ordered pairs.
Matt Diamond (Dec 07 2024 at 23:50):
I had expected that Lean can translate nearly all terms and concepts of basic pure mathematics
It certainly can... if what you're trying to do requires that the specific domain of a function is unknown then perhaps partial functions are what you're looking for.
Relevant docs: https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/PFun.html
Kevin Buzzard (Dec 07 2024 at 23:50):
The identification between functions and certain sets of ordered pairs as an equality is not a concept of basic pure mathematics, this is an artifact of what happens when mathematics is implemented in set theory. Lean is a functional programming language, and functions in lean are an undefined foundational concept, just like sets are an undefined foundational concept in set theory. In set theory, functions are defined in terms of sets. In Lean, sets are defined in terms of functions and the identification between functions and certain sets of ordered pairs is merely a bijection between two different things rather than being true by definition. Lean's foundations are type theory, not set theory.
You should not confuse mathematical concepts (like sets and functions) with implementation details which are foundation-specific (e.g. thinking that a function is a collection of ordered pairs).
Kevin Buzzard (Dec 07 2024 at 23:58):
An analogous situation would be if someone who was brought up on the type-theoretic foundations of mathematics started to use a set-theory-based theorem prover and incorrectly expected that a subset of a set X was equal to a function from X to the collection of true-false statements (sending the elements of the subset to "true" and the things not in the subset to "false"). The set theorists would point out that that these two concepts were not equal in set theory, but were merely in canonical bijection. In type theory these two concepts are identical. However we cannot deduce from this that the set-theory prover is not capable of handling "a concept of basic pure mathematics", because this is merely the implementation of sets in type theory.
Justus Willbad (Dec 08 2024 at 18:53):
I read somewhere "Set" in Lean means "subset". But now I read in the Lean documentation that it means "set".
I have to correct my code therefore to:
import Mathlib
variable (α β : Type*)
variable (X : Set α)
variable (Y : Set β)
But how can I create the variable ?
Ruben Van de Velde (Dec 08 2024 at 18:57):
That would also be a Set \a
with h : X1 \subset X
Edward van de Meent (Dec 08 2024 at 19:02):
in lean, we tend to only consider sets as subsets of "master sets". That is, X : Set α
really means X
is a set that is a subset of the "master set" α : Type*
. Depending on your situation, when you want to express , if you don't need to consider sets much larger than , you'd choose Y : Type*
to be a "master set", and have X:Set Y
be an arbitrary subset. on the other hand, if you need to have a larger set than exist, you can do as Ruben suggested and declare X Y : Set α
along with h : X ⊆ Y
Kevin Buzzard (Dec 08 2024 at 19:15):
Lean has two distinct things which the set theorists call sets -- one is types (an abstract collection of stuff) and one is subsets (of a fixed "master set" as Edward calls it, although a better term would be a "master type"). The collections of stuff are called X : Type
and the subsets of X
are called U : Set X
but note that U
is a term, not a type, so X
and U
behave differently in Lean's foundations for mathematics. If you're thinking set-theoretically then this is quite a good way to get confused about the basics here, because neither of these concepts (types, subsets) are a perfect fit for everything which a set theorist thinks about when they talk about sets (some of their sets are types and others are subsets); there is an art to doing the translation, and I would not recommend that you start focussing on this subtlety if you are a beginner to type theory, because you are quickly going to run into more statements which you might think are basic principles of mathematics but which turn out to be basic principles of set theory, and which might add to the confusion. In type theory, distinct types are always disjoint, for example.
Justus Willbad (Dec 08 2024 at 21:48):
How can I define X and X1 so that
#check X1 ⊆ X
gives no error?
Ruben Van de Velde (Dec 08 2024 at 21:50):
Backticks go the other way around
Ruben Van de Velde (Dec 08 2024 at 21:56):
import Mathlib
variable {α : Type*} {X X1 : Set α}
#check X1 ⊆ X
Justus Willbad (Dec 08 2024 at 22:22):
Both
#check X1 ⊆ X
#check X ⊆ X1
give no error, they give the type of the expression. That's not what I want.
How can I define in Lean that X1 is a subset of X and how can I check this?
Matt Diamond (Dec 08 2024 at 22:30):
Are you talking about a proof where you have a set X and you'd like to say "let X1 be an arbitrary subset of X"? Or is X1 defined in some other way?
Matt Diamond (Dec 08 2024 at 22:35):
If you're talking about a case where you want to prove something using the assumptions that you have a set X and a subset X1, then we would list those assumptions as arguments to the proof, in which case there's no need to "check" them since we've just provided proofs that they're true
something like:
theorem myTheorem {α : Type*} {X X1 : Set α} {h : X1 ⊆ X} : ... := sorry
with ...
replaced by the proposition you're trying to prove
Matt Diamond (Dec 08 2024 at 22:40):
if you want to prove several different theorems about these sets, then the most common way to do this is to introduce them using the variable
keyword, like so:
import Mathlib
variable {α : Type*} {X X1 : Set α} {h : X1 ⊆ X}
theorem myTheorem : ... := by
-- here we have access to X, X1, and the proof that X1 is a subset of X
sorry
Justus Willbad (Dec 09 2024 at 19:01):
I simply want to translate my mathematical objects and theorem from my first question into Lean and want to get a proof.
I expect I have to define a variable with and to define a variable that is the set of all functions out of into .
If , then is the set of all functions in , e. g. in the complex numbers.
Is there no other solution than to define a new variable h?
h : X1 ⊆ X
Kyle Miller (Dec 09 2024 at 19:05):
Justus Willbad said:
But I don't yet know the syntax and commands of Lean.
Justus Willbad said:
I don't know how to use things like X x Y, Set.MapsTo and Set.powerset.
I would suggest reading Mathematics in Lean https://leanprover-community.github.io/mathematics_in_lean/index.html
There's also a list of learning resources kept on the community website: https://leanprover-community.github.io/learn.html
https://adam.math.hhu.de/#/ has a "set theory game" that's like the Natural Number Game.
Alex Meiburg (Dec 09 2024 at 19:43):
It may be easier if you explain a bit what you'd like to prove, and then people can give more precise guidance on how to state (and then, prove) this in Lean. I tried reading your first message a couple times over, and - as written in English - it looks like a false theorem to me. You say,
Justus Willbad said:
Now I'm not sure if you mean
or
You might also mean something like
but then you have $f$ outside if the exists, and so I'm not sure what it's referring to.
The first option is an incorrect theorem. The statement $(\exists f\in F)$ does not always hold. If $Y$ is the empty set, then there can't be any functions from $X$ into $Y$, so there is no $f \in F$. So that's not a true statement.
The second one fails for the same reason. There doesn't always exist an $f \in F$.
And the third one is syntactically off.
Can you explain a bit more what exactly you want to show?
Justus Willbad (Dec 09 2024 at 21:19):
Theorem:
If there exist an and an so that and then .
I think I need to define, like in mathematics, all the mathematical objects in question first, formulate the theorem then and the proof at last.
Dan Velleman (Dec 09 2024 at 21:41):
Perhaps the theorem you are trying to state is:
example (X Y : Type) (X1 : Set X) (Y1 : Set Y)
(F1 : Set (X → Y)) (f : X → Y) (x0 : X)
(h1 : F1 = {f : X → Y | ∀ x ∈ X1, f x ∈ Y1})
(h2 : x0 ∈ X1) (h3 : f x0 ∉ Y1) : f ∉ F1
But I agree with Kyle: before you can prove this, you need to learn how to use Lean. Kyle has pointed you toward some good learning resources.
Alex Meiburg (Dec 09 2024 at 22:03):
Here are a few ways to state your theorem:
variable (X Y : Type*) (X1 : Set X) (Y1 : Set Y)
theorem your_theorem (f : X → Y) (x₀ : X) (hx₀ : x₀ ∈ X1) (hfx₀ : f x₀ ∉ Y1) :
let F₁ := { f : X → Y | ∀ x₀, x₀ ∈ X1 → f x₀ ∈ Y1 };
f ∉ F₁ := by
sorry
theorem your_theorem (X Y : Type*) (X1 : Set X) (Y1 : Set Y) (f : X → Y) (x₀ : X1) (h : f x₀ ∉ Y1) :
f ∉ { g : X → Y | ∀ (x₀ : X1), g x₀ ∈ Y1 } := by
sorry
This one has four sets that live in the same universe U. The funny ⟨x₀, hX1 x₀.2⟩
is saying: okay, to be able to plug x₀ into f, we need to show that it's in X. We are given that x₀ is in X1. So we combine the fact that x₀ is in X1 (which is x₀.2
) with the fact that X1 is a subset of X (which is hX1
) and this gives us a proof, hX1 x₀.2
. Then the combined value ⟨x₀, hX1 x₀.2⟩
wraps the value x₀ together with its proof that it's in X, so that we can plug it into f.
variable (U : Type*) --The universe that all of our sets, X and Y, live in
variable (X Y X1 Y1 : Set U) (hX1 : X1 ⊆ X) (hY1 : Y1 ⊆ Y)
theorem your_theorem (f : X → Y) (x₀ : X1) (h : ((f ⟨x₀, hX1 x₀.2⟩) : U) ∉ Y1) :
f ∉ { g : X → Y | ∀ (x₀ : X1), (g ⟨x₀, hX1 x₀.2⟩ : U) ∈ Y1 } := by
sorry
This last one just does everything in terms of the base universe, without any real typing:
variable (U : Type*) --The universe that both of ours sets, X and Y, live in
variable (X Y X1 Y1 : Set U) (hX1 : X1 ⊆ X) (hY1 : Y1 ⊆ Y)
variable (f : U →. U) (hf : f.Dom = X) (hf' : f.image f.Dom = Y)
--The notation U →. U means that f is a function from U to U, but not necessarily
-- a total function; its domain may be smaller than U. Then we add the hypothesis that the
-- domain of f is exactly equal to the set X.
theorem your_theorem (x₀ : U) (hx₀ : x₀ ∈ X) (h : (f x₀).get (by rwa [← hf] at hx₀) ∉ Y) :
f ∉ { g : U →. U | (g.Dom = X) ∧ (g.image g.Dom = Y) ∧ ∀ (x₀ : U), (g x₀).get (sorry) ∈ Y1 } := by
sorry
(I cheated a little on the last one, trying to make it more readable.)
Alex Meiburg (Dec 09 2024 at 22:04):
I agree about learning it first, but I also think that (if you're used to set theory) then trying to learn by doing the 'simple' math makes sense as an attempt. But, yes, it's maybe counterintuitive but the 'fundamentals' are not the easiest place to get started, because the real basics of systems of math can be different, while the consequences are essentially the same.
Justus Willbad (Dec 13 2024 at 21:12):
Now I understood the code below.
import Mathlib
theorem MyTheorem (X Y : Type) (X1 : Set X) (Y1 : Set Y) (F1 : Set (X → Y)) (f : X → Y) (x0 : X)
(h1 : F1 = {f : X → Y | ∀ x ∈ X1, f x ∈ Y1}) (h2 : x0 ∈ X1) (h3 : f x0 ∉ Y1) : f ∉ F1 := by sorry
But how can I code the proof of contradiction where I assume the negation of the conclusion of the theorem ( ¬ (f ∉ F1) ) and Lean concludes that f(x) ∈ Y1 follows, what is a contradiction to the preconditions?
Matt Diamond (Dec 13 2024 at 21:27):
If you write intro h4
it will add h4 : f ∈ F1
to the proof state and update the goal to False
. This is because f ∉ F1
is actually equivalent to f ∈ F1 → False
. More generally a proof by contradiction can be started by using the by_contra
tactic (or by_contra!
to automatically push negations inward).
Justus Willbad (Dec 14 2024 at 10:15):
intro h4
, intro
or intro assumption
work fine.
But how to proceed?
Alex Meiburg (Dec 14 2024 at 21:33):
Are you asking, just, how to write the proof? There are many possible ways to write this (fairly short) proof, and several people here could give you examples, but I'm guessing you want to learn how to write it yourself. I would suggest #tpil which will get you started on proof techniques
Alex Meiburg (Dec 14 2024 at 21:50):
As an example of a few very different solutions - spoilered in case you want to try more yourself first:
Four proofs
My point is that there are a lot of different ways to 'solve' this, the key thing is trying to see what works.
Justus Willbad (Dec 15 2024 at 17:21):
Thanks. Now I can work, play and learn with it.
It shows Lean seems suitable for my kind of mathematical problems.
Many many thanks to all of you.
Last updated: May 02 2025 at 03:31 UTC