Zulip Chat Archive

Stream: lean4

Topic: Buggy structure matching in monads


Gareth Ma (Nov 19 2023 at 23:12):

import Mathlib.Data.Nat.Basic

def works (a b : ) : ( × ) := Id.run do
  if h : (b % a) < a then
    let c := works (b % a) a
    return (a, c.2)
  else
    return (0, 1)

/- Two errors:
1. the `.match_1` (i.e. the `let (x, y) := ...`) is noncomputable
2. Well-foundedness is not proven automatically
-/
def fails (a b : ) : ( × ) := Id.run do
  if h : (b % a) < a then
    let (x, y) := fails (b % a) a
    return (a, y)
  else
    return (0, 1)

Gareth Ma (Nov 19 2023 at 23:13):

The structure matching makes the code noncomputable and makes determining well-foundedness fail, which sounds buggy to me.

Scott Morrison (Nov 20 2023 at 00:48):

Please try to post a #mwe (in particular, you have imports missing here, or need to replace ℕ with Nat, etc)

Scott Morrison (Nov 20 2023 at 00:53):

I suspect this is a known issue, but I'm not finding an open issue. Let me ping @Joachim Breitner, who has been working on recursion recently, and may know off-hand.

It would be good to have an issue tracking this. It should include also the non-monadic code, to show that the issue is specific to the do notation.

Scott Morrison (Nov 20 2023 at 00:53):

I think also your termination_by and decreasing_by clauses should be removed from the example.

Gareth Ma (Nov 20 2023 at 00:59):

Fixed both. I will wait for Joachim's response and one of us can open an issue then

Gareth Ma (Nov 20 2023 at 00:59):

I always forget that \N is not in Lean haha

Gareth Ma (Nov 20 2023 at 01:01):

Here's a non-monadic example:

def works_again (a b : ) :  ×  := by
  by_cases h : (b % a) < a
  · let x, y := works_again (b % a) a
    exact (a, y)
  · exact (0, 1)

Joachim Breitner (Nov 20 2023 at 10:16):

Marking it as noncomputable makes the well-foundness proof go through. Is that expected or strange?

This is the supposedly non-computable definition, looks computable to me:

def fails.match_1.{u_1} : (motive :  ×   Sort u_1)  (x :  × )  ((x : )  (y : )  motive (x, y))  motive x :=
fun motive x h_1 => Prod.casesOn x fun fst snd => h_1 fst snd

and

def foo := fails.match_1

doesn't complain about non-computability.

So maybe the problem is that these auxillary definitoins are not compiled early enough for something that’s happening in the well-foundedness proof?

I haven’t seen an issue about this (but I don't know all the issues); feel free to report (ideally minimized to have no imports)


Last updated: Dec 20 2023 at 11:08 UTC