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} ( : F α = F α') ( : F β = F β')
parameters (f : F α  F β) (f' : F α'  F β') (h : f == f')
include   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 [] },
  congr' 1, { rw  }, { simp [] },
  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} ( : F α = F α') ( : F β = F β')
parameters (f : F α  F β) (f' : F α'  F β') (h : f == f')
include   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 
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} ( : F α = F α') ( : F β = F β')
parameters (f : F α  F β) (f' : F α'  F β') (h : f == f')
include   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  },
  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):

Mario Carneiro (Sep 10 2018 at 16:58):

and 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 κ\kappa

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