Zulip Chat Archive

Stream: Is there code for X?

Topic: How to handle dependent type on Nat?


Kenny Lau (Jul 09 2025 at 15:15):

import Mathlib

abbrev g :   Type := fun _  
def gMul (i j : ) : g i  g j  g (i + j) := sorry

abbrev g' :   Type := fun _  
def gMul' (i j : ) : g' i  g' j  g' (i + j) := sorry

def map (i : ) : g i  g' i := fun x  x / i

@[simp] lemma map_gMul (i j : ) (x : g i) (y : g j) :
    map (i + j) (gMul i j x y) = gMul' i j (map i x) (map i y) := sorry

def component : g 1 := 3
def big : g 2 := gMul 1 1 component component

@[simp] lemma map_component : map 1 component = 0 := sorry
@[simp] lemma gMul'_eq_zero (i j x y) : gMul' i j x y = 0 := sorry

lemma map_big : map 2 big = 0 := by
  simp [big] -- fails to close the goal
  -- ⊢ map 2 (gMul 1 1 component component) = 0
  simp [map_gMul 1 1] -- works

I have this graded ring structure on my personal repo, which I've minimised to the code above.

My problem here is that the simp lemma map_gMul doesn't match the goal normally (because 1 + 1 is not 2 :shock: ), and I'll have to provide it the custom indices 1 1 to make it work. What's the best way to solve this?

Eric Wieser (Jul 09 2025 at 15:33):

I assume you're aware of docs#GradedMonoid.GMonoid ?

Kenny Lau (Jul 09 2025 at 15:41):

ah, i kept it at the back of my head and then forgot it; but how does this get rid of the problem that 2 is not 1+1?

Jz Pan (Jul 09 2025 at 16:46):

Kenny Lau said:

how does this get rid of the problem that 2 is not 1+1?

I don't think this problem has things to do with dependent type. Even the type is not dependent, your simp [big] is not working:

import Mathlib

abbrev g := 
def gMul (i j : ) : g  g  g := sorry

abbrev g' := 
def gMul' (i j : ) : g'  g'  g' := sorry

def map (i : ) : g  g' := fun x  x / i

@[simp] lemma map_gMul (i j : ) (x y : g) :
    map (i + j) (gMul i j x y) = gMul' i j (map i x) (map i y) := sorry

def component : g := 3
def big : g := gMul 1 1 component component

@[simp] lemma map_component : map 1 component = 0 := sorry
@[simp] lemma gMul'_eq_zero (i j x y) : gMul' i j x y = 0 := sorry

lemma map_big : map 2 big = 0 := by
  simp [big] -- fails to close the goal
  -- ⊢ map 2 (gMul 1 1 component component) = 0
  simp [map_gMul 1 1] -- works

Eric Wieser (Jul 09 2025 at 16:47):

I think your example is a little too contrived; ideally the types would actually be dependent

Jz Pan (Jul 09 2025 at 16:49):

Note that rw [map_gMul] following simp [big] is also not working. You need rw [map_gMul 1 1] or erw [map_gMul] to make it work.

Jz Pan (Jul 09 2025 at 16:51):

erw also works in the original example

Kenny Lau (Jul 09 2025 at 17:05):

Eric Wieser said:

I think your example is a little too contrived; ideally the types would actually be dependent

well... that's the spirit behind #mwe :upside_down:

Kenny Lau (Jul 09 2025 at 17:06):

so is there a known solution?

Jz Pan (Jul 09 2025 at 18:28):

I don't think so; seems that this is because the distinction between rw and erw...

My solution would be simp [big, show 2 = 1 + 1 from rfl] (untested)

Aaron Liu (Jul 09 2025 at 18:30):

that sounds like it will loop

Jz Pan (Jul 09 2025 at 18:32):

Oh, 1 + 1 = 2 is a simp lemma

Ruben Van de Velde (Jul 09 2025 at 18:33):

simp [← one_add_one_eq_two], maybe

Kenny Lau (Jul 09 2025 at 18:35):

well i have 2+1 in my example too

Kenny Lau (Jul 09 2025 at 18:36):

