feat(frontends/lean): modify syntax for local notation
The idea is to make it uniform with the syntax for defining local attributes.
This commit is contained in:
parent
b4d6f6e3ed
commit
e2c41fca75
14 changed files with 75 additions and 69 deletions
|
@ -15,9 +15,9 @@ namespace binary
|
|||
variable {A : Type}
|
||||
variables (op₁ : A → A → A) (inv : A → A) (one : A)
|
||||
|
||||
notation [local] a * b := op₁ a b
|
||||
notation [local] a ⁻¹ := inv a
|
||||
notation [local] 1 := one
|
||||
local notation a * b := op₁ a b
|
||||
local notation a ⁻¹ := inv a
|
||||
local notation 1 := one
|
||||
|
||||
definition commutative := ∀a b, a*b = b*a
|
||||
definition associative := ∀a b c, (a*b)*c = a*(b*c)
|
||||
|
@ -35,7 +35,7 @@ namespace binary
|
|||
|
||||
variable (op₂ : A → A → A)
|
||||
|
||||
notation [local] a + b := op₂ a b
|
||||
local notation a + b := op₂ a b
|
||||
|
||||
definition left_distributive := ∀a b c, a * (b + c) = a * b + a * c
|
||||
definition right_distributive := ∀a b c, (a + b) * c = a * c + b * c
|
||||
|
|
|
@ -10,7 +10,7 @@ import init.logic
|
|||
-- We need some of the following definitions asap when "initializing" Lean.
|
||||
|
||||
variables {A B : Type} (R : B → B → Type)
|
||||
infix [local] `≺`:50 := R
|
||||
local infix `≺`:50 := R
|
||||
|
||||
definition reflexive := ∀x, x ≺ x
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import types.prod
|
|||
open eq sigma sigma.ops equiv is_equiv
|
||||
|
||||
namespace sigma
|
||||
infixr [local] ∘ := function.compose --remove
|
||||
local infixr ∘ := function.compose --remove
|
||||
variables {A A' : Type} {B : A → Type} {B' : A' → Type} {C : Πa, B a → Type}
|
||||
{D : Πa b, C a b → Type}
|
||||
{a a' a'' : A} {b b₁ b₂ : B a} {b' : B a'} {b'' : B a''} {u v w : Σa, B a}
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace binary
|
|||
variable {A : Type}
|
||||
variables (op₁ : A → A → A) (inv : A → A) (one : A)
|
||||
|
||||
notation [local] a * b := op₁ a b
|
||||
notation [local] a ⁻¹ := inv a
|
||||
notation [local] 1 := one
|
||||
local notation a * b := op₁ a b
|
||||
local notation a ⁻¹ := inv a
|
||||
local notation 1 := one
|
||||
|
||||
definition commutative := ∀a b, a * b = b * a
|
||||
definition associative := ∀a b c, (a * b) * c = a * (b * c)
|
||||
|
@ -36,7 +36,7 @@ namespace binary
|
|||
|
||||
variable (op₂ : A → A → A)
|
||||
|
||||
notation [local] a + b := op₂ a b
|
||||
local notation a + b := op₂ a b
|
||||
|
||||
definition left_distributive := ∀a b c, a * (b + c) = a * b + a * c
|
||||
definition right_distributive := ∀a b c, (a + b) * c = a * c + b * c
|
||||
|
|
|
@ -151,7 +151,7 @@ cases_on a
|
|||
|
||||
definition equiv (p q : ℕ × ℕ) : Prop := pr1 p + pr2 q = pr2 p + pr1 q
|
||||
|
||||
notation [local] p `≡` q := equiv p q
|
||||
local notation p `≡` q := equiv p q
|
||||
|
||||
theorem equiv.refl {p : ℕ × ℕ} : p ≡ p := !add.comm
|
||||
|
||||
|
|
|
@ -334,7 +334,7 @@ private definition pair_nat.lt.wf : well_founded pair_nat.lt :=
|
|||
intro_k (measure.wf pr₂) 20 -- we use intro_k to be able to execute gcd efficiently in the kernel
|
||||
|
||||
local attribute pair_nat.lt.wf [instance] -- instance will not be saved in .olean
|
||||
infixl [local] `≺`:50 := pair_nat.lt
|
||||
local infixl `≺`:50 := pair_nat.lt
|
||||
|
||||
private definition gcd.lt.dec (x y₁ : nat) : (succ y₁, x mod succ y₁) ≺ (x, succ y₁) :=
|
||||
mod_lt (succ_pos y₁)
|
||||
|
|
|
@ -12,7 +12,7 @@ import init.logic
|
|||
-- We need some of the following definitions asap when "initializing" Lean.
|
||||
|
||||
variables {A B : Type} (R : B → B → Prop)
|
||||
infix [local] `≺`:50 := R
|
||||
local infix `≺`:50 := R
|
||||
|
||||
definition reflexive := ∀x, x ≺ x
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
;; modifiers
|
||||
(,(rx (or "\[persistent\]" "\[notation\]" "\[visible\]" "\[instance\]" "\[class\]" "\[parsing-only\]"
|
||||
"\[coercion\]" "\[reducible\]" "\[irreducible\]" "\[wf\]" "\[whnf\]" "\[multiple-instances\]"
|
||||
"\[decls\]" "\[strict\]" "\[local\]" "\[coercions\]" "\[classes\]" "\[notations\]" "\[tactic_hints\]" "\[reduce_hints\]"))
|
||||
"\[decls\]" "\[strict\]" "\[coercions\]" "\[classes\]" "\[notations\]" "\[tactic_hints\]" "\[reduce_hints\]"))
|
||||
. 'font-lock-doc-face)
|
||||
(,(rx "\[priority" (zero-or-more (not (any "\]"))) "\]") . font-lock-doc-face)
|
||||
;; tactics
|
||||
|
|
|
@ -610,15 +610,11 @@ static environment add_user_token(environment const & env, char const * val, uns
|
|||
}
|
||||
|
||||
struct notation_modifiers {
|
||||
bool m_persistent;
|
||||
bool m_parse_only;
|
||||
notation_modifiers():m_persistent(true), m_parse_only(false) {}
|
||||
notation_modifiers():m_parse_only(false) {}
|
||||
void parse(parser & p) {
|
||||
while (true) {
|
||||
if (p.curr_is_token(get_local_tk())) {
|
||||
p.next();
|
||||
m_persistent = false;
|
||||
} else if (p.curr_is_token(get_parsing_only_tk())) {
|
||||
if (p.curr_is_token(get_parsing_only_tk())) {
|
||||
p.next();
|
||||
m_parse_only = true;
|
||||
} else {
|
||||
|
@ -628,93 +624,108 @@ struct notation_modifiers {
|
|||
}
|
||||
};
|
||||
|
||||
static environment notation_cmd_core(parser & p, bool overload, bool reserve) {
|
||||
check_not_in_parametric_section(p);
|
||||
static environment notation_cmd_core(parser & p, bool overload, bool reserve, bool persistent) {
|
||||
if (persistent)
|
||||
check_not_in_parametric_section(p);
|
||||
notation_modifiers mods;
|
||||
mods.parse(p);
|
||||
flet<bool> set_allow_local(g_allow_local, in_context(p.env()) || !mods.m_persistent);
|
||||
flet<bool> set_allow_local(g_allow_local, in_context(p.env()) || !persistent);
|
||||
environment env = p.env();
|
||||
buffer<token_entry> new_tokens;
|
||||
auto ne = parse_notation_core(p, overload, reserve, new_tokens, mods.m_parse_only);
|
||||
for (auto const & te : new_tokens)
|
||||
env = add_user_token(env, te, mods.m_persistent);
|
||||
env = add_notation(env, ne, mods.m_persistent);
|
||||
env = add_user_token(env, te, persistent);
|
||||
env = add_notation(env, ne, persistent);
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment mixfix_cmd(parser & p, mixfix_kind k, bool overload, bool reserve) {
|
||||
check_not_in_parametric_section(p);
|
||||
static environment mixfix_cmd(parser & p, mixfix_kind k, bool overload, bool reserve, bool persistent) {
|
||||
if (persistent)
|
||||
check_not_in_parametric_section(p);
|
||||
notation_modifiers mods;
|
||||
mods.parse(p);
|
||||
flet<bool> set_allow_local(g_allow_local, in_context(p.env()) || !mods.m_persistent);
|
||||
flet<bool> set_allow_local(g_allow_local, in_context(p.env()) || !persistent);
|
||||
auto nt = parse_mixfix_notation(p, k, overload, reserve, mods.m_parse_only);
|
||||
environment env = p.env();
|
||||
if (nt.second)
|
||||
env = add_user_token(env, *nt.second, mods.m_persistent);
|
||||
env = add_notation(env, nt.first, mods.m_persistent);
|
||||
env = add_user_token(env, *nt.second, persistent);
|
||||
env = add_notation(env, nt.first, persistent);
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment notation_cmd(parser & p) {
|
||||
bool overload = !in_context(p.env());
|
||||
bool reserve = false;
|
||||
return notation_cmd_core(p, overload, reserve);
|
||||
bool persistent = true;
|
||||
return notation_cmd_core(p, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
static environment infixl_cmd(parser & p) {
|
||||
bool overload = !in_context(p.env());
|
||||
bool reserve = false;
|
||||
return mixfix_cmd(p, mixfix_kind::infixl, overload, reserve);
|
||||
bool persistent = true;
|
||||
return mixfix_cmd(p, mixfix_kind::infixl, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
static environment infixr_cmd(parser & p) {
|
||||
bool overload = !in_context(p.env());
|
||||
bool reserve = false;
|
||||
return mixfix_cmd(p, mixfix_kind::infixr, overload, reserve);
|
||||
bool persistent = true;
|
||||
return mixfix_cmd(p, mixfix_kind::infixr, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
static environment postfix_cmd(parser & p) {
|
||||
bool overload = !in_context(p.env());
|
||||
bool reserve = false;
|
||||
return mixfix_cmd(p, mixfix_kind::postfix, overload, reserve);
|
||||
bool persistent = true;
|
||||
return mixfix_cmd(p, mixfix_kind::postfix, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
static environment prefix_cmd(parser & p) {
|
||||
bool overload = !in_context(p.env());
|
||||
bool reserve = false;
|
||||
return mixfix_cmd(p, mixfix_kind::prefix, overload, reserve);
|
||||
bool persistent = true;
|
||||
return mixfix_cmd(p, mixfix_kind::prefix, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
// auxiliary procedure used by local_notation_cmd and reserve_cmd
|
||||
static environment dispatch_notation_cmd(parser & p, bool overload, bool reserve, bool persistent) {
|
||||
if (p.curr_is_token(get_notation_tk())) {
|
||||
p.next();
|
||||
return notation_cmd_core(p, overload, reserve, persistent);
|
||||
} else if (p.curr_is_token(get_infixl_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::infixl, overload, reserve, persistent);
|
||||
} else if (p.curr_is_token(get_infix_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::infixl, overload, reserve, persistent);
|
||||
} else if (p.curr_is_token(get_infixr_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::infixr, overload, reserve, persistent);
|
||||
} else if (p.curr_is_token(get_prefix_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::prefix, overload, reserve, persistent);
|
||||
} else if (p.curr_is_token(get_postfix_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::postfix, overload, reserve, persistent);
|
||||
} else {
|
||||
throw parser_error("invalid local/reserve notation, 'infix', 'infixl', 'infixr', 'prefix', "
|
||||
"'postfix' or 'notation' expected", p.pos());
|
||||
}
|
||||
}
|
||||
|
||||
environment local_notation_cmd(parser & p) {
|
||||
// TODO(Leo)
|
||||
return p.env();
|
||||
bool overload = !in_context(p.env());
|
||||
bool reserve = false;
|
||||
bool persistent = false;
|
||||
return dispatch_notation_cmd(p, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
static environment reserve_cmd(parser & p) {
|
||||
bool overload = false;
|
||||
bool reserve = true;
|
||||
if (p.curr_is_token(get_notation_tk())) {
|
||||
p.next();
|
||||
return notation_cmd_core(p, overload, reserve);
|
||||
} else if (p.curr_is_token(get_infixl_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::infixl, overload, reserve);
|
||||
} else if (p.curr_is_token(get_infix_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::infixl, overload, reserve);
|
||||
} else if (p.curr_is_token(get_infixr_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::infixr, overload, reserve);
|
||||
} else if (p.curr_is_token(get_prefix_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::prefix, overload, reserve);
|
||||
} else if (p.curr_is_token(get_postfix_tk())) {
|
||||
p.next();
|
||||
return mixfix_cmd(p, mixfix_kind::postfix, overload, reserve);
|
||||
} else {
|
||||
throw parser_error("invalid reserve notation, 'infix', 'infixl', 'infixr', 'prefix', "
|
||||
"'postfix' or 'notation' expected", p.pos());
|
||||
}
|
||||
bool overload = false;
|
||||
bool reserve = true;
|
||||
bool persistent = true;
|
||||
return dispatch_notation_cmd(p, overload, reserve, persistent);
|
||||
}
|
||||
|
||||
static environment precedence_cmd(parser & p) {
|
||||
|
|
|
@ -90,7 +90,7 @@ void init_token_table(token_table & t) {
|
|||
{"theorem", "axiom", "variable", "protected", "private", "opaque", "definition", "example", "coercion",
|
||||
"variables", "parameter", "parameters", "constant", "constants", "[persistent]", "[visible]", "[instance]",
|
||||
"[off]", "[on]", "[none]", "[class]", "[coercion]", "[reducible]", "[irreducible]", "[parsing-only]", "[multiple-instances]",
|
||||
"evaluate", "check", "eval", "[wf]", "[whnf]", "[strict]", "[local]", "[priority", "print", "end", "namespace", "section", "prelude",
|
||||
"evaluate", "check", "eval", "[wf]", "[whnf]", "[strict]", "[priority", "print", "end", "namespace", "section", "prelude",
|
||||
"import", "inductive", "record", "structure", "module", "universe", "universes", "local",
|
||||
"precedence", "reserve", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context",
|
||||
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "calc_symm", "tactic_hint",
|
||||
|
|
|
@ -101,7 +101,6 @@ static name * g_prefix = nullptr;
|
|||
static name * g_notation = nullptr;
|
||||
static name * g_call = nullptr;
|
||||
static name * g_persistent = nullptr;
|
||||
static name * g_local = nullptr;
|
||||
static name * g_root = nullptr;
|
||||
static name * g_fields = nullptr;
|
||||
static name * g_trust = nullptr;
|
||||
|
@ -201,7 +200,6 @@ void initialize_tokens() {
|
|||
g_notation = new name("notation");
|
||||
g_call = new name("call");
|
||||
g_persistent = new name("[persistent]");
|
||||
g_local = new name("[local]");
|
||||
g_root = new name("_root_");
|
||||
g_fields = new name("fields");
|
||||
g_trust = new name("trust");
|
||||
|
@ -209,7 +207,6 @@ void initialize_tokens() {
|
|||
|
||||
void finalize_tokens() {
|
||||
delete g_persistent;
|
||||
delete g_local;
|
||||
delete g_root;
|
||||
delete g_fields;
|
||||
delete g_trust;
|
||||
|
@ -402,7 +399,6 @@ name const & get_prefix_tk() { return *g_prefix; }
|
|||
name const & get_notation_tk() { return *g_notation; }
|
||||
name const & get_call_tk() { return *g_call; }
|
||||
name const & get_persistent_tk() { return *g_persistent; }
|
||||
name const & get_local_tk() { return *g_local; }
|
||||
name const & get_root_tk() { return *g_root; }
|
||||
name const & get_fields_tk() { return *g_fields; }
|
||||
name const & get_trust_tk() { return *g_trust; }
|
||||
|
|
|
@ -103,7 +103,6 @@ name const & get_prefix_tk();
|
|||
name const & get_notation_tk();
|
||||
name const & get_call_tk();
|
||||
name const & get_persistent_tk();
|
||||
name const & get_local_tk();
|
||||
name const & get_root_tk();
|
||||
name const & get_fields_tk();
|
||||
name const & get_trust_tk();
|
||||
|
|
|
@ -33,7 +33,7 @@ inv_image lt tree_forest_height
|
|||
definition tree_forest.subterm.wf [instance] (A : Type) : well_founded (@tree_forest.subterm A) :=
|
||||
inv_image.wf tree_forest_height lt.wf
|
||||
|
||||
infix [local] `≺`:50 := tree_forest.subterm
|
||||
local infix `≺`:50 := tree_forest.subterm
|
||||
|
||||
definition tree_forest.height_lt.node {A : Type} (a : A) (f : forest A) : sum.inr f ≺ sum.inl (tree.node a f) :=
|
||||
have aux : forest.height f < tree.height (tree.node a f), from
|
||||
|
|
|
@ -3,7 +3,7 @@ import logic
|
|||
section
|
||||
variables {A : Type}
|
||||
variables f : A → A → A
|
||||
infixl [local] `+++`:10 := f
|
||||
local infixl `+++`:10 := f
|
||||
|
||||
variables a b c : A
|
||||
check f a b
|
||||
|
|
Loading…
Reference in a new issue