Zulip Chat Archive

Stream: lean4

Topic: Pattern matching in let not substituting


Eric Wieser (Dec 10 2023 at 15:49):

Is this intended behavior?

example (n : Nat) (i : Fin n) : Option (Fin 3) := do
  let 3 := n | failure
  return i -- fails, pattern match did not substitute in hypothesis

example (n : Nat) (i : Fin 3) : Option (Fin n) := do
  let 3 := n | failure
  return i -- fails, pattern match did not substitute in goal

I thought let was suitable as a substitute for all single-arm matches, which work fine:

example (n : Nat) (i : Fin n) : Option (Fin 3) := do
  match n with
  | 3 => return i -- ok
  | _ => failure

example (n : Nat) (i : Fin 3) : Option (Fin n) := do
  match n with
  | 3 => return i -- ok
  | _ => failure

Damiano Testa (Dec 10 2023 at 15:58):

Does if let work there?

Eric Wieser (Dec 10 2023 at 16:04):

Yes!

example (n : Nat) (i : Fin n) : Option (Fin 3) := do
  if let 3 := n then
    return i
  else
    failure

example (n : Nat) (i : Fin 3) : Option (Fin n) := do
  if let 3 := n then
    return i
  else
    failure

(but this doesn't help with fixing quote4#29, since Qq uses only the let $path := $rhs version internally)

Damiano Testa (Dec 10 2023 at 16:09):

Too bad that it isn't helpful for your intended application.

I do find if let convenient sometimes, though.

Eric Wieser (Dec 12 2023 at 00:10):

Where exactly is pattern matching let implemented in core? If it's implemented in terms of match, can this be fixed simply by turning on the generalization flag? Or is there some reason related to do notation magic that this can't really work?

Kyle Miller (Dec 12 2023 at 00:25):

For do notation, there are two kinds of pattern-matching let. The first is the one that always succeeds (look for doLet in the source) and it seems to expand to the term let, and term let with a pattern expands to use a match. The second is the one with a failure case (doLetElse), and it expands your let 3 := n | failure to let __discr := n; match __discr with | 3 => ...continuation... | _ => failure

Kyle Miller (Dec 12 2023 at 00:25):

Maybe the match isn't generalizing through the __discr? I'm not sure why there's that let there and it's not match n with ...

Kyle Miller (Dec 12 2023 at 00:28):

docs#Lean.Elab.Term.Do.ToCodeBlock.doLetElseToCode

Kyle Miller (Dec 12 2023 at 00:30):

My guesses are that either it's to be consistent with arrow assign for mutable variables, or it's copy-paste from code for arrow assign and disabling generalization with this extra let isn't intentional.

Eric Wieser (Dec 12 2023 at 00:32):

Thanks!

Eric Wieser (Dec 12 2023 at 00:39):

I guess I'll try a patch later this week to see what happens, based on assuming the second option, unless you beat me to it!

Eric Wieser (Dec 13 2023 at 13:20):

(testing in lean4#3060, will clean up with a proper PR description if it succeeds)

Eric Wieser (Dec 15 2023 at 13:26):

Just to confirm, everything seems to work with this patch; though it seems no mathlib CI is attempted.

Joachim Breitner (Dec 15 2023 at 14:15):

We had some hickups with the PR testig workflow recently, mostly my fault. If you merge origin/nightly-with-mathlib into your branch and push, it should run the mathlib CI :fingers_crossed:

Eric Wieser (Dec 15 2023 at 22:49):

Thanks, it's running now and exposed a latent quote4 bug (but otherwise passes!)


Last updated: Dec 20 2023 at 11:08 UTC