Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Names received using as-matching are not reduced under case #3370

Open
buzden opened this issue Aug 13, 2024 · 0 comments
Open

Names received using as-matching are not reduced under case #3370

buzden opened this issue Aug 13, 2024 · 0 comments

Comments

@buzden
Copy link
Contributor

buzden commented Aug 13, 2024

Steps to Reproduce

Consider the following piece of code:

v : (Nat, Nat)

g : Unit
g = do
  let xx@(x, y) = v
  let prf1 = the (fst xx = x) Refl
  let _ = case () of
            _ => do
              let prf2 = the (fst xx = x) Refl
              ()
  ()

It contains similar proofs of equality, basically checking that fst xx indeed reduces to its value.

Expected Behavior

I'd expect both of the proofs to typecheck.

Observed Behavior

First one typechecks but the second fails with

Error: While processing right hand side of g. Can't solve constraint between: x and fst xx.

DoesntReduceUnderCase:9:43--9:47
 5 |   let xx@(x, y) = v
 6 |   let prf1 = the (fst xx = x) Refl
 7 |   let _ = case () of
 8 |             _ => do
 9 |               let prf2 = the (fst xx = x) Refl
                                               ^^^^

showing that fst xx did not reduce.

Analysis

Lengthy thoughts

My guess is that this behaviour is due to the coding of case expressions as functions, and that this coding ignores as-matches. I.e., g is translated to something like

caseFunction : (Nat, Nat) -> Nat -> Nat -> Unit -> Unit
caseFunction xx x y _ = do
  let prf2 = the (fst xx = x) Refl
  ()

g : Unit
g = do
  let xx@(x, y) = v
  let prf1 = the (fst xx = x) Refl
  let _ = caseFunction xx x y ()
  ()

My guess is that repeating as-pattern match could be useful (however, I don't know if this is generally possible, e.g. inside with-clauses), i.e. to be coded something like this:

caseFunction : (Nat, Nat) -> Unit -> Unit
caseFunction xx@(x, y) _ = do
  let prf2 = the (fst xx = x) Refl
  ()

g : Unit
g = do
  let xx@(x, y) = v
  let prf1 = the (fst xx = x) Refl
  let _ = caseFunction xx ()
  ()

or this (to not to do repeated runtime pattern matching):

caseFunction : (xx : (Nat, Nat)) -> (x : Nat) -> (y : Nat) -> (0 _ : xx = (x, y)) -> Unit -> Unit
caseFunction xx@(x, y) x y Refl _ = do
  let prf2 = the (fst xx = x) Refl
  ()

g : Unit
g = do
  let xx@(x, y) = v
  let prf1 = the (fst xx = x) Refl
  let _ = caseFunction xx x y Refl ()
  ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant