Zulip Chat Archive
Stream: mathlib4
Topic: logic.equiv.basic
Scott Morrison (Nov 19 2022 at 02:10):
77tigers (sorry, I don't know their zulip usernames --- @Kevin Buzzard?) started the port of Logic.Equiv.Basic
in mathlib4#631.
I feel this one is on the critical path to porting many other things, so I hope it is okay with the OP if others join in to get it done asap.
Scott Morrison (Nov 19 2022 at 02:10):
I've just gone ahead and finished renaming and aligning the file.
Scott Morrison (Nov 19 2022 at 02:11):
However there are many broken proofs still, for mostly independent reasons, so it should be fine if anyone wants to jump in and just fix as many as they have inclination to do.
Scott Morrison (Nov 19 2022 at 02:12):
Probably best not to sit on changes, however: if you fix a few proofs, push your commit. :-)
Scott Morrison (Nov 19 2022 at 02:27):
In that logic.equiv.basic we have the slightly esoteric (and only used in Chevalley-Warning)
/-- The type of all functions `X → Y` with prescribed values for all `x' ≠ x`
is equivalent to the codomain `Y`. -/
def subtypeEquivCodomain (f : { x' // x' ≠ x } → Y) : { g : X → Y // g ∘ coe = f } ≃ Y := ...
but of course coe
doesn't mean anything now. I'm guessing the closest replacement for this theorem will be:
def subtypeEquivCodomain (f : { x' // x' ≠ x } → Y) : { g : X → Y // (fun x : { x' // x' ≠ x } => g x) = f } ≃ Y :=
Any other suggestions?
Mario Carneiro (Nov 19 2022 at 02:32):
For specific types where we can find a Coe
instance, you should replace occurrences of coe
with (↑)
(defined in Mathlib.Tactic.Coe
) or (·)
Scott Morrison (Nov 19 2022 at 02:36):
I can't get (↑)
or (·)
to work here, as without a type annotation on the left-hand-side (i.e. g ∘ (·)
) they just seem to default to the identity, and then we get a type error on the f
.
Scott Morrison (Nov 19 2022 at 02:36):
Hence writing (fun x : { x' // x' ≠ x } => g x) = f
.
Mario Carneiro (Nov 19 2022 at 02:54):
I'm getting a bad error:
instance (p : α → Prop) : Coe (Subtype p) α := ⟨Subtype.val⟩
def subtypeEquivCodomain {X : Type u} {Y : Type v} (x : X) (f : { x' // x' ≠ x } → Y) :
{ g : X → Y // (g ∘ (·)) = f } ≃ Y := sorry
-- failed to synthesize
-- CoeHTCT ({ x' // x' ≠ x } → Y) (X → Y)
-- (deterministic) timeout at 'typeclass', maximum number of heartbeats (20000) has been reached (use 'set_option synthInstance.maxHeartbeats <num>' to set the limit)
Mario Carneiro (Nov 19 2022 at 02:55):
which indicates that there is a bad instance somewhere causing a loop
Mario Carneiro (Nov 19 2022 at 02:56):
oh, actually it's probably the subtype coe I had to add to make this compile
Mario Carneiro (Nov 19 2022 at 02:57):
Using Subtype.val
works, of course
Mario Carneiro (Nov 19 2022 at 02:58):
also by exact (·)
Scott Morrison (Nov 19 2022 at 02:58):
So is it better to have Subtype.val
in the statement, or what I wrote?
Mario Carneiro (Nov 19 2022 at 02:58):
I think this is a bug report
Gabriel Ebner (Nov 19 2022 at 02:59):
That (↑)
doesn't work here is a bug. Give me a sec.
Scott Morrison (Nov 19 2022 at 02:59):
A separate logic.equiv.basic question, I seem to be encountering a failure of beta reduction in the following:
structure Equiv (α : Sort _) (β : Sort _) where
toFun : α → β
invFun : β → α
left_inv : ∀ x, invFun (toFun x) = x
infixl:25 " ≃ " => Equiv
/-- A product of types can be split as the binary product of one of the types and the product
of all the remaining types. -/
def piSplitAt {α : Type _} [DecidableEq α] (i : α) (β : α → Type _) :
(∀ j, β j) ≃ β i × ∀ j : { j // j ≠ i }, β j where
toFun f := ⟨f i, fun j => f j⟩
invFun f j := if h : j = i then h.symm.rec f.1 else f.2 ⟨j, h⟩
left_inv f := by
apply funext
intro x
/- Goal is now:
```
(fun f j => if h : j = i then (_ : i = j) ▸ f.fst else Prod.snd f { val := j, property := h })
((fun f => (f i, fun j => f j.val)) f) x =
f x
```
-/
dsimp only -- Does nothing
-- Expected the goal to start with `if h : j = i ...`
Am I missing something, or is this a bug?
Mario Carneiro (Nov 19 2022 at 02:59):
I'm inclined to use Subtype.val
(or something that expands to it, once we work that out) to ensure it is still written in first-order style with explicit composition
Mario Carneiro (Nov 19 2022 at 03:00):
that also looks like a bug
Gabriel Ebner (Nov 19 2022 at 03:01):
https://github.com/leanprover-community/mathlib4/pull/652
Scott Morrison (Nov 19 2022 at 03:03):
Reported the beta reduction issue as lean4#1856.
Scott Morrison (Nov 19 2022 at 07:35):
In logic.equiv.basic
we have the somewhat tricky statement pi_congr_left'
, which translates to:
import Mathlib.Logic.Equiv.Defs
namespace Equiv
def piCongrLeft' (P : α → Sort _) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b) where
toFun f x := f (e.symm x)
invFun f x := by
rw [← e.symm_apply_apply x]
exact f (e x)
left_inv f :=
funext fun x =>
eq_of_heq
((eq_rec_heq _ _).trans
(by
dsimp
rw [e.symm_apply_apply])) -- fails, but the goal was already bad: `HEq ?m.205 ?m.206`
right_inv f := funext fun x => eq_of_heq ((eq_rec_heq _ _).trans (by rw [e.apply_symm_apply])) -- fails similarly
#align equiv.Pi_congr_left' Equiv.piCongrLeft'
However this proof isn't working. When I try to do it step by step I can't get the eq_rec_heq
s to unify. Can anyone work out a new proof here?
Scott Morrison (Nov 19 2022 at 08:22):
Ah, got it. I found the old thread form 2020 when we first put this in mathlib, where Mario offered some alternative proofs, and one of those translates just fine.
Matthew Ballard (Apr 08 2023 at 11:32):
I've run into another situation where dsimp
doesn't beta-reduce. Let me do a sanity check and report back.
Last updated: Dec 20 2023 at 11:08 UTC