is there a way to write a simp procedure to look at the three natural number expressions %k %i %j and try to prove %k = %i + %j by rfl?

Aaron Liu (Jul 09 2025 at 18:37):

there's already a simproc that does the other way around so you'll be fighting it

Kenny Lau (Jul 09 2025 at 18:37):

i meant, in the context of this lemma

Kenny Lau (Jul 09 2025 at 18:38):

so it only activates when it sees map %k (x : g %i) (y : g %j)

Aaron Liu (Jul 09 2025 at 18:39):

that could work

Ruben Van de Velde (Jul 09 2025 at 18:39):

You could do this:

import Mathlib

abbrev g := 
def gMul (i j : ) : g  g  g := sorry

abbrev g' := 
def gMul' (i j : ) : g'  g'  g' := sorry

def map (i : ) : g  g' := fun x  x / i

@[simp] lemma map_gMul (i j : ) (x y : g) :
    map (i + j) (gMul i j x y) = gMul' i j (map i x) (map i y) := sorry

lemma map_gMul_of_eq (i j k : ) (x y : g) (hk : k = i + j) :
    map k (gMul i j x y) = gMul' i j (map i x) (map i y) := by
  subst k
  apply map_gMul

def component : g := 3
def big : g := gMul 1 1 component component

@[simp] lemma map_component : map 1 component = 0 := sorry
@[simp] lemma gMul'_eq_zero (i j x y) : gMul' i j x y = 0 := sorry

lemma map_big : map 2 big = 0 := by
  simp [big, map_gMul_of_eq] -- works

(I didn't expect it to just work like that, but maybe that's the simproc mentioned above)

Kenny Lau (Jul 09 2025 at 18:43):

@Ruben Van de Velde except that that example has been minimised (by others) to get rid of the dependent type; if you tried to do this in my original example you'll end up with a type error

Ruben Van de Velde (Jul 09 2025 at 18:53):

Well, then you need to unminimize it :)

Kenny Lau (Jul 09 2025 at 19:00):

@Ruben Van de Velde

import Mathlib

abbrev g :   Type := fun n  Vector  n
def gMul (i j : ) : g i  g j  g (i + j) := sorry

abbrev g' :   Type := fun n  Vector  n
def gMul' (i j : ) : g' i  g' j  g' (i + j) := sorry

instance : Zero (g' n) where
  zero := Vector.mk (Array.mk (List.iterate id 0 n)) (by simp)

def map (i : ) : g i  g' i := fun v  v.map (fun x :   x / i)

@[simp] lemma map_gMul (i j : ) (x : g i) (y : g j) :
    map (i + j) (gMul i j x y) = gMul' i j (map i x) (map j y) := sorry

lemma map_gMul_of_eq (i j k : ) (x : g i) (y : g j) (hk : k = i + j) :
    map k (gMul i j x y) = gMul' i j (map i x) (map j y) := by
  subst k
  apply map_gMul

def component : g 1 := Vector.mk (Array.mk [3]) rfl
def big : g 2 := gMul 1 1 component component

@[simp] lemma map_component : map 1 component = 0 := sorry
@[simp] lemma gMul'_eq_zero (i j x y) : gMul' i j x y = 0 := sorry

lemma map_big : map 2 big = 0 := by
  simp [big] -- fails to close the goal
  -- ⊢ map 2 (gMul 1 1 component component) = 0
  simp [map_gMul 1 1] -- works

Kenny Lau (Jul 09 2025 at 21:08):

Eric Wieser said:

I assume you're aware of docs#GradedMonoid.GMonoid ?

now I have an idea in my head of how to make this all work using the sigma type, lemme try it...

Kenny Lau (Jul 09 2025 at 21:10):

in particular, I have a proposal to (the underlying thing would be a graded algebra, but I want to always keep it homogeneous):

  1. Only ever multiply things together in the sigma type
  2. Only ever add things together in the individual modules

Kenny Lau (Jul 09 2025 at 23:18):

Update: it almost worked, if not for the fact that GradedMonoid.snd_mul is tagged with @[simp], and I don't know if attribute [-simp] is a good idea...


Last updated: Dec 20 2025 at 21:32 UTC