Zulip Chat Archive

Stream: new members

Topic: finset.univ_eq_set_univ_to_finset


Alex Zhang (Jul 17 2021 at 15:49):

I wrote

variables (I : Type*) [fintype I]
lemma finset.univ_eq_set_univ_to_finset :
finset.univ = (@set.univ I).to_finset :=
by {simp [finset.univ, set.to_finset], ext, simp, exact fintype.complete a}

Should this be a simplification lemma? If so, which direction is the right direction to simply?

Eric Wieser (Jul 17 2021 at 15:54):

Did you try by library_search to see if we already have this?

Eric Wieser (Jul 17 2021 at 15:55):

docs#set.to_finset_univ or docs#set.univ_to_finset would be my immediate guess

Eric Wieser (Jul 17 2021 at 15:56):

So yes, this should be and already is a simp lemma

Eric Wieser (Jul 17 2021 at 15:57):

I think your mistake here was simplifying away the definitions before asking lean if the result was already proven

Alex Zhang (Jul 17 2021 at 16:42):

I think they are not the same thing actually,

lemma finset.univ_eq_set_univ_to_finset :
finset.univ = (@set.univ I).to_finset :=
set.to_finset_univ.symm

won't able to close the goal.

Eric Wieser (Jul 17 2021 at 16:51):

With what error?

Alex Zhang (Jul 17 2021 at 16:59):

type mismatch, term
  set.to_finset_univ.symm
has type
  @finset.univ ?m_1 ?m_2 =
    @set.to_finset ?m_1 (@set.univ ?m_1)
      (@subtype.fintype ?m_1 (λ (x : ?m_1), x  @set.univ ?m_1) (λ (a : ?m_1), @set.univ_decidable ?m_1 a) ?m_2)
but is expected to have type
  @finset.univ I _inst_1 = @set.to_finset I (@set.univ I) (@set.fintype_univ I _inst_1)

Eric Wieser (Jul 17 2021 at 17:03):

Can you give a mwe with imports?

Eric Wieser (Jul 17 2021 at 17:04):

It might succeed / fail depending on what you have imported

Eric Wieser (Jul 17 2021 at 17:04):

by convert set.to_finset_univ.symm may also close it

Alex Zhang (Jul 17 2021 at 17:54):

That is weird, Eric. Why should this happen? @Eric Wieser
If I do

import tactic
import data.fintype.card
variables (I : Type*) [fintype I]
lemma finset.univ_eq_set_univ_to_finset :
finset.univ = (@set.univ I).to_finset :=
set.to_finset_univ.symm

then it fails, but it will succeed if I remove the import tactic.

Eric Wieser (Jul 17 2021 at 18:00):

Can you narrow down the import that makes it fail?

Eric Wieser (Jul 17 2021 at 18:01):

import tactic imports tactic.default, which is just a file full of imports

Eric Wieser (Jul 17 2021 at 18:01):

You can paste those all in, and delete them one at a time until it works

Kyle Miller (Jul 17 2021 at 18:06):

tactic imports data.set.finite, which provides the instance fintype_univ, which conflicts with subtype.fintype for set.univ.

Kyle Miller (Jul 17 2021 at 18:07):

import tactic
import data.fintype.card

local attribute [-instance] set.fintype_univ
lemma finset.univ_eq_set_univ_to_finset (I : Type*) [h : fintype I] :
finset.univ = (@set.univ I).to_finset :=
set.to_finset_univ.symm

Kyle Miller (Jul 17 2021 at 18:07):

Maybe set.to_finset_univ should be changed to take a [fintype set.univ] instance

Eric Wieser (Jul 17 2021 at 18:13):

Is there any reason for docs#set.fintype_univ to exist?

Eric Wieser (Jul 17 2021 at 18:14):

If not, it seems easier to remove it than to add that argument

Kyle Miller (Jul 17 2021 at 18:19):

I don't see why set.fintype_univ exists, since set.univ is a decidable predicate. Only thing I can think of is that subtype.fintype breaks the set API slightly, since it treats sets as predicates directly.

(Though it still might be worth fixing set.to_finset_univ, since it breaks the ideal rule that instances used in a lemma should all be given as arguments.)

Eric Wieser (Jul 17 2021 at 18:48):

I thought I fixed docs#subtype.fintype to not abuse the set API

Kyle Miller (Jul 17 2021 at 18:51):

@Alex Zhang The reason by convert works is that it makes use of the fact that fintype is a subsingleton (if you have two fintype instances, while they might not be definitionally equal, they are at least provably equal). There are two instances for fintype (@set.univ I) floating around, and set.to_finset_univ has picked up on a different instance than (@set.univ I).to_finset.

Just for completeness, here is how to get it to work (better to not mess around with removing attributes):

import tactic
import data.fintype.card

lemma finset.univ_eq_set_univ_to_finset (I : Type*) [h : fintype I] :
  finset.univ = (@set.univ I).to_finset :=
by convert set.to_finset_univ.symm

Kyle Miller (Jul 17 2021 at 18:53):

@Eric Wieser I'm not sure what counts as abuse exactly. I was just going on the fact that p here is not a set:

