Zulip Chat Archive
Stream: new members
Topic: Resolve coercion in hypothesis
Henning Dieterichs (Dec 05 2020 at 16:37):
I have h: ↥p
. How do I rewrite it to h: p = tt
? Neither rw coe
nor simp
worked.
Kevin Buzzard (Dec 05 2020 at 16:38):
p
is a bool, presumably? You could do cases on it I guess, but there is probably a one-liner.
Henning Dieterichs (Dec 05 2020 at 16:39):
yes, p is a bool ;) Would love to have a one-liner at hand to deal with coercions!
Kevin Buzzard (Dec 05 2020 at 16:40):
example (p : bool) (hp : p) : p = tt :=
begin
cases p,
{ cases hp },
{ refl },
end
Henning Dieterichs (Dec 05 2020 at 16:42):
Why is cases hp
closing the goal?
Henning Dieterichs (Dec 05 2020 at 16:43):
Ah, because it is an empty inductive type
Kevin Buzzard (Dec 05 2020 at 16:43):
because there are no cases, so there are no goals after it's done :-)
Henning Dieterichs (Dec 05 2020 at 16:43):
but how does it resolve the coercion?
Kevin Buzzard (Dec 05 2020 at 16:44):
If p
is a random bool then Lean doesn't know what ↥p
is, but if p
is tt
or ff
then it knows.
Kevin Buzzard (Dec 05 2020 at 16:45):
no I just checked the definition and what I just said is false.
Kevin Buzzard (Dec 05 2020 at 16:46):
I had assumed the coercion would be defined by cases, but ↥p := p = tt
Kevin Buzzard (Dec 05 2020 at 16:46):
import tactic
example (p : bool) (hp : p) : p = tt :=
begin
exact hp,
end
Henning Dieterichs (Dec 05 2020 at 16:46):
hmm, I guess exact is doing some kind of reduction then?
Kevin Buzzard (Dec 05 2020 at 16:47):
They are definitionally equal. You can use change
to change one to the other. Sorry for misleading you!
Kevin Buzzard (Dec 05 2020 at 16:47):
example (p : bool) (hp : p) : p = tt := hp
Henning Dieterichs (Dec 05 2020 at 16:48):
no problem, thank you very much for helping me reducing my confusion ;)
Henning Dieterichs (Dec 05 2020 at 16:48):
does definitionionally equal mean they are equal after rewriting definitions?
Henning Dieterichs (Dec 05 2020 at 16:49):
why does this unfolding of definitions happen automatically, while I have to unfold all my definitions manually or with simp?
Kevin Buzzard (Dec 05 2020 at 16:49):
In term mode Lean can see through all definitions.
Kevin Buzzard (Dec 05 2020 at 16:49):
You need to talk to someone who knows something about computers really.
Kevin Buzzard (Dec 05 2020 at 16:50):
https://leanprover.github.io/reference/expressions.html#computation is something I found useful
Marc Huisinga (Dec 05 2020 at 16:50):
Kevin Buzzard said:
You need to talk to someone who knows something about computers really.
i remember that you wrote a pretty good blog post on the matter yourself
Kevin Buzzard (Dec 05 2020 at 16:50):
but you might know it already. You might want to hear something about #reduce
but this is something I never use or think about.
Kevin Buzzard (Dec 05 2020 at 16:51):
Lean won't unfold a definition automatically, but if I say x = y
and the proof is rfl
, then at that point Lean will start to try and prove x and y are definitionally equal and it will happily unfold anything.
Marc Huisinga (Dec 05 2020 at 16:51):
https://xenaproject.wordpress.com/2019/05/21/equality-part-1-definitional-equality/
https://xenaproject.wordpress.com/2019/05/25/equality-part-2-syntactic-equality/
Kevin Buzzard (Dec 05 2020 at 16:52):
In fact you can hang Lean by giving it two complicated terms which aren't equal and then telling it to try and prove them by rfl
. The exact
tactic will presumably just be a wrapper around rfl
.
Henning Dieterichs (Dec 05 2020 at 16:53):
ah so rfl
is the tactic I can use to show that two syntactically different terms are definitionally equivalent?
Kevin Buzzard (Dec 05 2020 at 16:53):
rfl
is the term, refl
is the tactic.
Henning Dieterichs (Dec 05 2020 at 16:54):
thanks a lot!
Kevin Buzzard (Dec 05 2020 at 16:55):
(strictly speaking refl
is a bit stronger, it will attempt to prove any goal of the form R a b
where R
is a reflexive predicate which has been tagged with the @[refl]
attribute by invoking reflexivity of R
and then trying to prove a = b
; for example you can prove with refl
in tactic mode but not with rfl
in term mode, which is strictly for equality)
Kevin Buzzard (Dec 05 2020 at 16:56):
example : 2 + 2 = 4 := rfl
(because both reduce to S(S(S(S(0))))
Marc Huisinga (Dec 05 2020 at 16:58):
if you care about implementation details, rfl
is just eq.refl
(https://github.com/leanprover-community/lean/blob/master/library/init/core.lean#L231), where eq.refl
is described in TPIL (https://leanprover.github.io/theorem_proving_in_lean/inductive_types.html#inductive-families), and definitional equality is built into the kernel
Kevin Buzzard (Dec 05 2020 at 16:58):
example (p : bool) : p = tt = ↥p := rfl
Kevin Buzzard (Dec 05 2020 at 16:59):
and the contradiction is that definitional equality is undecidable but rfl
is a computer program :-) There's an example in the reference manual where two things are definitionally equal but rfl
doesn't prove it, but this is very much an edge case.
Henning Dieterichs (Dec 05 2020 at 17:05):
But why is refl
able to solve this:
example (p: bool): tt && p = p :=
begin
refl,
end
?
Kevin Buzzard (Dec 05 2020 at 17:06):
Here's how I'd diagnose this.
Kevin Buzzard (Dec 05 2020 at 17:07):
#print notation && -- it's notation for `band`
#check band -- and now right click and peek definition
Kevin Buzzard (Dec 05 2020 at 17:08):
I find
def band : bool → bool → bool
| tt b := b
| ff b := ff
Kevin Buzzard (Dec 05 2020 at 17:08):
so tt && p
is by definition p
.
Henning Dieterichs (Dec 05 2020 at 17:08):
So I guess there is some kind of reduction β and refl solves R a b
by checking whether β a is syntactically equal to β b? Can I somehow invoke this reduction β manually to make terms simpler in hypothesis/goals?
Kevin Buzzard (Dec 05 2020 at 17:09):
yeah you need to talk to a computers person. I have no idea how all this works.
Marc Huisinga (Dec 05 2020 at 17:10):
https://leanprover-community.github.io/mathlib_docs/tactics.html#dsimp
Kevin Buzzard (Dec 05 2020 at 17:10):
If I want to unfold things I just unfold
them. As a mathematician I believe that definitional equality is a weird implementation issue which I should not be using; I don't like the fact that n + 0 = n
is definitional and 0 + n = n
is not because this upsets my view of the universe as a beautiful symmetric thing. In short, I try not to think about definitional equality. But for what you're doing it's probably super-important!
Mario Carneiro (Dec 05 2020 at 17:21):
Henning Dieterichs said:
So I guess there is some kind of reduction β and refl solves
R a b
by checking whether β a is syntactically equal to β b? Can I somehow invoke this reduction β manually to make terms simpler in hypothesis/goals?
The tactic for this is called whnf
Mario Carneiro (Dec 05 2020 at 17:21):
but it's not great for interactive use
Mario Carneiro (Dec 05 2020 at 17:21):
prefer simp
Henning Dieterichs (Dec 05 2020 at 17:22):
But still, this does not work to get rid of the coercion operator:
example (p : bool) (hp : p) : p = tt :=
begin
simp at hp,
sorry
end
Henning Dieterichs (Dec 05 2020 at 17:23):
I don't want to prove that two terms are equal, I want to obtain p = tt, so I can rewrite that term at a different hypothesis
Mario Carneiro (Dec 05 2020 at 17:25):
there should be a theorem that says that
Kevin Buzzard (Dec 05 2020 at 17:55):
import tactic
example (p : bool) (hp : p) : p = tt :=
begin
unfold_coes at hp,
assumption
end
works but goes a little against the way things are supposed to work.
Kevin Buzzard (Dec 05 2020 at 17:56):
(and of course the assumption
tactic works without unfold_coes
anyway, because it also relies on rfl
;-) )
Calle Sönne (Dec 05 2020 at 19:21):
I think I have a very similar problem to this one. I also need to "unfold" a coercion, but in my specific situation I am unsure how to enter tactic mode to be able to try the above suggestions. Here is my code:
def limit_cone (F : J ⥤ Profinite) : cone F :=
{ X := { to_Top := {
α := (F ⋙ Profinite_to_Top ⋙ forget Top).sections,
str := topological_space.induced
(@set.inclusion _ (F ⋙ Profinite_to_Top ⋙ (forget Top)).sections set.univ (set.subset_univ _))
(@Pi.topological_space J ((F ⋙ Profinite_to_Top ⋙ (forget Top)).obj)
(λ j, ((F ⋙ Profinite_to_Top).obj j).str))
},
is_compact := _,
is_t2 := _,
is_totally_disconnected := _ },
π := _ }
And I get the following error:
type mismatch at application
topological_space.induced (set.inclusion _) Pi.topological_space
term
Pi.topological_space
has type
topological_space (Π (a : J), (F ⋙ Profinite_to_Top ⋙ forget Top).obj a)
but is expected to have type
topological_space ↥set.univ
and set.univ is just: set (Π (j : J), (F ⋙ Profinite_to_Top ⋙ forget Top).obj j)
.
So is there some way of "wrapping" the Pi.topological_space line in tactic mode and then rewriting it in there? Or is there a theorem I can use directly in term mode?
Kevin Buzzard (Dec 05 2020 at 19:23):
I suspect that ↥set.univ
is not _definitionally_ equal to (Π (a : J), (F ⋙ Profinite_to_Top ⋙ forget Top).obj a)
.
Calle Sönne (Dec 05 2020 at 19:25):
When I have my cursor on the Pi.topological_space line and press set.univ in the infoview that is what I get
Calle Sönne (Dec 05 2020 at 19:27):
Or I get that set.univ is set (Π (j : J), (F ⋙ Profinite_to_Top ⋙ forget Top).obj j)
but maybe I dont understand what the coercion is doing. I assume that coe_sort will give me (Π (j : J), (F ⋙ Profinite_to_Top ⋙ forget Top).obj j)
Kevin Buzzard (Dec 05 2020 at 19:42):
No it won't, it will give you a type which bijects with that but which is not equal to that.
Kevin Buzzard (Dec 05 2020 at 19:42):
import tactic
example (X : Type) : X = (set.univ : set X) :=
begin
refl -- fails
end
Kevin Buzzard (Dec 05 2020 at 19:44):
The coercion will give you a subtype of X corresponding to all the terms in X for which true
is true, so in particular it will give you a different but isomorphic type.
Kevin Buzzard (Dec 05 2020 at 19:45):
What happens if you just delete str
completely? Does type class inference fill it in?
Calle Sönne (Dec 05 2020 at 19:48):
Kevin Buzzard said:
What happens if you just delete
str
completely? Does type class inference fill it in?
unfortunately not
Kevin Buzzard (Dec 05 2020 at 19:49):
What is the goal in str := begin sorry end
?
Calle Sönne (Dec 05 2020 at 19:49):
Kevin Buzzard said:
The coercion will give you a subtype of X corresponding to all the terms in X for which
true
is true, so in particular it will give you a different but isomorphic type.
That is interesting. So I should look for some lemma which puts a topology on an isomorphic type? Maybe that will be hard to work with in practice though
Kevin Buzzard (Dec 05 2020 at 19:49):
Maybe something like str := by unfold sections; apply_instance
will work? Can you post some working code which I can run at my end?
Calle Sönne (Dec 05 2020 at 19:49):
topological_space ↥((F ⋙ Profinite_to_Top ⋙ forget Top).sections)
Kenny Lau (Dec 05 2020 at 19:50):
@Calle Sönne if you want to do this in real time you can stream in Xena
Last updated: Dec 20 2023 at 11:08 UTC