Zulip Chat Archive
Stream: lean4
Topic: Trouble with rw/subst
sgcs (Apr 24 2023 at 07:37):
I have the following MWE:
inductive Foo where
| foo₁ : Foo
| foo₂ : Foo
| foo₃ : Foo
inductive Baz : Foo → Type where
| baz1 : Baz Foo.foo₁
| baz2 : Baz Foo.foo₂
inductive Bar : Foo → Foo → Type where
axiom Bar.deterministic {f₁ f₂ f₃ : Foo} (bar₁ : Bar f₁ f₂) (bar₂ : Bar f₁ f₃) : f₂ = f₃
inductive Barᵣₜ : Foo → Foo → Type where
| refl : (f : Foo) → Barᵣₜ f f
| trans (f₁ : Foo) {f₂ f₃ : Foo} : (Bar f₁ f₂) → Barᵣₜ f₂ f₃ → Barᵣₜ f₁ f₃
def Barᵣₜ.length {f f' : Foo} : (Barᵣₜ f f') → Nat
| .refl _ => 0
| .trans _ _ mtr => 1 + length mtr
axiom Barᵣₜ.deterministic {f₁ f₂ f₃ : Foo} (barᵣₜ₁ : Barᵣₜ f₁ f₂) (barᵣₜ₂ : Barᵣₜ f₁ f₃) (baz₁ : Baz f₂) (baz₂ : Baz f₃) : f₂ = f₃
axiom Foo.barᵣₜ (f : Foo) : Σ f' : Foo, Baz f' × Barᵣₜ f f'
theorem Foo.count (f : Foo) : Nat := (Foo.barᵣₜ f).2.2.length
theorem foo
{f₁ f₂ : Foo} (bar₁ : Bar f₁ f₂) :
1 + f₂.count = f₁.count := by
unfold Foo.count
let ⟨_, baz₁, barᵣₜ₁⟩ := f₁.barᵣₜ
rename_i f₃
let ⟨_, baz₂, barᵣₜ₂⟩ := f₂.barᵣₜ
rename_i f₃'
cases barᵣₜ₁ with
| refl => sorry -- this is not important
| trans _ bar₁' barᵣₜ₂' =>
rename_i fₘ
simp only
conv => rhs; unfold Barᵣₜ.length
-- Had the same problem below as I did here, but was able to resolve by reverting
revert barᵣₜ₂ barᵣₜ₂'
rw [Bar.deterministic bar₁ bar₁'] at *
intro barᵣₜ₂' barᵣₜ₂
-- If I try the following, I get:
-- ```
-- application type mismatch
-- Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁
-- argument
-- baz₁
-- has type
-- Baz f₃ : Type
-- but is expected to have type
-- Baz f₃' : Type
-- ```
-- rw [Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂] at *
-- Which I don't understand since this works by itself:
-- let eq := Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂
-- But if I try to subst `eq`, I get:
-- `failed to create binder due to failure when reverting variable dependencies`
-- subst eq
sorry
I have an equality Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂
that I want to rewrite with, but can't seem to figure out how to do so. I have some comments above showing what I've tried and what errors I've gotten.
Kevin Buzzard (Apr 24 2023 at 07:52):
If I put set_option autoImplicit false
at the top of your file it indicates an error in the definition of Baz
, meaning that your definition of Baz
might not say what you think it says (foo₁ ≠ Foo.foo₁
, in fact foo₁
is just a variable here). Does this help?
sgcs (Apr 24 2023 at 07:58):
Oh, thank you, I didn't notice that. Unfortunately, that was just a mistake in making the MWE. Changing it to be Foo.foo₁
and Foo.foo₂
doesn't change the error I'm getting.
sgcs (Apr 24 2023 at 08:55):
Another example where I run into the same problems is (in the context of the above code) is:
axiom Bar.irrelevant {f f' : Foo} (bar bar' : Bar f f') : bar = bar'
theorem thm {f₁ f₂ : Foo} (barᵣₜ barᵣₜ' : Barᵣₜ f₁ f₂) (baz : Baz f₂) : barᵣₜ = barᵣₜ' :=
match barᵣₜ, barᵣₜ' with
| .refl _, .refl _ => rfl
| .refl _, .trans _ _ _ => sorry -- not important
| .trans _ _ _, .refl _ => sorry -- not important
| .trans _ bar barᵣₜ, .trans _ bar' barᵣₜ' => by
-- Want to:
-- 1. rewrite using `Bar.deterministic bar bar'`
-- 2. rewrite using `Bar.irrelevant bar bar'`
-- 3. rewrite using `thm barᵣₜ barᵣₜ' baz`
rw [Bar.deterministic bar bar'] at *
rw [Bar.irrelevant bar bar'] at *
rw [thm barᵣₜ barᵣₜ' baz] at *
sorry
When I try to rw [Bar.deterministic bar bar'] at *
, it remove the old hypotheses which makes the following rewrites fail. I get the same failed to create binder due to failure when reverting variable dependencies
error if I try to use subst
instead.
Kevin Buzzard (Apr 24 2023 at 08:58):
I'm a bit confused by exactly what you're asking. Can you just post one question? Give an example of a rewrite which you think should work, but which fails, for example. The error you get with rw [Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂] at *
seems to be exactly the error one would expect, for example.
Kyle Miller (Apr 24 2023 at 08:59):
Using cases
instead of subst
works here:
theorem thm {f₁ f₂ : Foo} (barᵣₜ barᵣₜ' : Barᵣₜ f₁ f₂) (baz : Baz f₂) : barᵣₜ = barᵣₜ' :=
match barᵣₜ, barᵣₜ' with
| .refl _, .refl _ => rfl
| .refl _, .trans _ _ _ => sorry -- not important
| .trans _ _ _, .refl _ => sorry -- not important
| .trans _ bar barᵣₜ, .trans _ bar' barᵣₜ' => by
cases Bar.deterministic bar bar'
cases Bar.irrelevant bar bar'
cases thm barᵣₜ barᵣₜ' baz
sorry
Kyle Miller (Apr 24 2023 at 09:00):
cases
is more low-level than subst
Kyle Miller (Apr 24 2023 at 09:00):
I didn't check to what extent it carried out the full substitution however.
sgcs (Apr 24 2023 at 09:09):
Kyle Miller said:
Using
cases
instead ofsubst
works here:theorem thm {f₁ f₂ : Foo} (barᵣₜ barᵣₜ' : Barᵣₜ f₁ f₂) (baz : Baz f₂) : barᵣₜ = barᵣₜ' := match barᵣₜ, barᵣₜ' with | .refl _, .refl _ => rfl | .refl _, .trans _ _ _ => sorry -- not important | .trans _ _ _, .refl _ => sorry -- not important | .trans _ bar barᵣₜ, .trans _ bar' barᵣₜ' => by cases Bar.deterministic bar bar' cases Bar.irrelevant bar bar' cases thm barᵣₜ barᵣₜ' baz sorry
Thank you! That solves all of the rewrite problems I was having, though I don't understand why rw
and subst
fail while cases
works.
Kyle Miller (Apr 24 2023 at 09:11):
I don't know why subst
fails, but rw at *
is usually not good for global substitutions. It uses a different algorithm to do the rewrite.
sgcs (Apr 24 2023 at 09:12):
Kevin Buzzard said:
I'm a bit confused by exactly what you're asking. Can you just post one question? Give an example of a rewrite which you think should work, but which fails, for example. The error you get with
rw [Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂] at *
seems to be exactly the error one would expect, for example.
I'm not sure what you mean about the error being expected, at least it doesn't seem obvious to me. Changing it to use cases
makes it work which is what I would have expected with rw
.
sgcs (Apr 24 2023 at 09:12):
For example, the final code with finished proofs (excluding some other cases that needed additional lemmas outside of the MWE):
inductive Foo where
| foo₁ : Foo
| foo₂ : Foo
| foo₃ : Foo
inductive Baz : Foo → Type where
| baz1 : Baz Foo.foo₁
| baz2 : Baz Foo.foo₂
inductive Bar : Foo → Foo → Type where
axiom Bar.deterministic {f₁ f₂ f₃ : Foo} (bar₁ : Bar f₁ f₂) (bar₂ : Bar f₁ f₃) : f₂ = f₃
inductive Barᵣₜ : Foo → Foo → Type where
| refl : (f : Foo) → Barᵣₜ f f
| trans (f₁ : Foo) {f₂ f₃ : Foo} : (Bar f₁ f₂) → Barᵣₜ f₂ f₃ → Barᵣₜ f₁ f₃
def Barᵣₜ.length {f f' : Foo} : (Barᵣₜ f f') → Nat
| .refl _ => 0
| .trans _ _ mtr => 1 + length mtr
axiom Barᵣₜ.deterministic {f₁ f₂ f₃ : Foo} (barᵣₜ₁ : Barᵣₜ f₁ f₂) (barᵣₜ₂ : Barᵣₜ f₁ f₃) (baz₁ : Baz f₂) (baz₂ : Baz f₃) : f₂ = f₃
axiom Foo.barᵣₜ (f : Foo) : Σ f' : Foo, Baz f' × Barᵣₜ f f'
theorem Foo.count (f : Foo) : Nat := (Foo.barᵣₜ f).2.2.length
axiom Bar.irrelevant {f f' : Foo} (bar bar' : Bar f f') : bar = bar'
theorem thm {f₁ f₂ : Foo} (barᵣₜ barᵣₜ' : Barᵣₜ f₁ f₂) (baz : Baz f₂) : barᵣₜ = barᵣₜ' :=
match barᵣₜ, barᵣₜ' with
| .refl _, .refl _ => rfl
| .refl _, .trans _ _ _ => sorry -- not important
| .trans _ _ _, .refl _ => sorry -- not important
| .trans _ bar barᵣₜ, .trans _ bar' barᵣₜ' => by
cases Bar.deterministic bar bar'
cases Bar.irrelevant bar bar'
cases thm barᵣₜ barᵣₜ' baz
rfl
theorem foo
{f₁ f₂ : Foo} (bar₁ : Bar f₁ f₂) :
1 + f₂.count = f₁.count := by
unfold Foo.count
let ⟨_, baz₁, barᵣₜ₁⟩ := f₁.barᵣₜ
rename_i f₃
let ⟨_, baz₂, barᵣₜ₂⟩ := f₂.barᵣₜ
rename_i f₃'
cases barᵣₜ₁ with
| refl => sorry -- this is not important
| trans _ bar₁' barᵣₜ₂' =>
rename_i fₘ
simp only
conv => rhs; unfold Barᵣₜ.length
revert barᵣₜ₂ barᵣₜ₂'
rw [Bar.deterministic bar₁ bar₁'] at *
intro barᵣₜ₂' barᵣₜ₂
cases Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂
cases thm barᵣₜ₂ barᵣₜ₂' baz₁
rfl
Kyle Miller (Apr 24 2023 at 09:16):
I'm not actually able to reproduce that subst
fails:
theorem foo
{f₁ f₂ : Foo} (bar₁ : Bar f₁ f₂) :
1 + f₂.count = f₁.count := by
unfold Foo.count
let ⟨_, baz₁, barᵣₜ₁⟩ := f₁.barᵣₜ
rename_i f₃
let ⟨_, baz₂, barᵣₜ₂⟩ := f₂.barᵣₜ
rename_i f₃'
cases barᵣₜ₁ with
| refl => sorry -- this is not important
| trans _ bar₁' barᵣₜ₂' =>
rename_i fₘ
simp only
conv => rhs; unfold Barᵣₜ.length
revert barᵣₜ₂ barᵣₜ₂'
have := Bar.deterministic bar₁ bar₁'
subst this
intro barᵣₜ₂' barᵣₜ₂
have := Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂
subst this
have := thm barᵣₜ₂ barᵣₜ₂' baz₁
subst this
rfl
sgcs (Apr 24 2023 at 09:17):
Really? When I have:
theorem foo
{f₁ f₂ : Foo} (bar₁ : Bar f₁ f₂) :
1 + f₂.count = f₁.count := by
unfold Foo.count
let ⟨_, baz₁, barᵣₜ₁⟩ := f₁.barᵣₜ
rename_i f₃
let ⟨_, baz₂, barᵣₜ₂⟩ := f₂.barᵣₜ
rename_i f₃'
cases barᵣₜ₁ with
| refl => sorry -- this is not important
| trans _ bar₁' barᵣₜ₂' =>
rename_i fₘ
simp only
conv => rhs; unfold Barᵣₜ.length
-- Had the same problem below as I did here, but was able to resolve by reverting
revert barᵣₜ₂ barᵣₜ₂'
rw [Bar.deterministic bar₁ bar₁'] at *
intro barᵣₜ₂' barᵣₜ₂
let eq := Barᵣₜ.deterministic barᵣₜ₂ barᵣₜ₂' baz₁ baz₂
subst eq
sorry
I get: failed to create binder due to failure when reverting variable dependencies
Let me try yours
sgcs (Apr 24 2023 at 09:18):
But, you're right, yours works. Am I using subst
incorrectly?
Kyle Miller (Apr 24 2023 at 09:18):
Yeah, don't use let
for propositions, use have
.
sgcs (Apr 24 2023 at 09:19):
Oh, ok, I wasn't aware there was even a difference between using let
and have
in tactics, I thought they were the same
Kyle Miller (Apr 24 2023 at 09:21):
They general difference between let
and have
(both inside and outside tactics) is that with let
the defined variable is definitionally equal to its value, but with have
the defined variable isn't, and it can't be unfolded to its value (it's been forgotten, so to speak).
Kyle Miller (Apr 24 2023 at 09:21):
With propositions, you don't generally want the value, and many tactics assume any local proofs are created with have
, like apparently subst
.
Kyle Miller (Apr 24 2023 at 09:22):
Maybe subst
should detect this and report an error, rather than giving a cryptic second-order error
sgcs (Apr 24 2023 at 09:24):
Thanks, that clarifies a lot for me. I think part of the problem is that I've used (or recall doing so) subst
successfully with let
bindings previously in simpler proofs so wasn't aware that was a problem.
Last updated: Dec 20 2023 at 11:08 UTC