Zulip Chat Archive

Stream: general

Topic: equation compiler match on variable


Kevin Buzzard (Jun 02 2022 at 17:36):

I don't know how to do this:

def f :    := λ x, x + 37

def foo (n : ) :   bool
| (f n) := tt
| _ := ff

The equation compiler complains :-( I can use if then else in my situation but I was hoping for better definitional equalities.

Kevin Buzzard (Jun 02 2022 at 17:37):

Note that

def foo (n : ) :   bool
| n := tt
| _ := ff

doesn't work because the equation compiler assumes n is a fresh variable, and thus always matches the first branch.

Alex J. Best (Jun 02 2022 at 17:37):

@[pattern]
def f :    := λ x, x + 37

def foo (n : ) :   bool
| (f n) := tt
| _ := ff

hope it works in a non-minimal example :wink:

Adam Topaz (Jun 02 2022 at 17:38):

Is this even possible?

Adam Topaz (Jun 02 2022 at 17:38):

(And I know why you need it Kevin, and I really do wish it actually is possible)

Kevin Buzzard (Jun 02 2022 at 17:40):

In my actual example, f n is just n - 1.

Alex J. Best (Jun 02 2022 at 17:42):

Kevin Buzzard said:

In my actual example, f n is just n - 1.

:frown: so looks like the solution doesn't work, do you need the truncating property of - exactly in this way?

Kevin Buzzard (Jun 02 2022 at 17:43):

Scott uses if then else in the definition of homological_complex.single in algebra/homology/single.lean:

{ obj := λ A,
  { X := λ i, if i = j then A else 0,
    d := λ i j, 0, },

and then later on defines single₀ "with better definitional equalities" in the special case j = 0, when he can use the equation compiler.

Adam Topaz (Jun 02 2022 at 17:44):

Yeah the benefit of single_0 is that (single_0.obj B).X 0 is defeq to B

Adam Topaz (Jun 02 2022 at 17:45):

Maybe we can try something approximately like this?

def foo :     
| 0 := λ k, match k with
  | 0 := 1
  | (i+1) := 0
  end
| (n+1) := λ k, match k with
  | 0 := 0
  | (i+1) := foo n i
  end

Adam Topaz (Jun 02 2022 at 17:49):

With that we get

example :  (n : ), foo n n = 1 :=
begin
  intros n,
  induction n,
  refl,
  assumption
end

Adam Topaz (Jun 02 2022 at 17:56):

import algebra.homology.homological_complex
import category_theory.abelian.basic

open category_theory
variables {A  : Type*} [category A] [abelian A]

open_locale zero_object

noncomputable
def single_X (B : A) :     A
| 0 0 := B
| 0 (k+1) := 0
| (n+1) 0 := 0
| (n+1) (k+1) := single_X n k

noncomputable
def single (B : A) (n : ) : chain_complex A  :=
{ X := single_X B n,
  d := λ i j, 0,
  shape' := sorry,
  d_comp_d' := sorry }

Adam Topaz (Jun 02 2022 at 18:11):

In the following code, why is the dsimp needed in the last branch of of_hom_d?

import algebra.homology.homological_complex
import category_theory.abelian.basic

open category_theory
variables {A  : Type*} [category A] [abelian A]

open_locale zero_object

noncomputable
def of_hom_X {X Y : A} (f : X  Y) :     A
| 0 0 := X
| 0 1 := Y
| 0 (k+2) := 0
| (n+1) 0 := 0
| (n+1) (k+1) := of_hom_X n k

noncomputable
def of_hom_d {X Y : A} (f : X  Y) : Π (n i j : ), of_hom_X f n i  of_hom_X f n j
| 0 0 0 := 0
| 0 0 1 := f
| 0 0 (k+2) := 0
| 0 (i+1) 0 := 0
| 0 (i+1) (j+1) := 0
| (n+1) 0 _ := 0
| (n+1) (i+1) 0 := 0
| (n+1) (i+1) (j+1) := by { dsimp [of_hom_X], exact of_hom_d n i j }

noncomputable
def of_hom {X Y : A} (f : X  Y) (n : ) : chain_complex A  :=
{ X := of_hom_X f n,
  d := of_hom_d f n,
  shape' := sorry,
  d_comp_d' := sorry }

Adam Topaz (Jun 02 2022 at 18:13):

Is this just a quirk of the equation compiler?

Adam Topaz (Jun 02 2022 at 19:04):

(For those in the know, those d's define a cochain complex, not a chain complex as indicated, but the issue is of course unrelated)

Kevin Buzzard (Jun 02 2022 at 19:55):

Even if you do it like this, single_X B n n = B won't be rfl, the proof term will have a nat.rec in it.

Adam Topaz (Jun 02 2022 at 19:57):

Yeah, you can make it rfl using the equation compiler.

Adam Topaz (Jun 02 2022 at 19:57):

Well, no, you're right, not rfl because you need induction.

Kevin Buzzard (Jun 02 2022 at 19:57):

For an explicit value of n you can, but not in general right?

Adam Topaz (Jun 02 2022 at 19:58):

Yeah you're right.

Kevin Buzzard (Jun 02 2022 at 19:58):

I am now using the eq_to_iso trick

Kevin Buzzard (Jun 02 2022 at 19:59):

Unless you know how to prove that cast (f >> g) = cast f >> cast g and cast 0 = 0...

Adam Topaz (Jun 02 2022 at 20:00):

No, I think that would be worse!

Adam Topaz (Jun 02 2022 at 20:01):

At least eq_to_iso is an iso which you can move around

Eric Wieser (Jun 02 2022 at 22:23):

This feels like a bug in the equation compiler to me:

def foo (n : ) :   bool
| .(n) := tt

Lean is happy to accept this, and is clearly not binding a new variable with the .(n) as .(bar) is forbidden; but it doesn't do the right thing.

Eric Wieser (Jun 02 2022 at 22:26):

Maybe I don't understand . notation:

def is_37 :   bool
| .(37) := tt

#eval is_37 1  -- tt

Kevin Buzzard (Jun 02 2022 at 22:33):

Yeah, Alex' code above doesn't work either, it matches on any n not the one which you want to match on.


Last updated: Dec 20 2023 at 11:08 UTC