-
Notifications
You must be signed in to change notification settings - Fork 234
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Data/Finsupp): add notation (#6367)
This PR provides `fun₀ | 3 => a | 7 => b` notation for `Finsupp`, which desugars to `Finsupp.update` and `Finsupp.single`, in the same way that `{a, b}` desugars to `insert` and `singleton`. It also provides a matching delaborator: as an example of the effect of this, `Finsupp.single_add` now shows as: ```lean Finsupp.single_add.{u_2, u_1} {α : Type u_1} {M : Type u_2} [inst✝ : AddZeroClass M] (a : α) (b₁ b₂ : M) : (fun₀ | a => b₁ + b₂) = (fun₀ | a => b₁) + fun₀ | a => b₂ ``` Finally, it provides a `Repr` instance; though this is somewhat misleading as the syntax that is produced by `Repr` isn't actually computable so can't round-trip! [Discussed on Zulip here](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Notation.20for.20.60Finsupp.60/near/381919585).
- Loading branch information
1 parent
2677935
commit a5c7037
Showing
4 changed files
with
89 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/- | ||
Copyright (c) 2023 Eric Wieser. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Eric Wieser | ||
-/ | ||
import Mathlib.Data.Finsupp.Defs | ||
|
||
/-! | ||
# Notation for `Finsupp` | ||
This file provides `fun₀ | 3 => a | 7 => b` notation for `Finsupp`, which desugars to | ||
`Finsupp.update` and `Finsupp.single`, in the same way that `{a, b}` desugars to `insert` and | ||
`singleton`. | ||
-/ | ||
|
||
namespace Finsupp | ||
|
||
open Lean | ||
open Lean.Parser | ||
open Lean.Parser.Term | ||
|
||
/-- A variant of `Lean.Parser.Term.matchAlts` with less line wrapping. -/ | ||
def fun₀.matchAlts : Parser := | ||
leading_parser withPosition $ ppRealGroup <| many1Indent (ppSpace >> ppGroup matchAlt) | ||
|
||
@[term_parser, inherit_doc Finsupp] | ||
def fun₀ := leading_parser:maxPrec | ||
ppAllowUngrouped >> unicodeSymbol "λ₀" "fun₀" >> fun₀.matchAlts | ||
|
||
macro_rules | ||
| `(term| fun₀ $x:matchAlt*) => do | ||
let mut stx : Term ← `(0) | ||
let mut fst : Bool := true | ||
for xi in x do | ||
for xii in (← Elab.Term.expandMatchAlt xi) do | ||
match xii with | ||
| `(matchAltExpr| | $pat => $val) => | ||
if fst then | ||
stx ← `(Finsupp.single $pat $val) | ||
else | ||
stx ← `(Finsupp.update $stx $pat $val) | ||
fst := false | ||
| _ => Macro.throwUnsupported | ||
pure stx | ||
|
||
/-- Unexpander for the `fun₀ | i => x` notation. -/ | ||
@[app_unexpander Finsupp.single] | ||
def singleUnexpander : Lean.PrettyPrinter.Unexpander | ||
| `($_ $pat $val) => `(fun₀ | $pat => $val) | ||
| _ => throw () | ||
|
||
/-- Unexpander for the `fun₀ | i => x` notation. -/ | ||
@[app_unexpander Finsupp.update] | ||
def updateUnexpander : Lean.PrettyPrinter.Unexpander | ||
| `($_ $f $pat $val) => match f with | ||
| `(fun₀ $xs:matchAlt*) => `(fun₀ $xs:matchAlt* | $pat => $val) | ||
| _ => throw () | ||
| _ => throw () | ||
|
||
/-- Display `Finsupp` using `fun₀` notation. -/ | ||
unsafe instance {α β} [Repr α] [Repr β] [Zero β] : Repr (α →₀ β) where | ||
reprPrec f p := | ||
if f.support.card = 0 then | ||
"0" | ||
else | ||
let ret := "fun₀" ++ | ||
Std.Format.join (f.support.val.unquot.map <| | ||
fun a => " | " ++ repr a ++ " => " ++ repr (f a)) | ||
if p ≥ leadPrec then Format.paren ret else ret | ||
|
||
end Finsupp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import Mathlib.Data.Finsupp.Notation | ||
|
||
example : (fun₀ | 1 => 3) 1 = 3 := | ||
by simp | ||
|
||
example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 1 = 3 := | ||
by simp | ||
example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 2 = 3 := | ||
by simp | ||
example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 3 = 4 := | ||
by simp | ||
|
||
#eval show Lean.MetaM Unit from | ||
guard <| | ||
reprStr (Finsupp.mk {1, 2} (fun | 1 | 2 => 3 | _ => 0) (fun x => by aesop)) | ||
= "fun₀ | 1 => 3 | 2 => 3" |