feat(frontends/lean): allow backticks in binder declarations
This commit is contained in:
parent
fbaa8b21f6
commit
cc396cba76
3 changed files with 23 additions and 7 deletions
|
@ -79,9 +79,9 @@ have ¬ (∀ m, m < succ n → m ∣ n → m = 1 ∨ m = n), from
|
||||||
assume h, absurd (λ m hl hd, h m (lt_succ_of_le hl) hd) this,
|
assume h, absurd (λ m hl hd, h m (lt_succ_of_le hl) hd) this,
|
||||||
have {m | m < succ n ∧ ¬(m ∣ n → m = 1 ∨ m = n)}, from bsub_not_of_not_ball this,
|
have {m | m < succ n ∧ ¬(m ∣ n → m = 1 ∨ m = n)}, from bsub_not_of_not_ball this,
|
||||||
obtain m hlt (h₃ : ¬(m ∣ n → m = 1 ∨ m = n)), from this,
|
obtain m hlt (h₃ : ¬(m ∣ n → m = 1 ∨ m = n)), from this,
|
||||||
obtain (h₄ : m ∣ n) (h₅ : ¬ (m = 1 ∨ m = n)), from iff.mp !not_implies_iff_and_not h₃,
|
obtain `m ∣ n` (h₅ : ¬ (m = 1 ∨ m = n)), from iff.mp !not_implies_iff_and_not h₃,
|
||||||
have ¬ m = 1 ∧ ¬ m = n, from iff.mp !not_or_iff_not_and_not h₅,
|
have ¬ m = 1 ∧ ¬ m = n, from iff.mp !not_or_iff_not_and_not h₅,
|
||||||
subtype.tag m (and.intro h₄ this)
|
subtype.tag m (and.intro `m ∣ n` this)
|
||||||
|
|
||||||
theorem ex_dvd_of_not_prime {n : nat} : n ≥ 2 → ¬ prime n → ∃ m, m ∣ n ∧ m ≠ 1 ∧ m ≠ n :=
|
theorem ex_dvd_of_not_prime {n : nat} : n ≥ 2 → ¬ prime n → ∃ m, m ∣ n ∧ m ≠ 1 ∧ m ≠ n :=
|
||||||
assume h₁ h₂, ex_of_sub (sub_dvd_of_not_prime h₁ h₂)
|
assume h₁ h₂, ex_of_sub (sub_dvd_of_not_prime h₁ h₂)
|
||||||
|
@ -125,7 +125,7 @@ definition infinite_primes (n : nat) : {p | p ≥ n ∧ prime p} :=
|
||||||
let m := fact (n + 1) in
|
let m := fact (n + 1) in
|
||||||
have m ≥ 1, from le_of_lt_succ (succ_lt_succ (fact_pos _)),
|
have m ≥ 1, from le_of_lt_succ (succ_lt_succ (fact_pos _)),
|
||||||
have m + 1 ≥ 2, from succ_le_succ this,
|
have m + 1 ≥ 2, from succ_le_succ this,
|
||||||
obtain p (pp : prime p) (pd : p ∣ m + 1), from sub_prime_and_dvd this,
|
obtain p `prime p` `p ∣ m + 1`, from sub_prime_and_dvd this,
|
||||||
have p ≥ 2, from ge_two_of_prime `prime p`,
|
have p ≥ 2, from ge_two_of_prime `prime p`,
|
||||||
have p > 0, from lt_of_succ_lt (lt_of_succ_le `p ≥ 2`),
|
have p > 0, from lt_of_succ_lt (lt_of_succ_le `p ≥ 2`),
|
||||||
have p ≥ n, from by_contradiction
|
have p ≥ n, from by_contradiction
|
||||||
|
@ -144,8 +144,8 @@ ex_of_sub (infinite_primes n)
|
||||||
lemma odd_of_prime {p : nat} : prime p → p > 2 → odd p :=
|
lemma odd_of_prime {p : nat} : prime p → p > 2 → odd p :=
|
||||||
λ pp p_gt_2, by_contradiction (λ hn,
|
λ pp p_gt_2, by_contradiction (λ hn,
|
||||||
have even p, from even_of_not_odd hn,
|
have even p, from even_of_not_odd hn,
|
||||||
obtain k (hk : p = 2*k), from exists_of_even this,
|
obtain k `p = 2*k`, from exists_of_even this,
|
||||||
assert 2 ∣ p, by rewrite [hk]; apply dvd_mul_right,
|
assert 2 ∣ p, by rewrite [`p = 2*k`]; apply dvd_mul_right,
|
||||||
or.elim (eq_one_or_eq_self_of_prime_of_dvd pp this)
|
or.elim (eq_one_or_eq_self_of_prime_of_dvd pp this)
|
||||||
(suppose 2 = 1, absurd this dec_trivial)
|
(suppose 2 = 1, absurd this dec_trivial)
|
||||||
(suppose 2 = p, by subst this; exact absurd p_gt_2 !lt.irrefl))
|
(suppose 2 = p, by subst this; exact absurd p_gt_2 !lt.irrefl))
|
||||||
|
|
|
@ -934,6 +934,13 @@ void parser::parse_binders_core(buffer<expr> & r, buffer<notation_entry> * nentr
|
||||||
if (curr_is_identifier()) {
|
if (curr_is_identifier()) {
|
||||||
parse_binder_block(r, binder_info(), rbp);
|
parse_binder_block(r, binder_info(), rbp);
|
||||||
last_block_delimited = false;
|
last_block_delimited = false;
|
||||||
|
} else if (curr_is_backtick()) {
|
||||||
|
auto p = pos();
|
||||||
|
name n = mk_fresh_name();
|
||||||
|
expr type = parse_backtick_expr_core();
|
||||||
|
expr local = save_pos(mk_local(n, type, binder_info()), p);
|
||||||
|
add_local(local);
|
||||||
|
r.push_back(local);
|
||||||
} else {
|
} else {
|
||||||
optional<binder_info> bi = parse_optional_binder_info(simple_only);
|
optional<binder_info> bi = parse_optional_binder_info(simple_only);
|
||||||
if (bi) {
|
if (bi) {
|
||||||
|
@ -1330,8 +1337,8 @@ expr parser::parse_string_expr() {
|
||||||
return from_string(v);
|
return from_string(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr parser::parse_backtick_expr() {
|
|
||||||
auto p = pos();
|
expr parser::parse_backtick_expr_core() {
|
||||||
next();
|
next();
|
||||||
flet<bool> set(m_in_backtick, true);
|
flet<bool> set(m_in_backtick, true);
|
||||||
expr type = parse_expr();
|
expr type = parse_expr();
|
||||||
|
@ -1339,6 +1346,12 @@ expr parser::parse_backtick_expr() {
|
||||||
throw parser_error("invalid expression, '`' expected", pos());
|
throw parser_error("invalid expression, '`' expected", pos());
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr parser::parse_backtick_expr() {
|
||||||
|
auto p = pos();
|
||||||
|
expr type = parse_backtick_expr_core();
|
||||||
expr assump = mk_by_plus(save_pos(mk_constant(get_tactic_assumption_name()), p), p);
|
expr assump = mk_by_plus(save_pos(mk_constant(get_tactic_assumption_name()), p), p);
|
||||||
return save_pos(mk_typed_expr(type, assump), p);
|
return save_pos(mk_typed_expr(type, assump), p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,6 +234,7 @@ class parser {
|
||||||
elaborator_context mk_elaborator_context(environment const & env, local_level_decls const & lls, pos_info_provider const & pp);
|
elaborator_context mk_elaborator_context(environment const & env, local_level_decls const & lls, pos_info_provider const & pp);
|
||||||
|
|
||||||
bool m_in_backtick; // true if parser `expr` notation
|
bool m_in_backtick; // true if parser `expr` notation
|
||||||
|
expr parse_backtick_expr_core();
|
||||||
expr parse_backtick_expr();
|
expr parse_backtick_expr();
|
||||||
|
|
||||||
optional<expr> is_tactic_command(name & id);
|
optional<expr> is_tactic_command(name & id);
|
||||||
|
@ -338,6 +339,8 @@ public:
|
||||||
bool curr_is_token_or_id(name const & tk) const;
|
bool curr_is_token_or_id(name const & tk) const;
|
||||||
/** \brief Return true iff the current token is a command, EOF, period or script block */
|
/** \brief Return true iff the current token is a command, EOF, period or script block */
|
||||||
bool curr_is_command_like() const;
|
bool curr_is_command_like() const;
|
||||||
|
/** \brief Return true iff the current token is a backtick ` */
|
||||||
|
bool curr_is_backtick() const { return curr() == scanner::token_kind::Backtick; }
|
||||||
/** \brief Read the next token if the current one is not End-of-file. */
|
/** \brief Read the next token if the current one is not End-of-file. */
|
||||||
void next() { if (m_curr != scanner::token_kind::Eof) scan(); }
|
void next() { if (m_curr != scanner::token_kind::Eof) scan(); }
|
||||||
/** \brief Return true iff the current token is a keyword (or command keyword) named \c tk */
|
/** \brief Return true iff the current token is a keyword (or command keyword) named \c tk */
|
||||||
|
|
Loading…
Reference in a new issue