Zulip Chat Archive
Stream: general
Topic: heq again
Reid Barton (Sep 10 2018 at 16:24):
Hmm, I wasn't expecting this to work.
lemma types_eq_of_heq : Π {α : Type} (a : α) {β : Type} (b : β) (h : a == b), α = β | α a _ _ (heq.refl _) := rfl
Kenny Lau (Sep 10 2018 at 16:25):
why not?
Kenny Lau (Sep 10 2018 at 16:25):
casing on h
makes sure that the types are equal and the arguments are equal
Reid Barton (Sep 10 2018 at 16:26):
Mostly because I haven't seen this fact in core or mathlib, so I guess I assumed it was not provable.
Reid Barton (Sep 10 2018 at 16:26):
Now I have a followup question about congr
.
Reid Barton (Sep 10 2018 at 16:26):
import data.set section parameters {F : Type → Type} {α β α' β' : Type} (hα : F α = F α') (hβ : F β = F β') parameters (f : F α → F β) (f' : F α' → F β') (h : f == f') include hα hβ h def fns := Σ' X Y : set.range F, X.1 → Y.1 def g : fns := ⟨⟨F α, α, rfl⟩, ⟨F β, β, rfl⟩, f⟩ def g' : fns := ⟨⟨F α', α', rfl⟩, ⟨F β', β', rfl⟩, f'⟩ def e : g = g' := begin dsimp [g, g'], /- ⊢ ⟨⟨F α, _⟩, ⟨⟨F β, _⟩, f⟩⟩ = ⟨⟨F α', _⟩, ⟨⟨F β', _⟩, f'⟩⟩ -/ /- How to proceed? My solution: -/ congr' 1, { simp [hα] }, congr' 1, { rw hα }, { simp [hβ] }, simp [h], end end
Kenny Lau (Sep 10 2018 at 16:27):
are you going to livestream?
Mario Carneiro (Sep 10 2018 at 16:27):
type_eq_of_heq
Reid Barton (Sep 10 2018 at 16:27):
I'm annoyed about this { rw hα }
thing. The goal there is
⊢ (λ (Y : {x // x ∈ set.range F}), F α → Y.val) = λ (Y : {x // x ∈ set.range F}), F α' → Y.val
which I think is trying to say that when I do the second congr'
, the types of the two sides are equal.
Reid Barton (Sep 10 2018 at 16:28):
Wow, my grep skills failed
Reid Barton (Sep 10 2018 at 16:29):
If I put { admit }
there, the rest of the proof seems to go through fine. So couldn't congr'
deduce that the types are equal after the fact, using type_eq_of_heq
?
Reid Barton (Sep 10 2018 at 16:32):
Here's a dumber example.
example {α β : Type} (a : α) (b : β) : (a, a) == (b, b) := begin congr, end
There are four goals, ⊢ α = β
twice and ⊢ a == b
twice. But I can get the former from the latter.
Reid Barton (Sep 10 2018 at 16:35):
Or a nicer presentation
example {α α' β β' : Type} (a : α) (b : β) (a' : α') (b' : β') : (a, b) == (a', b') :=
Kenny Lau (Sep 10 2018 at 16:36):
import data.set section parameters {F : Type → Type} {α β α' β' : Type} (hα : F α = F α') (hβ : F β = F β') parameters (f : F α → F β) (f' : F α' → F β') (h : f == f') include hα hβ h def fns := Σ' X Y : set.range F, X.1 → Y.1 def g : fns := ⟨⟨F α, α, rfl⟩, ⟨F β, β, rfl⟩, f⟩ def g' : fns := ⟨⟨F α', α', rfl⟩, ⟨F β', β', rfl⟩, f'⟩ def e : g = g' := begin dsimp only [g, g'], congr; try {assumption}, ext Y, rw hα end end
Reid Barton (Sep 10 2018 at 16:37):
The ext Y, rw hα
part is still there, though. That's the only part I care about because it seems unnecessary.
In my real use case, I have three of them and they are bigger
Reid Barton (Sep 10 2018 at 16:41):
Does set_option trace.congr_lemma true
do anything?
Reid Barton (Sep 10 2018 at 16:43):
Kenny, I was thinking I would try this evening US eastern time today, maybe a bit late for you
Mario Carneiro (Sep 10 2018 at 16:51):
That's a pretty messy goal. I would clean it up by hand as follows:
begin let G := λ A B (f : A → B) h h', (⟨⟨A, h⟩, ⟨B, h'⟩, f⟩ : fns), suffices : ∀ {f f' h₁ h₂ h₃ h₄}, f == f' → G (F α) (F β) f h₁ h₂ = G (F α') (F β') f' h₃ h₄, exact this h, rw [hα, hβ], intros, congr', apply eq_of_heq a end
Mario Carneiro (Sep 10 2018 at 16:51):
I would avoid having type equalities and heqs in the hypotheses to begin with
Mario Carneiro (Sep 10 2018 at 16:52):
congr
is clearly dropping the ball here. There are lots of superfluous goals being generated
Mario Carneiro (Sep 10 2018 at 16:53):
But usually you don't want to deduce a type equality from a heq; rather you want to assume the type equality and prove a regular equality dependent on it
Kenny Lau (Sep 10 2018 at 16:53):
is there any way to prove this goal?
Kenny Lau (Sep 10 2018 at 16:53):
import data.set section parameters {F : Type → Type} {α β α' β' : Type} (hα : F α = F α') (hβ : F β = F β') parameters (f : F α → F β) (f' : F α' → F β') (h : f == f') include hα hβ h def fns := Σ' X Y : set.range F, X.1 → Y.1 def g : fns := ⟨⟨F α, α, rfl⟩, ⟨F β, β, rfl⟩, f⟩ def g' : fns := ⟨⟨F α', α', rfl⟩, ⟨F β', β', rfl⟩, f'⟩ set_option pp.proofs true theorem e : g = g' := begin fapply psigma.eq, { exact subtype.eq hα }, fapply psigma.eq, { /- (eq.rec_on (subtype.eq hα) (g.snd)).fst = (g'.snd).fst -/ } end end
Reid Barton (Sep 10 2018 at 16:54):
Well how about the following modification to congr
. After each single layer of congr
, try filling each of the new goals by applying exact type_eq_of_heq ?m_i
where ?m_i
is the metavariable of each other goal.
Mario Carneiro (Sep 10 2018 at 16:55):
That's not what you want though. You will have to deduce those type equalities anyway in order to prove the heq
Reid Barton (Sep 10 2018 at 16:55):
But I didn't!
Reid Barton (Sep 10 2018 at 16:56):
I happen to have the heq lying around, and where I proved it, the type equalities were obvious
Mario Carneiro (Sep 10 2018 at 16:56):
You satisfied the type equality proof by assumption
Reid Barton (Sep 10 2018 at 16:57):
Which type equality proof?
Mario Carneiro (Sep 10 2018 at 16:57):
hα
Mario Carneiro (Sep 10 2018 at 16:58):
and hβ
later in the proof
Reid Barton (Sep 10 2018 at 16:58):
Right, but then there is an inner proof obligation I have to take care of, the one I solve using { rw hα }
Reid Barton (Sep 10 2018 at 16:59):
Let me put up my real code
Mario Carneiro (Sep 10 2018 at 16:59):
you have to solve that anyway
Reid Barton (Sep 10 2018 at 17:00):
No, it follows from being able to solve the rest of the goals
Mario Carneiro (Sep 10 2018 at 17:00):
how?
Reid Barton (Sep 10 2018 at 17:00):
By type_eq_of_heq
. Right?
Mario Carneiro (Sep 10 2018 at 17:00):
applied to what?
Reid Barton (Sep 10 2018 at 17:01):
Isn't it the same thing as this?
example {α α' β β' : Type} (a : α) (b : β) (a' : α') (b' : β') (ha : a == a') (hb : b == b') : (a, b) == (a', b') := begin congr, { exact type_eq_of_heq ha }, { exact type_eq_of_heq hb }, { exact ha }, { exact hb } end
Mario Carneiro (Sep 10 2018 at 17:03):
sure, but this is an unrealistic goal. Where are you going to get those heqs without a type equality?
Reid Barton (Sep 10 2018 at 17:03):
so in my real code it happens here https://gist.github.com/rwbarton/dfb90b2552f09b51798bb52af9948d48#file-filtered-lean-L249
Reid Barton (Sep 10 2018 at 17:05):
S is the image of a functor F : I -> C considered as a subgraph, defined here https://gist.github.com/rwbarton/dfb90b2552f09b51798bb52af9948d48#file-filtered-lean-L87
Mario Carneiro (Sep 10 2018 at 17:07):
can you MWE the state just before the rintro
?
Mario Carneiro (Sep 10 2018 at 17:07):
or maybe just after
Reid Barton (Sep 10 2018 at 17:09):
It should be more or less what I pasted originally.
Note hg : functor.map F ((⟨i', ⟨j', g⟩⟩.snd).snd) == f
, which came from the definition of S
Reid Barton (Sep 10 2018 at 17:10):
Corresponding to my original (h : f == f')
Mario Carneiro (Sep 10 2018 at 17:10):
I want to catch the state before the type equalities enter the context
Reid Barton (Sep 10 2018 at 17:12):
Ah, so you mean hi', hj'
Mario Carneiro (Sep 10 2018 at 17:12):
ideally you should be able to match on hi', hj', hg
and save all the mess
Mario Carneiro (Sep 10 2018 at 17:13):
don't match on ⟨X, i, rfl⟩, ⟨Y, j, rfl⟩
, just do ⟨X, _⟩, ⟨Y, _⟩
Reid Barton (Sep 10 2018 at 17:15):
Hmm, I will try that
Reid Barton (Sep 10 2018 at 17:19):
Meanwhile I updated the gist with a version which is not M, but should be a WE
Reid Barton (Sep 10 2018 at 17:21):
Oh, there is a trick in F ijg.1 = X ∧ F ijg.2.1 = Y ∧ ...
. That is not just X
, but X.val
Reid Barton (Sep 10 2018 at 17:21):
because of my representation of a subgraph, which I now infinitely regret
Reid Barton (Sep 10 2018 at 17:23):
I have a subgraph as (1) a subset of the vertices, (2) for each pair of vertices in that set (as a subtype), a subset of the edges between them
Mario Carneiro (Sep 10 2018 at 17:25):
works for me:
rintro ⟨⟨X, _⟩, ⟨Y, _⟩, ⟨f, ⟨i, j, g⟩, ⟨⟩, ⟨⟩, ⟨⟩⟩⟩, exact ⟨⟨i, j, g⟩, rfl⟩,
Mario Carneiro (Sep 10 2018 at 17:26):
using rfl
instead of ⟨⟩
calls subst
instead of cases
, and subst
is not sufficiently aggressive wrt definitionally unfolding one side to a variable
Reid Barton (Sep 10 2018 at 17:27):
Ahh
Mario Carneiro (Sep 10 2018 at 17:28):
I would suggest, if you are okay with the added verbosity, that you use an inductive type to define your hom sets instead of ands of eqs and heqs
Reid Barton (Sep 10 2018 at 17:28):
I see
rfl : ⇑F (⟨i', ⟨j', g⟩⟩.fst) = ↑⟨X, b_fst_property⟩,
Mario Carneiro (Sep 10 2018 at 17:29):
it names the variable rfl
before substing, I think
Reid Barton (Sep 10 2018 at 17:29):
Looks that way.
Reid Barton (Sep 10 2018 at 17:30):
that's a whole lot better, thanks!
Reid Barton (Sep 10 2018 at 17:30):
You mean, in the definition of S?
Mario Carneiro (Sep 10 2018 at 17:30):
yes
Mario Carneiro (Sep 10 2018 at 17:31):
it's up to you, you can use tricks like this to match on it either way
Reid Barton (Sep 10 2018 at 17:31):
oh, I could replace the whole λ X Y, {f | ∃ (ijg : Σ (i j : I), i ⟶ j), F ijg.1 = X ∧ F ijg.2.1 = Y ∧ F.map ijg.2.2 == f}
with an inductive type I guess
Mario Carneiro (Sep 10 2018 at 17:31):
right
Mario Carneiro (Sep 10 2018 at 17:32):
it would give nicer equations, but if this is a one-off it's probably not worth it
Reid Barton (Sep 10 2018 at 17:32):
and elsewhere I have similar constructions, like the union of a family of subgraphs
Reid Barton (Sep 10 2018 at 17:33):
Yeah, I'm not sure I will need any of these constructions more than once, inside the associated proof
Reid Barton (Sep 10 2018 at 17:33):
But a good technique to keep in mind
Mario Carneiro (Sep 10 2018 at 17:34):
oh, looks like you don't even need to match on ijg
in that proof
Reid Barton (Sep 10 2018 at 17:35):
Yep
Reid Barton (Sep 10 2018 at 17:35):
I think I know what happened here
Reid Barton (Sep 10 2018 at 17:35):
I started without the F ijg.1 = X ∧ F ijg.2.1 = Y ∧
part
Reid Barton (Sep 10 2018 at 17:36):
in the definition of S. And then I realized that wasn't going to work
Reid Barton (Sep 10 2018 at 17:36):
but I think I had already written the ⟨X, i, rfl⟩, ⟨Y, j, rfl⟩
patterns
Mario Carneiro (Sep 10 2018 at 17:39):
yeah, of course you can't deduce X = X'
and Y = Y'
from X ⟶ Y = X' ⟶ Y'
Mario Carneiro (Sep 10 2018 at 17:39):
not for function types and definitely not for homsets
Reid Barton (Sep 10 2018 at 17:41):
Although it curiously would not even matter for the cardinality estimate I need to do here, because it would blow things up by a factor of less than
Reid Barton (Sep 10 2018 at 17:41):
But anyways, that's when I started to wonder: would it be better to just define the edges as (mors : set (Σ X Y, X ⟶ Y))
Mario Carneiro (Sep 10 2018 at 17:45):
I'm inclined to say no, although possibly you might want homs
to be defined on all objects, not just those in the subset
Mario Carneiro (Sep 10 2018 at 17:45):
and just require that it be empty outside the subset
Mario Carneiro (Sep 10 2018 at 17:46):
structure subgraph (C : Type u) [small_category C] : Type u := (objs : set C) (homs : Π X Y : C, set (X ⟶ Y)) (dom_mem : Π X Y f, f ∈ homs X Y → X ∈ objs) (cod_mem : Π X Y f, f ∈ homs X Y → Y ∈ objs)
Reid Barton (Sep 10 2018 at 17:47):
Right, I would need those last two fields anyways. Just a difference between set (Σ X Y, X ⟶ Y)
and Π X Y : C, set (X ⟶ Y)
Mario Carneiro (Sep 10 2018 at 17:48):
having a big sigma will make things more complicated with heqs and stuff as you've seen
Reid Barton (Sep 10 2018 at 17:48):
Given that some of the things I do are look at the cardinality of the set of edges, and form the union of subgraphs
Reid Barton (Sep 10 2018 at 17:48):
but I guess those are not significantly harder with the Pi approach
Mario Carneiro (Sep 10 2018 at 17:48):
I think arrows := Σ X Y, X ⟶ Y
is a useful definition in a category though
Last updated: Dec 20 2023 at 11:08 UTC