Zulip Chat Archive

Stream: mathlib4

Topic: Finset.choose


Heather Macbeth (Nov 30 2023 at 22:14):

@Jeremy Avigad and I just distilled the following strange behaviour of Finset.choose:

import Mathlib.Data.Finset.Basic

lemma foo : ∃! x, x  ({0,3} : Finset (Fin 5))  x = 3 := by
  use 3
  simp

example : Finset.choose _ _ foo = 3 := by rfl -- works
example : Finset.choose _ _ foo = 3 := rfl -- fails
example : Finset.choose _ _ foo = 3 := by eq_refl -- works
example : Finset.choose _ _ foo = 3 := by exact rfl -- fails
example : Finset.choose _ _ foo = 3 := by decide -- fails

Among the strange points here are that, if you hover over eq_refl you get the docstring

eq_refl is equivalent to exact rfl, but has a few optimizations

which, it seems, is not true in this case!

Heather Macbeth (Nov 30 2023 at 22:14):

Is something wrong with the implementation of Finset.choose? We tried to make examples not using it, and failed.

Eric Wieser (Nov 30 2023 at 22:15):

(docs#Finset.choose)

Eric Wieser (Nov 30 2023 at 22:17):

A slightly simpler test using docs#List.choose with analogous behavior:

import Mathlib.Data.Finset.Basic

lemma foo :  x, x  ([0,3] : List (Fin 5))  x = 3 := by
  use 3
  simp

example : List.choose _ _ foo = 3 := by rfl -- works
example : List.choose _ _ foo = 3 := rfl -- fails
example : List.choose _ _ foo = 3 := by eq_refl -- works
example : List.choose _ _ foo = 3 := by exact rfl -- fails
example : List.choose _ _ foo = 3 := by decide -- fails

Kyle Miller (Nov 30 2023 at 22:24):

It seems to be a reducibility thing. This works:

example : Finset.choose _ _ foo = 3 := by with_unfolding_all exact rfl

Eric Wieser (Nov 30 2023 at 22:29):

I think this is due to a non-structural recursion

Eric Wieser (Nov 30 2023 at 22:37):

The let pattern match in chooseX is to blame

Eric Wieser (Nov 30 2023 at 22:39):

Patch incoming

Eric Wieser (Nov 30 2023 at 22:45):

#8753

Eric Wieser (Nov 30 2023 at 22:46):

I'm afraid this doesn't answer your question about eq_refl, nor do I know why the pattern match is problematic here.

Eric Wieser (Nov 30 2023 at 22:51):

This is "no eta for propositions" striking again

Eric Wieser (Nov 30 2023 at 22:52):

def ohno (h : True  True) : Nat :=
  let _a, _b := h
  1

example : ohno sorry = 1 := rfl -- fails

def anyway (h : Unit × Unit) : Nat :=
  let _a, _b := h
  1

example : anyway sorry = 1 := rfl -- succeeds

Kyle Miller (Dec 01 2023 at 04:14):

Eric Wieser said:

I'm afraid this doesn't answer your question about eq_refl, nor do I know why the pattern match is problematic here.

One thing I noticed when digging into this earlier was that eq_refl uses the kernel to check that rfl works rather than using the elaborator's isDefEq check(*). I suspect isDefEq is more restrictive than the kernel here -- the kernel doesn't know about reducibility for example.

(*) This is conditional in the code. It uses the kernel if there are no metavariables or fvars.


Last updated: Dec 20 2023 at 11:08 UTC