Zulip Chat Archive
Stream: lean4
Topic: mix and match matching on Syntax
Damiano Testa (May 04 2024 at 14:02):
Below, you can see the two ways in which I typically match on syntax. Is there a way of mixing the two matchings in a single pattern?
import Lean
open Lean Elab Command
-- works and can be extended by more `(...)
example : Syntax → Syntax
| s@`(a + b) => s
| s => s
-- works and can be extended by more .atom, .node, ...
example : Syntax → Syntax
| .ident _ _ v _ => mkIdent v
| s => s
-- does not work
example : Syntax → Syntax
| s@`(a + b) => s
| .ident _ _ v _ => mkIdent v
| s => s
/-
match (syntax) : unexpected pattern kind .ident _ _ v _
-/
Eric Wieser (May 04 2024 at 14:08):
(and similarly for TSyntax
with ⟨.ident _ _ _ _⟩
)
Damiano Testa (May 04 2024 at 14:10):
I am comforted that one of the native Lean-speakers does not know of this feature! :smile:
Eric Wieser (May 04 2024 at 14:11):
I'm pretty sure it's just missing, for the same reason that I think you can't match on syntax and other arguments at the same time?
Damiano Testa (May 04 2024 at 14:11):
Ah, that I never tried!
Eric Wieser (May 04 2024 at 14:12):
I bet you can trick it by adding a ~q
match to the same match
Damiano Testa (May 04 2024 at 14:14):
I am not sure that I understand what you have in mind, but both of these work:
-- works
example : Syntax → Unit → Unit
| s, t => t
-- works
example (s : Syntax) (u : Unit) : Unit :=
match s, u with
| .node .., t => t
| _, t => t
Eric Wieser (May 04 2024 at 14:14):
Does the one with a syntax antiquotation match work?
Damiano Testa (May 04 2024 at 14:15):
I think so:
-- works
example (s : Syntax) (u : Unit) : Unit :=
match s, u with
| `(a + b), t => t
| _, t => t
seems to work.
Damiano Testa (May 04 2024 at 14:15):
I wonder what happens if you match on two syntaxes, one with anti-quotations on one with constructors...
Damiano Testa (May 04 2024 at 21:59):
Ok, for completeness, this is what happens:
open Lean
-- does not work
example : Syntax → Syntax → Unit
| `(a + b), .node .. => ()
| _, t => ()
-- does not work
example : Syntax → Syntax → Unit
| .node .., `(a + b) => ()
| _, _ => ()
-- works
example : Syntax → Syntax → Unit
| .node .., .node .. => ()
| _, _ => ()
-- works
example : Syntax → Syntax → Unit
| `(a * b), `(a + b) => ()
| _, _ => ()
Mario Carneiro (May 04 2024 at 22:01):
This will require rearchitecting the way match works to fix
Damiano Testa (May 04 2024 at 22:02):
Ok, it is not that important: the constructor matching works, it is just more verbose at times.
Mario Carneiro (May 04 2024 at 22:03):
you can usually refactor it into separate matches to get the desired mix and match
Eric Wieser (May 04 2024 at 23:07):
Eric Wieser said:
I bet you can trick it by adding a
~q
match to the same match
Yep:
import Qq
open Lean Qq
-- works
example (s1 : Syntax) (s2 : Syntax) : MetaM Unit :=
match s1, s2, q(trivial) with
| `(a + b), .node .., ~q(trivial) => return ()
| _, t, _ => return ()
-- works
example (s1 : Syntax) (s2 : Syntax) : MetaM Unit :=
match s1, s2, q(trivial) with
| .node .., `(a + b), ~q(trivial) => return ()
| _, _, _ => return ()
Eric Wieser (May 04 2024 at 23:09):
Damiano Testa said:
I think so:
-- works example (s : Syntax) (u : Unit) : Unit := match s, u with | `(a + b), t => t | _, t => t
seems to work.
This fails if you replace t =>
with () => ()
(or any other pattern that actually does work); so I think my original claim is basically correct
Last updated: May 02 2025 at 03:31 UTC