Full source
/-- Elaborate set builder notation for `Set`.
* `{x | p x}` is elaborated as `Set.setOf fun x ↦ p x`
* `{x : α | p x}` is elaborated as `Set.setOf fun x : α ↦ p x`
* `{binder x | p x}`, where `x` is bound by the `binder` binder, is elaborated as
`{x | binder x ∧ p x}`. The typical example is `{x ∈ s | p x}`, which is elaborated as
`{x | x ∈ s ∧ p x}`. The possible binders are
* `· ∈ s`, `· ∉ s`
* `· ⊆ s`, `· ⊂ s`, `· ⊇ s`, `· ⊃ s`
* `· ≤ a`, `· ≥ a`, `· < a`, `· > a`, `· ≠ a`
More binders can be declared using the `binder_predicate` command, see `Init.BinderPredicates` for
more info.
See also
* `Data.Finset.Basic` for the `Finset` builder notation elaborator partly overriding this one for
syntax of the form `{x ∈ s | p x}`.
* `Data.Fintype.Basic` for the `Finset` builder notation elaborator partly overriding this one for
syntax of the form `{x | p x}`, `{x : α | p x}`, `{x ∉ s | p x}`, `{x ≠ a | p x}`.
* `Order.LocallyFinite.Basic` for the `Finset` builder notation elaborator partly overriding this
one for syntax of the form `{x ≤ a | p x}`, `{x ≥ a | p x}`, `{x < a | p x}`, `{x > a | p x}`.
-/
@[term_elab setBuilder]
def elabSetBuilder : TermElab
| `({ $x:ident | $p }), expectedType? => do
elabTerm (← `(setOf fun $x:ident ↦ $p)) expectedType?
| `({ $x:ident : $t | $p }), expectedType? => do
elabTerm (← `(setOf fun $x:ident : $t ↦ $p)) expectedType?
| `({ $x:ident $b:binderPred | $p }), expectedType? => do
elabTerm (← `(setOf fun $x:ident ↦ satisfies_binder_pred% $x $b ∧ $p)) expectedType?
| _, _ => throwUnsupportedSyntax