Compare commits

...

9 Commits

Author SHA1 Message Date
Leonardo de Moura
4bdeeab2e8 chore: fix test 2024-02-13 10:05:00 -08:00
Leonardo de Moura
60e1555457 test: binder predicates 2024-02-13 10:00:57 -08:00
Leonardo de Moura
4b6b4000e7 chore: add binder_predicate declarations 2024-02-13 10:00:57 -08:00
Leonardo de Moura
653e445865 chore: update stage0 2024-02-13 10:00:57 -08:00
Leonardo de Moura
d5ff50e81f feat: builtin binder_predicate command 2024-02-13 10:00:52 -08:00
Leonardo de Moura
9210746a25 chore: update stage0 2024-02-13 09:45:56 -08:00
Leonardo de Moura
3d3bff8dd1 chore: disable Elab/BinderPredicates.lean before update stage0 2024-02-13 09:43:17 -08:00
Leonardo de Moura
67705435a9 feat: binderPredicate builtin parser 2024-02-13 09:41:23 -08:00
Scott Morrison
6157973fb3 chore: upstream Std.Util.ExtendedBinders 2024-02-13 22:51:03 +11:00
54 changed files with 128 additions and 0 deletions

View File

@@ -28,3 +28,4 @@ import Init.Conv
import Init.Guard
import Init.Simproc
import Init.SizeOfLemmas
import Init.BinderPredicates

View File

@@ -0,0 +1,58 @@
/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner
-/
prelude
import Init.NotationExtra
namespace Lean
/--
The syntax category of binder predicates contains predicates like `> 0`, `∈ s`, etc.
(`: t` should not be a binder predicate because it would clash with the built-in syntax for ∀/∃.)
-/
declare_syntax_cat binderPred
/--
`satisfies_binder_pred% t pred` expands to a proposition expressing that `t` satisfies `pred`.
-/
syntax "satisfies_binder_pred% " term:max binderPred : term
-- Extend ∀ and ∃ to binder predicates.
/--
The notation `∃ x < 2, p x` is shorthand for `∃ x, x < 2 ∧ p x`,
and similarly for other binary operators.
-/
syntax "" binderIdent binderPred ", " term : term
/--
The notation `∀ x < 2, p x` is shorthand for `∀ x, x < 2 → p x`,
and similarly for other binary operators.
-/
syntax "" binderIdent binderPred ", " term : term
macro_rules
| `( $x:ident $pred:binderPred, $p) =>
`( $x:ident, satisfies_binder_pred% $x $pred $p)
| `( _ $pred:binderPred, $p) =>
`( x, satisfies_binder_pred% x $pred $p)
macro_rules
| `( $x:ident $pred:binderPred, $p) =>
`( $x:ident, satisfies_binder_pred% $x $pred $p)
| `( _ $pred:binderPred, $p) =>
`( x, satisfies_binder_pred% x $pred $p)
/-- Declare `∃ x > y, ...` as syntax for `∃ x, x > y ∧ ...` -/
binder_predicate x " > " y:term => `($x > $y)
/-- Declare `∃ x ≥ y, ...` as syntax for `∃ x, x ≥ y ∧ ...` -/
binder_predicate x "" y:term => `($x $y)
/-- Declare `∃ x < y, ...` as syntax for `∃ x, x < y ∧ ...` -/
binder_predicate x " < " y:term => `($x < $y)
/-- Declare `∃ x ≤ y, ...` as syntax for `∃ x, x ≤ y ∧ ...` -/
binder_predicate x "" y:term => `($x $y)
/-- Declare `∃ x ≠ y, ...` as syntax for `∃ x, x ≠ y ∧ ...` -/
binder_predicate x "" y:term => `($x $y)
end Lean

View File

@@ -10,6 +10,7 @@ import Lean.Elab.Command
import Lean.Elab.Term
import Lean.Elab.App
import Lean.Elab.Binders
import Lean.Elab.BinderPredicates
import Lean.Elab.LetRec
import Lean.Elab.Frontend
import Lean.Elab.BuiltinNotation

View File

@@ -0,0 +1,41 @@
/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner
-/
import Lean.Parser.Syntax
import Lean.Elab.MacroArgUtil
import Lean.Linter.MissingDocs
namespace Lean.Elab.Command
@[builtin_command_elab binderPredicate] def elabBinderPred : CommandElab := fun stx => do
match stx with
| `($[$doc?:docComment]? $[@[$attrs?,*]]? $attrKind:attrKind binder_predicate%$tk
$[(name := $name?)]? $[(priority := $prio?)]? $x $args:macroArg* => $rhs) => do
let prio liftMacroM do evalOptPrio prio?
let (stxParts, patArgs) := ( args.mapM expandMacroArg).unzip
let name match name? with
| some name => pure name.getId
| none => liftMacroM do mkNameFromParserSyntax `binderTerm (mkNullNode stxParts)
let nameTk := name?.getD (mkIdentFrom tk name)
/- The command `syntax [<kind>] ...` adds the current namespace to the syntax node kind.
So, we must include current namespace when we create a pattern for the following
`macro_rules` commands. -/
let pat : TSyntax `binderPred := (mkNode (( getCurrNamespace) ++ name) patArgs).1
elabCommand <|<-
`($[$doc?:docComment]? $[@[$attrs?,*]]? $attrKind:attrKind syntax%$tk
(name := $nameTk) (priority := $(quote prio)) $[$stxParts]* : binderPred
$[$doc?:docComment]? macro_rules%$tk
| `(satisfies_binder_pred% $$($x):term $pat:binderPred) => $rhs)
| _ => throwUnsupportedSyntax
open Linter.MissingDocs Parser Term in
/-- Missing docs handler for `binder_predicate` -/
@[builtin_missing_docs_handler Lean.Parser.Command.binderPredicate]
def checkBinderPredicate : SimpleHandler := fun stx => do
if stx[0].isNone && stx[2][0][0].getKind != ``«local» then
if stx[4].isNone then lint stx[3] "binder predicate"
else lintNamed stx[4][0][3] "binder predicate"
end Lean.Elab.Command

