Zulip Chat Archive
Stream: maths
Topic: flexible indices
Johan Commelin (Feb 20 2019 at 09:45):
I'm fooling around with sequences of groups. Here is an extract of some code:
import algebra.group group_theory.subgroup import category_theory.instances.groups import category_theory.functor_category import data.set.function universes v v₁ v₂ v₃ u u₁ u₂ u₃ -- declare the `v`'s first; see `category_theory.category` for an explanation namespace category_theory open set instances variables (C : Type u₁) [𝒞 : category.{v₁} C] include 𝒞 def sequence := ℤ ⥤ C namespace sequence instance : category (sequence C) := functor.category _ _ variables {C} (X : sequence C) def delta (i : ℤ) {j : ℤ} (h : i = j - 1 . obviously) : X.obj i ⟶ X.obj j := X.map $ begin rw auto_param_eq at h, rw h, tidy, end
Johan Commelin (Feb 20 2019 at 09:45):
What I am after is a nice definition of delta
Johan Commelin (Feb 20 2019 at 09:47):
It is the map X.obj i \hom X.obj (i+1)
but I want to use unification to replace i
with (i-1+1)
when necessary.
Johan Commelin (Feb 20 2019 at 09:51):
Currently this fails:
variable (i : ℤ) #check X.delta (i-1) ≫ X.delta i
Johan Commelin (Feb 20 2019 at 09:51):
Because the second X.delta
should be X.delta (i-1+1)
, which is ugly.
Johan Commelin (Feb 20 2019 at 09:59):
My goal is to make things like this typecheck:
variable (A : sequence Group) def is_complex := ∀ (i : ℤ), range (A.delta (i-1)) ⊆ ker (A.delta i)
Kenny Lau (Feb 20 2019 at 10:00):
(never mind)
Kenny Lau (Feb 20 2019 at 10:03):
also your code doesn't work because category_theory.instances.groups
doesn't exist
Johan Commelin (Feb 20 2019 at 10:38):
Yes, I know. It exists on my machine. It's a pity it doesn't yet exist in mathlib.
Johan Commelin (Feb 20 2019 at 11:04):
Here is category_theory/instances/groups.lean
:
/- Copyright (c) 2018 Johan Commelin. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin Introduce Group -- the category of groups. Currently only the basic setup. Copied from monoids.lean. -/ import category_theory.concrete_category import category_theory.fully_faithful import category_theory.adjunction import data.finsupp universes u v open category_theory namespace category_theory.instances /-- The category of groups and group morphisms. -/ @[reducible] def Group : Type (u+1) := bundled group instance (G : Group) : group G := G.str instance concrete_is_group_hom : concrete_category @is_group_hom := ⟨by introsI α ia; apply_instance, by introsI α β γ ia ib ic f g hf hg; apply_instance⟩ instance Group_hom_is_group_hom {G₁ G₂ : Group} (f : G₁ ⟶ G₂) : is_group_hom (f : G₁ → G₂) := f.2 instance : has_one Group := ⟨{ α := punit, str := by tidy }⟩ /-- The category of commutative groups and group morphisms. -/ @[reducible] def CommGroup : Type (u+1) := bundled comm_group instance (x : CommGroup) : comm_group x := x.str @[reducible] def is_comm_group_hom {α β} [comm_group α] [comm_group β] (f : α → β) : Prop := is_group_hom f instance concrete_is_comm_group_hom : concrete_category @is_comm_group_hom := ⟨by introsI α ia; apply_instance, by introsI α β γ ia ib ic f g hf hg; apply_instance⟩ instance CommGroup_hom_is_comm_group_hom {R S : CommGroup} (f : R ⟶ S) : is_comm_group_hom (f : R → S) := f.2 namespace CommGroup /-- The forgetful functor from commutative groups to groups. -/ def forget_to_Group : CommGroup ⥤ Group := concrete_functor (by intros _ c; exact { ..c }) (by introsI _ _ _ _ f i; exact { ..i }) instance : faithful (forget_to_Group) := {} instance : has_one CommGroup := ⟨{ α := punit, str := by tidy }⟩ end CommGroup end category_theory.instances
Kevin Buzzard (Feb 20 2019 at 12:23):
What's the story as to why it's not in mathlib? My MSc student was going to use categories for doing schemes but we decided it wasn't a good idea because categories seemed to be happening too slowly
Johan Commelin (Feb 20 2019 at 14:51):
The story is that nobody copied the file about the category of monoids and did a search-replace s/monoid/group/
. That's all.
Johan Commelin (Feb 26 2019 at 12:13):
My goal is to make things like this typecheck:
variable (A : sequence Group) def is_complex := ∀ (i : ℤ), range (A.delta (i-1)) ⊆ ker (A.delta i)
Does anyone have an idea how to make this work?
I think writing A.delta (i-1+1)
is very very ugly.
Mario Carneiro (Feb 26 2019 at 12:14):
Why not use +1 instead of -1?
Mario Carneiro (Feb 26 2019 at 12:14):
it's over all integers
Mario Carneiro (Feb 26 2019 at 12:15):
Another way to flexify the indices for dependent types is to have an equality argument i+1 = j
and have i
on the left and j
on the right
Johan Commelin (Feb 26 2019 at 12:15):
But can we make it transparent?
Mario Carneiro (Feb 26 2019 at 12:15):
don't know what you intend to do with this
Johan Commelin (Feb 26 2019 at 12:16):
Why not use +1 instead of -1?
I could do that here. But I think this issue will show up elsewhere as soon as we start looking in a broader range of indices.
Johan Commelin (Feb 26 2019 at 12:16):
don't know what you intend to do with this
For starters we could try to prove the snake lemma (-;
Mario Carneiro (Feb 26 2019 at 12:17):
More generally, you want an inductive family describing the allowable index combinations
Mario Carneiro (Feb 26 2019 at 12:17):
In this case it is just inductive next : nat -> nat -> Prop | mk (i) : next i (i+1)
Johan Commelin (Feb 26 2019 at 12:18):
Hmm, how do I use next
?
Johan Commelin (Feb 26 2019 at 12:18):
Should I put that in my definition of delta
?
Mario Carneiro (Feb 26 2019 at 12:18):
def is_complex := ∀ (i j : ℤ), next i j -> range (A.delta i) ⊆ ker (A.delta j)
Mario Carneiro (Feb 26 2019 at 12:19):
or are you looking somewhere else?
Johan Commelin (Feb 26 2019 at 12:22):
Aah, ok
Johan Commelin (Feb 26 2019 at 12:23):
But that means I have 3 explicit arguments. So I can't just write A.delta i
Johan Commelin (Feb 26 2019 at 12:24):
I would like to tell Lean: "If unification knows what j
should be, use that. Otherwise, default to (i+1)
."
Mario Carneiro (Feb 26 2019 at 12:24):
Yeah, I think so... it's just like with categories, you want the objects to be there before the morphisms, rather than extracting objects as the dom/cod of morphisms
Johan Commelin (Feb 26 2019 at 12:25):
And after that I say to Lean: "Hey, 95% of the time you can prove next i j
by mk i
. Otherwise, simplify the expression for j
before doing that."
Johan Commelin (Feb 26 2019 at 12:25):
And so in 99% of the cases I can get away with just writing A.delta i
. And in 1% of the cases I might to actually work on the proof obligation...
Johan Commelin (Feb 26 2019 at 12:26):
If something like that can work, that would be cool.
Mario Carneiro (Feb 26 2019 at 12:26):
So is_complex
is actually talking about three objects....
Mario Carneiro (Feb 26 2019 at 12:27):
def is_complex := ∀ {{i j k : ℤ}} (n1: next i j) (n2 : next j k), range (A.delta n1) ⊆ ker (A.delta n2)
Kenny Lau (Feb 26 2019 at 12:27):
what is {{}}?
Mario Carneiro (Feb 26 2019 at 12:28):
half implicit, too lazy to unicode
Mario Carneiro (Feb 26 2019 at 12:28):
I think it is working ascii notation though
Kenny Lau (Feb 26 2019 at 12:28):
what is half implicit?
Mario Carneiro (Feb 26 2019 at 12:28):
not applied unless you apply an argument after them
Mario Carneiro (Feb 26 2019 at 12:29):
like in the definition of subset
Kenny Lau (Feb 26 2019 at 12:29):
:o
Johan Commelin (Feb 26 2019 at 12:32):
Hmm, but I think you are working on the wrong part. The definition of delta
has to change.
Johan Commelin (Feb 26 2019 at 12:33):
is_complex
is just an example of something that doesn't typecheck with the current definition of delta
.
Mario Carneiro (Feb 26 2019 at 12:33):
I did that... A.delta {i j} n1
Johan Commelin (Feb 26 2019 at 12:33):
Ooh, right. Ok.
Johan Commelin (Feb 26 2019 at 12:33):
But that means I can't write A.delta i
, can I?
Mario Carneiro (Feb 26 2019 at 12:33):
although possibly i
and j
shouldn't be implicit - this will print a bit weird if n1
is not a simple term
Mario Carneiro (Feb 26 2019 at 12:34):
No, I'm claiming that's a bad idea
Mario Carneiro (Feb 26 2019 at 12:35):
If you don't have the objects lying around already, you can use +1 and -1 to access next elements, but if you ever want to link two of them together you need a variable for the common object
Mario Carneiro (Feb 26 2019 at 12:35):
is_complex
is a good example of this - j
is mediating the connection between i
and k
Mario Carneiro (Feb 26 2019 at 12:35):
I know this looks silly but it's a DTT thing
Johan Commelin (Feb 26 2019 at 12:37):
This will be hard to explain to mathematicians...
Johan Commelin (Feb 26 2019 at 12:37):
Why can't automation help us here?
Mario Carneiro (Feb 26 2019 at 12:38):
because DTT doesn't like it when you try to prove defeqs
Johan Commelin (Feb 26 2019 at 12:38):
If Lean figures out j
by unification, that's cool. If it didn't: use i+1
.
Mario Carneiro (Feb 26 2019 at 12:38):
You want all rewriting and stuff to happen in prop land
Mario Carneiro (Feb 26 2019 at 12:38):
but delta
is data, so it needs a general type
Mario Carneiro (Feb 26 2019 at 12:39):
it's not a question of figuring out the expressions, it's about making i+1-1
defeq to i
Johan Commelin (Feb 26 2019 at 12:44):
Hmmm, I think that I wouldn't mind if automation could also help us with providing data, and not only proofs.
Patrick Massot (Feb 26 2019 at 12:46):
I don't know if automation is the right word here, but it's pretty clear that proof assistants that require using this next
trick are not ready for use by mathematicians
Mario Carneiro (Feb 26 2019 at 12:46):
It's about wrangling DTT issues
Mario Carneiro (Feb 26 2019 at 12:47):
You are causing equality of integers to propagate to equality of types, which is bad
Patrick Massot (Feb 26 2019 at 12:47):
I understand. It means we need either better wrangling tools or a better foundational framework. I'm not saying this is an easy question
Mario Carneiro (Feb 26 2019 at 12:47):
I am in favor of both of those
Patrick Massot (Feb 26 2019 at 12:48):
What a nice thesis topic!
Johan Commelin (Feb 26 2019 at 12:49):
Mario, I agree with Patrick. I understand the issues. But the issues are non-mathematical, so they should be hidden. Somehow...
Johan Commelin (Feb 26 2019 at 12:50):
In the end, DTT should be our assembly language. We want a Python on top of that.
Patrick Massot (Feb 26 2019 at 12:50):
You already have it: the tactic language
Mario Carneiro (Feb 26 2019 at 12:50):
DTT is a horrible assembly language
Mario Carneiro (Feb 26 2019 at 12:51):
it's like javascript - high level ish but used for low level things
Mario Carneiro (Feb 26 2019 at 12:51):
I know a much better proof assembly language, and it starts with M
Johan Commelin (Feb 26 2019 at 12:52):
Sure, but is there a Python on top of your M?
Johan Commelin (Feb 26 2019 at 12:52):
One that will let me define functors on objects and morphisms, and check that they are lawful in a completely transparent way?
Mario Carneiro (Feb 26 2019 at 12:58):
Proof automation is hard, and no one has a perfect solution. Lean could have the stuff you are talking about if it didn't have to fight its own foundation
Johan Commelin (Feb 26 2019 at 13:00):
What do you mean with that last sentence?
Mario Carneiro (Feb 26 2019 at 13:02):
You could just rewrite i+1-1 = i
with the simplifier and we would all be happy
Johan Commelin (Feb 26 2019 at 13:22):
Sure, that's exactly what I would want. But what do you mean with:
Lean could have the stuff you are talking about if it didn't have to fight its own foundation
Is that an issue that can be solved, or is this fight some intrinsic DTT issue?
Mario Carneiro (Feb 26 2019 at 14:14):
it's an intrinsic DTT issue
Mario Carneiro (Feb 26 2019 at 14:14):
defeq matters, and tactics can't change that
Johan Commelin (Feb 26 2019 at 14:14):
Aah, so Lean will always be fighting its foundations.
Johan Commelin (Feb 26 2019 at 14:17):
So, why don't we write a Python-like on top of your assembly M? Do you think we would get further into state-of-the-art research level maths with a Python-like on top of M? Or is Lean just the best there is, and are we stuck with a system that fights its own foundations?
Mario Carneiro (Feb 26 2019 at 14:17):
You are hitting surprisingly close to my current research areas
Johan Commelin (Feb 26 2019 at 14:18):
That only means that I've been paying attention to what you've been saying on Zulip over the last couple of months (-;
Mario Carneiro (Feb 26 2019 at 14:19):
I think that the killer combo is untyped foundations (ZFC like) + good tactic language + metaprogramming
Mario Carneiro (Feb 26 2019 at 14:20):
as you can see lean has 2 out of 3
Mario Carneiro (Feb 26 2019 at 14:21):
Isabelle gets pretty close, but it's not quite untyped foundations and as a result they are stuck with some things
Johan Commelin (Feb 26 2019 at 14:21):
Hmmm, so why again did you give my colleagues that nlab blogpost on why type theory p0wns set theory?
Mario Carneiro (Feb 26 2019 at 14:22):
I didn't write it, and I don't really endorse most of nLab philosophy
Mario Carneiro (Feb 26 2019 at 14:22):
but it's a good place to find the philosophy when you want it
Johan Commelin (Feb 26 2019 at 17:56):
Why not use +1 instead of -1?
So, for is_complex
I could do this. But for is_exact_at (i : int)
you need to reference A.obj (i-1)
at some point. You can't avoid the subtraction. (Unless you want to break with the indexing conventions, but that will just move the pain to the next page, where it will hit you twice as hard.)
Mario Carneiro (Feb 26 2019 at 18:01):
with the next
thing, you can say \ex j, next i j /\ ...
Mario Carneiro (Feb 26 2019 at 18:02):
but depending on what you want to say just plain A.obj (i-1)
might be best
Johan Commelin (Feb 26 2019 at 18:05):
So what is actually the benefit of next
? Why can't I just write a condition (h : j = i+1)
in the definition of delta
?
Mario Carneiro (Feb 26 2019 at 18:05):
you can
Mario Carneiro (Feb 26 2019 at 18:05):
but it generalizes to more complicated index structures
Johan Commelin (Feb 26 2019 at 18:09):
I see...
Mario Carneiro (Feb 26 2019 at 18:09):
I'm not saying you should necessarily use it here
Reid Barton (Feb 26 2019 at 18:11):
Another example of this index business is (commutative / graded commutative) graded algebras
Reid Barton (Feb 26 2019 at 18:12):
where multiplication is a family of operations and is supposed to be, say, associative, but stating that depends on the associativity of addition of indices
Johan Commelin (Feb 26 2019 at 18:13):
@Mario Carneiro Do you know how mathematicians write the predicate is_complex
?
They just write A.delta \circ A.delta = 0
Now, I thought I should write \forall i, A.delta i \circ A.delta (i-1) = 0
. But you are telling me I need 3 explicit arguments... it will probably take my psyche some time to adjust.
Johan Commelin (Feb 26 2019 at 18:15):
@Reid Barton Yeah, I was thinking about those a bit. (Because you can of course also do sequences as graded modules with a differential of degree 1.) I really don't know if the A_i
should be an indexed family of types or an indexed family of subsets... We will probably need both...
Sebastien Gouezel (Feb 26 2019 at 19:15):
Mario Carneiro Do you know how mathematicians write the predicate
is_complex
?
They just writeA.delta \circ A.delta = 0
You can also write it in this way in Lean if you think of the total space of your complex as a group/module/whatever (with an additional filtered structure), and A.delta
as a group/module/whatever morphism that, incidentally, happens to respect the filtration.
Johan Commelin (Feb 26 2019 at 19:23):
Yes, but I fear that will make talking about homogeneous elements a lot more awkward...
Last updated: Dec 20 2023 at 11:08 UTC