Zulip Chat Archive

Stream: lean4

Topic: Type Mismatch when Simplifying Constants


David Pearce (May 20 2024 at 23:26):

I've encountered an unexpected type mismatch issue. Here's a simplified example:

abbrev UInt4 := Fin 16
abbrev U4_MAX : UInt4 := {val:=15, isLt:=(by simp_arith)}

@[simp]
def sum(items: List (Fin n))(p:n>0) : Fin n :=
  match items with
  | h::t => h + (sum t p)
  | [] => {val:=0, isLt:=(by simp_arith [p])}

example(p:16>0) : sum (1::2::[]) p = 3  :=
by
  simp_arith

This works fine, and just illustrates the setup. So then I want to add another test ...

example(p:16>0) : sum (1::U4_MAX::[]) p = 0  :=
by
  --unfold U4_MAX
  simp_arith

Now, the proof appears to go through OK but Lean is reporting this error:

src/test.lean:15:0: error: application type mismatch
  List.cons (Fin.add 1 (U4_MAX + 0))
argument has type
  Fin 16
but function has type
  Nat  List Nat  List Nat

I figured out two solutions. Firstly, we can manually unfold U4_MAX (as illustrated by the comment); or, we can annotate U4_MAX with @[simp]. But, I don't understand why I need to do this? I might understand better if U4_MAX was a def ... ?

Kyle Miller (May 21 2024 at 00:46):

I'm not seeing an error locally. Which version of Lean are you using? (#eval Lean.versionString)

David Pearce (May 21 2024 at 00:47):

Lean (version 4.7.0, x86_64-unknown-linux-gnu, commit 6fce8f7d5cd1, Release

Kyle Miller (May 21 2024 at 00:49):

I'm using 4.8.0-rc1

Kyle Miller (May 21 2024 at 00:49):

By the way, here's a way to handle the positivity condition:

abbrev UInt4 := Fin 16
abbrev U4_MAX : UInt4 := {val:=15, isLt:=(by simp_arith)}

@[simp]
def sum (items : List (Fin (n + 1))) : Fin (n + 1) :=
  items.foldl (init := 0) (· + ·)

example : sum (1::2::[]) = (3 : UInt4)  :=
by
  simp_arith

example : sum (1::U4_MAX::[]) = 0  :=
by
  simp_arith

David Pearce (May 21 2024 at 00:50):

Hmmm... well I can try upgrading I suppose

Kyle Miller (May 21 2024 at 00:50):

(Also, I used a fold, but that's not necessary. The main thing is that (0 : Fin (n + 1)) works without needing to pass a proof.)

David Pearce (May 21 2024 at 00:50):

Ah, I see ... yeah neat Fin (n + 1).

Kyle Miller (May 21 2024 at 00:52):

A risk with Fin (n + 1) is that if you're dealing with complicated expressions (you're not here to be clear -- the 16 in Fin 16 is very simple) then unifying against n + 1 can trigger a potentially expensive calculation. It's perfectly fine for fixed-width numeric types like this.

David Pearce (May 21 2024 at 00:53):

Well, my real code is working against UInt256 ... how does that stack up ?

Kyle Miller (May 21 2024 at 00:53):

(You might also like to know that set_option pp.numericTypes true shows all the types of all the numeric literals. Just mentioning it in case it's eventually useful.)

Kyle Miller (May 21 2024 at 00:54):

That's mod 2 ^ 256? Should be fine.

David Pearce (May 21 2024 at 00:55):

Yes, U256_MAX is defined as:

abbrev U256_MAX : UInt256 := {val:=(2^256) - 1, isLt:=(by simp_arith)}

David Pearce (May 21 2024 at 00:56):

The set_option doesn't seem to make heaps of difference in VS Code (though some)

David Pearce (May 21 2024 at 00:56):

Ah, I see in the error messages though it makes a difference

Kyle Miller (May 21 2024 at 01:01):

It affects the Infoview too

Kyle Miller (May 21 2024 at 01:02):

Regarding your first error, I would guess that adding some type ascriptions somewhere, like

example(p:16>0) : sum (1::U4_MAX::[]) p = (0 : UInt4)  := ...

would make a difference, if you don't want to upgrade.

David Pearce (May 21 2024 at 01:04):

Hmmm, no still fails:

example(p:16>0) : sum (1::U4_MAX::[]) p = (0 : UInt4)  :=
by
  --unfold U4_MAX
  simp_arith

Kyle Miller (May 21 2024 at 01:07):

I'm wondering if you happen to have anything else in context? If you copy your mwe into a fresh file, do you still see the error? (I'm wondering in particular if there's another sum that's conflicting with yours somehow...)

David Pearce (May 21 2024 at 01:07):

I can try that now

David Pearce (May 21 2024 at 01:10):

Hmmm, I don't think that's it. Moving into a different workspace which is essentially empty, and same thing. I'm running lean directly against the test.lean file. Also, moving out of any existing lean workspace ... same thing.

Kyle Miller (May 21 2024 at 01:11):

Last guess, maybe sum ((1 : UInt4)::U4_MAX::[]) p = (0 : UInt4)?

Kyle Miller (May 21 2024 at 01:13):

Oh, sorry, I didn't understand what sort of error you were reporting. You're saying that simp_arith itself isn't reporting the error, right? Is the error on example?

David Pearce (May 21 2024 at 01:13):

Oh, so wierd. Just pushing through the change to use Fin (n+1). Here's it working nicely:

bbrev UInt4 := Fin 16
abbrev U4_MAX : UInt4 := {val:=15, isLt:=(by simp_arith)}

@[simp]
def sum(items: List (Fin (n+1))): Fin (n+1) :=
  match items with
  | h::t => h + (sum t)
  | [] => {val:=0, isLt:=(by simp_arith)}

example : sum (1::2::[]) = (3:UInt4)  :=
by
  simp_arith

example : sum (1::U4_MAX::[]) = 0  :=
by
  simp_arith

Its strange though as don't need a type for 0 but do need one now for 3 in the first example!!

David Pearce (May 21 2024 at 01:14):

sum ((1 : UInt4)::U4_MAX::[]) p = (0 : UInt4)

I tried a bunch of this stuff. I understand its having problem inferring the correct type.

Kyle Miller (May 21 2024 at 01:15):

Is the error on example?

If this is the case, that means there was an error inside of simp_arith itself. There have been some bug fixes there since 4.7.0

David Pearce (May 21 2024 at 01:15):

Yes, the error was underlying example.

David Pearce (May 21 2024 at 01:15):

Almost like an internal error

Kyle Miller (May 21 2024 at 01:16):

Yes, definitely an internal error. It's saying that the proof generated by simp_arith was type incorrect.

David Pearce (May 21 2024 at 01:17):

Right, ok. I didn't understand fully what it was complaining about :joy:

David Pearce (May 21 2024 at 01:18):

Thanks

Kyle Miller (May 21 2024 at 01:19):

Error messages are still being improved! Don't be shy bringing up any that don't make sense.


Last updated: May 02 2025 at 03:31 UTC