instance subtype.fintype (p : α  Prop) [decidable_pred p] [fintype α] : fintype {x // p x} :=
fintype.subtype (univ.filter p) (by simp)

(If this is an abuse, I think it's an ok one, but that's just my opinion. I think the fact that sets are predicates is a fundamental fact about them.)

Eric Wieser (Jul 17 2021 at 19:08):

Doesn't it infer that with p = (∈ s)?

Eric Wieser (Jul 17 2021 at 19:09):

Interestingly we have docs#set_fintype right below that, but it's not an instance

Kyle Miller (Jul 17 2021 at 19:22):

Eric Wieser said:

Doesn't it infer that with p = (∈ s)?

Oh, my mistake -- thanks.

Alex Zhang (Jul 17 2021 at 19:24):

Eric Wieser said:

I thought I fixed docs#subtype.fintype to not abuse the set API

Eric, what do you mean by "not abuse the set API" here?

Eric Wieser (Jul 17 2021 at 19:24):

A lot of stuff used to behave the way you were claiming though - I changed it in the last week or so.

Eric Wieser (Jul 17 2021 at 19:25):

By abuse, I mean using s x instead x ∈ s when s : set α

Alex Zhang (Jul 17 2021 at 19:37):

So is the current solution for working on relevant things to block an instance?

Alex Zhang (Jul 17 2021 at 19:38):

Is local attribute [-instance] set.fintype_univ the right thing supposed to do now?

Alex Zhang (Jul 17 2021 at 19:38):

and also do local attribute [instance] set_fintype perhas?

Alex Zhang (Jul 17 2021 at 19:39):

@Eric Wieser @Kyle Miller

Alex Zhang (Jul 17 2021 at 19:43):

I asked how to block things in another post as I had felt that something was going wrong at that point before encounter this specific issue when working on my own project.

Kyle Miller (Jul 17 2021 at 20:06):

Alex Zhang said:

Is local attribute [-instance] set.fintype_univ the right thing supposed to do now?

No, you should use by convert like in the code block in one of my last comments (at least until these overlapping instances are possibly fixed).

Alex Zhang (Jul 17 2021 at 20:13):

There is no mismatch of instances constructed between set_fintype and subtype.fintype right? @Kyle Miller

Kyle Miller (Jul 17 2021 at 20:30):

@Alex Zhang Correct, those are definitionally equal.

Alex Zhang (Jul 17 2021 at 20:41):

I note there is one mismatch : set_fintype uses [_inst_1 : decidable_pred p], subtype.fintype uses [_inst_1 : decidable_pred p]. I suggest to match them.
Which condition is a better form?

Eric Wieser (Jul 17 2021 at 21:19):

Did you mean to type those as the same in both cases?

Alex Zhang (Jul 17 2021 at 21:43):

Yes!

Eric Wieser (Jul 17 2021 at 21:54):

Then in what way are they a mismatch?

Alex Zhang (Jul 17 2021 at 22:03):

sorry, there is a typo, I fixed it.

Eric Wieser (Jul 17 2021 at 22:09):

decidable_pred expects a p : α → Prop, but s : set α. To get the right type, we need (∈ s) : α → Prop.

Eric Wieser (Jul 17 2021 at 22:10):

Using decidable_pred s directly is telling lean to unfold set, which you should never do

Alex Zhang (Jul 17 2021 at 22:19):

What I am saying is that subtype.fintype uses [_inst_1 : decidable_pred p] as a condition, I suggest to rewrite it to [_inst_2 : decidable_pred (λ (_x : α), _x ∈ s)]

Eric Wieser (Jul 17 2021 at 22:27):

But subtype.fintype has no s argument, so that second version doesn't make sense!

Alex Zhang (Jul 17 2021 at 22:28):

You use p.

Eric Wieser (Jul 17 2021 at 22:28):

You can't use on p because it's not a set

Alex Zhang (Jul 17 2021 at 22:29):

Oh, that's sad..

Eric Wieser (Jul 17 2021 at 22:29):

Why?

Alex Zhang (Jul 17 2021 at 22:30):

If you have [_inst_2 : decidable_pred (λ (_x : α), _x ∈ s)], can lean infer [_inst_1 : decidable_pred s]?

Eric Wieser (Jul 17 2021 at 22:31):

The latter is nonsense, because it implies using s x on a set

Eric Wieser (Jul 17 2021 at 22:31):

Lean happens to accept it, but you don't want to do it

Eric Wieser (Jul 17 2021 at 22:32):

Because there are no lemmas about s x but lots of lemmas about x ∈ x

Eric Wieser (Jul 17 2021 at 22:35):

#8211 tried to clean this sort of mess up

Kyle Miller (Jul 17 2021 at 22:37):

Alex Zhang said:

Oh, that's sad..

Just FYI, set_of is how you convert a predicate into a set. The subtype.fintype instance will convert the set into a predicate (via (λ (x : α), x ∈ s) through a couple of nice coincidences.

Eric Wieser (Jul 17 2021 at 22:39):

docs#set_of aka {x | p x}

Eric Wieser (Jul 17 2021 at 22:43):

As I understand it, the only reason that lean doesn't define set as structure set := (mem : α → Prop) is so that both (∈ {x | p x}) = p and {x | x ∈ s} = s are true definitionally; if it were a structure, the second statement would require extensionality to prove as lean does not perform eta reduction.

Yakov Pechersky (Jul 18 2021 at 02:12):

BTW, to answer the first question, docs#set.to_finset_univ is in the desired direction. An alright rule of thumb for simp lemmas is that the RHS term should have fewer terms.

Yakov Pechersky (Jul 18 2021 at 02:12):

On the LHS, you have both set.univ and set.to_finset. The RHS only have finset.univ


Last updated: Dec 20 2023 at 11:08 UTC