diff --git a/library/theories/number_theory/primes.lean b/library/theories/number_theory/primes.lean index d1416373c..67def367f 100644 --- a/library/theories/number_theory/primes.lean +++ b/library/theories/number_theory/primes.lean @@ -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, 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 (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₅, -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 := 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 have m ≥ 1, from le_of_lt_succ (succ_lt_succ (fact_pos _)), 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 > 0, from lt_of_succ_lt (lt_of_succ_le `p ≥ 2`), 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 := λ pp p_gt_2, by_contradiction (λ hn, have even p, from even_of_not_odd hn, - obtain k (hk : p = 2*k), from exists_of_even this, - assert 2 ∣ p, by rewrite [hk]; apply dvd_mul_right, + obtain k `p = 2*k`, from exists_of_even this, + 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) (suppose 2 = 1, absurd this dec_trivial) (suppose 2 = p, by subst this; exact absurd p_gt_2 !lt.irrefl)) diff --git a/src/frontends/lean/parser.cpp b/src/frontends/lean/parser.cpp index c044be322..5d1beee0c 100644 --- a/src/frontends/lean/parser.cpp +++ b/src/frontends/lean/parser.cpp @@ -934,6 +934,13 @@ void parser::parse_binders_core(buffer & r, buffer * nentr if (curr_is_identifier()) { parse_binder_block(r, binder_info(), rbp); 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 { optional bi = parse_optional_binder_info(simple_only); if (bi) { @@ -1330,8 +1337,8 @@ expr parser::parse_string_expr() { return from_string(v); } -expr parser::parse_backtick_expr() { - auto p = pos(); + +expr parser::parse_backtick_expr_core() { next(); flet set(m_in_backtick, true); expr type = parse_expr(); @@ -1339,6 +1346,12 @@ expr parser::parse_backtick_expr() { throw parser_error("invalid expression, '`' expected", pos()); } 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); return save_pos(mk_typed_expr(type, assump), p); } diff --git a/src/frontends/lean/parser.h b/src/frontends/lean/parser.h index 6d80488b8..1df3b4921 100644 --- a/src/frontends/lean/parser.h +++ b/src/frontends/lean/parser.h @@ -234,6 +234,7 @@ class parser { 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 + expr parse_backtick_expr_core(); expr parse_backtick_expr(); optional is_tactic_command(name & id); @@ -338,6 +339,8 @@ public: 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 */ 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. */ 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 */