Zulip Chat Archive
Stream: new members
Topic: Using attach with fold
Bhavik Mehta (Nov 20 2019 at 12:14):
I'm trying to prove that if z is disjoint from everything in A, then z is disjoint from the union of the things in A:
lemma disjoint_all {α} [decidable_eq α] {A : finset (finset α)} {z : finset α} (h : ∀ x ∈ A, disjoint x z) : disjoint (A.fold (∪) ∅ id) z := begin apply finset.induction_on A, rw finset.fold_empty, apply finset.disjoint_empty_left, intros a s h₂ k, rw [finset.fold_insert h₂], rw finset.disjoint_union_left, split, apply h, sorry, exact k end
It was all going really well, but I just need to show that the element we're inserting for the fold has come from A
- which should be obvious because we're folding over A
. (Not entirely sure why induction_on
isn't set up so that I can use this...) I'm pretty sure this is the sort of thing attach
is meant to fix, but letting B := A.attach
means it's no longer clear to me how the induction should work - if I do induction on B
how can I prove that the thing we get is equivalent?
Mario Carneiro (Nov 20 2019 at 12:18):
You might find it easier working with A.bind id
as the union of A, or perhaps ⋃ x ∈ A, ↑x
Mario Carneiro (Nov 20 2019 at 12:22):
You need to do induction generalizing h
:
lemma disjoint_all {α} [decidable_eq α] {A : finset (finset α)} {z : finset α} (h : ∀ x ∈ A, disjoint x z) : disjoint (A.fold (∪) ∅ id) z := begin revert h, apply finset.induction_on A, { intro, rw finset.fold_empty, apply finset.disjoint_empty_left }, { intros a s h₂ ih h, rw [finset.fold_insert h₂], rw finset.disjoint_union_left, split, { exact h _ (finset.mem_insert_self _ _) }, { exact ih (λ x hx, h _ (finset.mem_insert_of_mem hx)) } } end
Bhavik Mehta (Nov 20 2019 at 12:30):
I see, thanks!
Bhavik Mehta (Nov 20 2019 at 12:31):
I'm surprised that the generalisation trick works, but it makes sense! I can't use your latter suggestion for the union, since I do need finiteness in another part of my proof, but I'll have a go with bind
as well.
Reid Barton (Nov 20 2019 at 13:21):
Not sure how helpful this is, but I think the original proof is misguided. You shouldn't be using induction to prove this at all. Instead, you should have a lemma that tells you when something is an element of A.fold (∪) ∅ id
(which you will prove by induction).
Mario Carneiro (Nov 20 2019 at 13:22):
Using A.bind id
basically solves this problem, since it already has the requisite lemmas
Reid Barton (Nov 20 2019 at 13:22):
Then this proof becomes easy (intro a
, apply lemmas about what it means for a
to be an element of various finset
s).
Reid Barton (Nov 20 2019 at 13:24):
The difference is that knowing the elements of A.fold (∪) ∅ id
totally characterizes it as a set, so you won't have to do another induction for the next lemma like this one that you need.
Reid Barton (Nov 20 2019 at 13:24):
Yeah, I'm a little surprised there isn't already a definition like A.Union := A.bind id
.
Mario Carneiro (Nov 20 2019 at 13:27):
Me too, but really I don't think Union
will be able to provide better lemmas than bind
already has, when specialized to id
Bhavik Mehta (Nov 20 2019 at 13:27):
I think your criticism is fair, but this lemma was meant to be used when proving that the cardinality of the union is the sum of the cardinalities when the sets are all disjoint - so this seemed like the natural way of going about it. Perhaps with broader context using bind might turn out better, I will try further. I think I will need to characterise elements at some point anyway.
Mario Carneiro (Nov 20 2019 at 13:28):
that theorem generalizes to bind
indeed
Mario Carneiro (Nov 20 2019 at 13:29):
in fact it already exists - finset.card_bind
in algebra.big_operators
Bhavik Mehta (Nov 20 2019 at 13:31):
Oh! Big operators sounds very useful, thank you
Reid Barton (Nov 20 2019 at 13:35):
Yeah, mainly I think finset.bind id
is not that easily discoverable, especially because bind
is a notion which doesn't really appear in math.
Mario Carneiro (Nov 20 2019 at 13:35):
the name is only useful if you think in monads
Mario Carneiro (Nov 20 2019 at 13:36):
the notion of course does appear in math, but it's called "indexed union"
Reid Barton (Nov 20 2019 at 13:37):
Tangentially related story. I wanted to prove that if o : roption α
and a ∈ o
and b ∈ o
then a = b
. I didn't see it looking through data.pfun
so I defined mem_unique
and proved it.
Bhavik Mehta (Nov 20 2019 at 13:37):
Yeah I was familiar with the notion of bind, but my cardinality theorem felt like the maths proof should use induction
Reid Barton (Nov 20 2019 at 13:37):
That worked fine but then Lean gave an error on this later line:
theorem mem_unique : relator.left_unique ((∈) : α → roption α → Prop)
Reid Barton (Nov 20 2019 at 13:38):
It's actually exactly the same type but my eyes were looking for a ∈ o → b ∈ o → a = b
Bhavik Mehta (Nov 20 2019 at 13:38):
Also I don't think I saw theorems about cardinality of bind, but maybe I looked in the wrong place
Mario Carneiro (Nov 20 2019 at 13:39):
I think it has happened to me on at least three separate occasions that I prove a lemma and end up finding that it already exists because the name clashes
Mario Carneiro (Nov 20 2019 at 13:40):
I also wouldn't have thought to look there for it; I grepped for card_bind
Mario Carneiro (Nov 20 2019 at 13:41):
it makes sense in hindsight, because that's where finset.sum
is defined, which is required for the statement
Bhavik Mehta (Nov 20 2019 at 13:46):
It wasn't required for my statement :P But yeah this helps a lot, thanks both
Bhavik Mehta (Nov 20 2019 at 13:49):
Tangential: if my goal has something like id a
or (λ x, _) y
, sometimes lean doesn't unify it how I want - what's the tactic I need for simplifying those terms? (I know simp
would do it, but it feels like overkill and might screw up other terms)
Mario Carneiro (Nov 20 2019 at 13:50):
dsimp
Bhavik Mehta (Nov 20 2019 at 13:51):
Awesome thanks
Johan Commelin (Nov 20 2019 at 15:00):
the name is only useful if you think in monads
Make that CS monads, because the monads that do occur in maths use different terminology, I think.
Bhavik Mehta (Nov 21 2019 at 09:47):
You might find it easier working with
A.bind id
as the union of A, or perhaps⋃ x ∈ A, ↑x
Using bind
turned out to be a lot nicer, thank you!
Last updated: Dec 20 2023 at 11:08 UTC