View File

@@ -104,6 +104,16 @@ def elabTail := leading_parser atomic (" : " >> ident >> optional (" <= " >> ide
optional docComment >> optional Term.«attributes» >> Term.attrKind >>
"elab" >> optPrecedence >> optNamedName >> optNamedPrio >> many1 (ppSpace >> elabArg) >> elabTail
/--
Declares a binder predicate. For example:
```
binder_predicate x " > " y:term => `($x > $y)
```
-/
@[builtin_command_parser] def binderPredicate := leading_parser
optional docComment >> optional Term.attributes >> optional Term.attrKind >>
"binder_predicate" >> optNamedName >> optNamedPrio >> ppSpace >> ident >> many (ppSpace >> macroArg) >> " => " >> termParser
end Command
end Parser

BIN
stage0/stdlib/Init.c generated

Binary file not shown.

BIN
stage0/stdlib/Init/BinderPredicates.c generated Normal file

Binary file not shown.

Binary file not shown.

BIN
stage0/stdlib/Init/Guard.c generated Normal file

Binary file not shown.

Binary file not shown.

BIN
stage0/stdlib/Init/RCases.c generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
stage0/stdlib/Lean/Elab/BinderPredicates.c generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
stage0/stdlib/Lean/Elab/Tactic/Change.c generated Normal file

Binary file not shown.

BIN
stage0/stdlib/Lean/Elab/Tactic/Guard.c generated Normal file

Binary file not shown.

BIN
stage0/stdlib/Lean/Elab/Tactic/RCases.c generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,8 @@
#check x > 10, x = 15
#check x < 10, x = 5
#check x 10, x = 15
#check x 10, x = 5
#check x > 10, x 5
#check x < 10, x 15
#check x 10, x 5
#check x 10, x 15

View File

@@ -0,0 +1,8 @@
∃ x, x > 10 ∧ x = 15 : Prop
∃ x, x < 10 ∧ x = 5 : Prop
∃ x, x ≥ 10 ∧ x = 15 : Prop
∃ x, x ≤ 10 ∧ x = 5 : Prop
∀ (x : Nat), x > 10 → x ≠ 5 : Prop
∀ (x : Nat), x < 10 → x ≠ 15 : Prop
∀ (x : Nat), x ≥ 10 → x ≠ 5 : Prop
∀ (x : Nat), x ≤ 10 → x ≠ 15 : Prop

View File

@@ -2,6 +2,7 @@
"position": {"line": 4, "character": 10}}
{"items":
[{"label": "bin", "kind": 21, "detail": "Type 1"},
{"label": "binder_predicate", "kind": 14, "detail": "keyword"},
{"label": "binop%", "kind": 14, "detail": "keyword"},
{"label": "binop_lazy%", "kind": 14, "detail": "keyword"},
{"label": "binrel%", "kind": 14, "detail": "keyword"},