Zulip Chat Archive

Stream: general

Topic: explicit parameters lead to more work


FR (May 22 2022 at 06:20):

import algebra.order.monoid

namespace implicit

def bar (m : with_bot ) : Type* := sorry

def foo' {m n : } (x : bar m) (y : bar n) :  := sorry

def foo :  {m n : with_bot }, bar m  bar n  
| (m' : ) (n' : ) := λ x y, foo' x y
| _        _        := λ _ _, 0

def mul :  {m n : with_bot }, bar m  bar n  bar (m + n) := sorry

lemma h {m₁ m₂ n : }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (mul x₁ x₂) y = foo x₁ y * foo x₂ y := sorry

example {m₁ m₂ n : with_bot }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (mul x₁ x₂) y = foo x₁ y * foo x₂ y :=
begin
  cases m₁; cases m₂; cases n; simp only [foo, nat.zero_mul, nat.mul_zero],
  exact h x₁ x₂ y,
end

end implicit

namespace explicit

def bar (m : with_bot ) : Type* := sorry

def foo' (m n : ) (x : bar m) (y : bar n) :  := sorry

def foo :  (m n : with_bot ), bar m  bar n  
| (m : ) (n : ) := λ x y, foo' m n x y
| (m : )        := λ _ _, 0
|        (n : ) := λ _ _, 0
|               := λ _ _, 0

def mul :  {m n : with_bot }, bar m  bar n  bar (m + n) := sorry

lemma h {m₁ m₂ n : }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (m₁ + m₂) n (mul x₁ x₂) y = foo m₁ n x₁ y * foo m₂ n x₂ y := sorry

example {m₁ m₂ n : with_bot }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (m₁ + m₂) n (mul x₁ x₂) y = foo m₁ n x₁ y * foo m₂ n x₂ y :=
begin
  induction m₁ using with_bot.rec_bot_coe;
  induction m₂ using with_bot.rec_bot_coe;
  induction n using with_bot.rec_bot_coe;
  try { rw [with_bot.bot_add], };
  try { rw [with_bot.add_bot], };
  try { rw [ with_bot.coe_add], };
  simp only [foo, nat.zero_mul, nat.mul_zero],
  exact h x₁ x₂ y,
end

end explicit

Once I made the pattern matching argument explicit, I found I had to deal with far more problems on my own than before. Are there any better solutions?

FR (May 22 2022 at 10:57):

Oh, I did it. Just use simp !

example {m₁ m₂ n : with_bot }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (m₁ + m₂) n (mul x₁ x₂) y = foo m₁ n x₁ y * foo m₂ n x₂ y :=
begin
  cases m₁; cases m₂; cases n; simp ! only [nat.zero_mul, nat.mul_zero],
  exact h x₁ x₂ y,
end

FR (May 22 2022 at 11:27):

But it unfolds too much. Can I control it?

Eric Wieser (May 22 2022 at 12:21):

Once I made the pattern matching argument explicit

What do you mean by that? Your implicit.foo and explicit.foo contain a different number of patterns to match against; there's more difference than just (m n : with_bot ℕ) vs {m n : with_bot ℕ}

Eric Wieser (May 22 2022 at 12:22):

I suspect your question is actually "why does this get harder when I fully-expand the wildcard pattern", and the answer is something along the lines of "because now you have to do the same expansion in the proof

FR (May 22 2022 at 12:30):

import algebra.order.monoid

namespace implicit

def bar (m : with_bot ) : Type* := sorry

def foo' {m n : } (x : bar m) (y : bar n) :  := sorry

def foo :  {m n : with_bot }, bar m  bar n  
| (m : ) (n : ) := λ x y, foo' x y
| _       _       := λ _ _, 0

def mul :  {m n : with_bot }, bar m  bar n  bar (m + n) := sorry

lemma h {m₁ m₂ n : }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (mul x₁ x₂) y = foo x₁ y * foo x₂ y := sorry

example {m₁ m₂ n : with_bot }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (mul x₁ x₂) y = foo x₁ y * foo x₂ y :=
begin
  cases m₁; cases m₂; cases n; simp only [foo, nat.zero_mul, nat.mul_zero],
  exact h x₁ x₂ y,
end

end implicit

namespace explicit

def bar (m : with_bot ) : Type* := sorry

def foo' (m n : ) (x : bar m) (y : bar n) :  := sorry

def foo :  (m n : with_bot ), bar m  bar n  
| (m : ) (n : ) := λ x y, foo' m n x y
| _       _       := λ _ _, 0

def mul :  {m n : with_bot }, bar m  bar n  bar (m + n) := sorry

lemma h {m₁ m₂ n : }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (m₁ + m₂) n (mul x₁ x₂) y = foo m₁ n x₁ y * foo m₂ n x₂ y := sorry

example {m₁ m₂ n : with_bot }
  (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
    foo (m₁ + m₂) n (mul x₁ x₂) y = foo m₁ n x₁ y * foo m₂ n x₂ y :=
begin
  cases m₁; cases m₂; cases n; simp only [foo, nat.zero_mul, nat.mul_zero],
  exact h x₁ x₂ y,
end

end explicit

But this still fails?

FR (May 22 2022 at 12:37):

It seems that simp treats implicit parameters differently than explicit parameters.

Eric Wieser (May 22 2022 at 12:52):

Ah thanks, you're right!

Eric Wieser (May 22 2022 at 12:59):

A slightly shorter mwe:

import algebra.order.monoid

def bar (m : with_bot ) : Type* := sorry
def mul :  {m n : with_bot }, bar m  bar n  bar (m + n) := sorry
def foo' (m n : ) (x : bar m) (y : bar n) :  := sorry

namespace implicit

def foo :  {m n : with_bot }, bar m  bar n  
| (m : ) (n : ) := λ x y, foo' _ _ x y
| _       _       := λ _ _, 0

example {m₁ m₂ n : with_bot } (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
  foo (mul x₁ x₂) y = foo x₁ y * foo x₂ y :=
begin
  cases m₁; cases m₂; cases n,
  { simp only [foo, nat.zero_mul, nat.mul_zero], },
  all_goals { sorry }
end

end implicit

namespace explicit

def foo :  (m n : with_bot ), bar m  bar n  
| (m : ) (n : ) := λ x y, foo' m n x y
| _       _       := λ _ _, 0

example {m₁ m₂ n : with_bot } (x₁ : bar m₁) (x₂ : bar m₂) (y : bar n) :
  foo _ _ (mul x₁ x₂) y = foo _ _ x₁ y * foo _ _ x₂ y :=
begin
  cases m₁; cases m₂; cases n,
  { simp only [foo, nat.zero_mul, nat.mul_zero], },
  all_goals { sorry }
end

end explicit

FR (May 22 2022 at 15:30):

How should I get lean to do the same thing in the case of explicit parameters? simp ! can unfold it but this would also unfold other things.

Gabriel Ebner (May 22 2022 at 15:42):

simp uses reducible transparency for matching. With reducible transparency, a definition like (0 : with_bot ℕ) is not unfolded to some 0 because it is only semireducible.

Gabriel Ebner (May 22 2022 at 15:42):

However, there's a big exception. Implicit arguments get "upgraded" to semireducible transparency.

Gabriel Ebner (May 22 2022 at 15:42):

In other words, the following works with the implicit version but not the explicit version, because 0 = some 0 is only defeq with semireducible transparency:

example (x y) : @foo 0 0 x y = @foo (some 0) (some 0) x y :=
by tactic.reflexivity tactic.transparency.reducible

Last updated: Dec 20 2023 at 11:08 UTC