diff --git a/library/init/funext.lean b/library/init/funext.lean index 454263bc6..761feefe9 100644 --- a/library/init/funext.lean +++ b/library/init/funext.lean @@ -56,7 +56,7 @@ section ... = f₂ : rfl end -attribute funext [intro] +attribute funext [intro!] open function.equiv_notation diff --git a/library/init/logic.lean b/library/init/logic.lean index 2ad5df110..4426285bf 100644 --- a/library/init/logic.lean +++ b/library/init/logic.lean @@ -24,7 +24,7 @@ prefix `¬` := not definition absurd {a : Prop} {b : Type} (H1 : a) (H2 : ¬a) : b := false.rec b (H2 H1) -lemma not.intro [intro] {a : Prop} (H : a → false) : ¬ a := +lemma not.intro [intro!] {a : Prop} (H : a → false) : ¬ a := H theorem mt {a b : Prop} (H1 : a → b) (H2 : ¬b) : ¬a := @@ -243,7 +243,7 @@ notation a ∧ b := and a b variables {a b c d : Prop} attribute and.rec [elim] -attribute and.intro [intro] +attribute and.intro [intro!] theorem and.elim (H₁ : a ∧ b) (H₂ : a → b → c) : c := and.rec H₂ H₁ @@ -280,7 +280,7 @@ notation a ↔ b := iff a b theorem iff.intro : (a → b) → (b → a) → (a ↔ b) := and.intro -attribute iff.intro [intro] +attribute iff.intro [intro!] theorem iff.elim : ((a → b) → (b → a) → c) → (a ↔ b) → c := and.rec @@ -508,9 +508,7 @@ and_congr (imp_congr H1 H2) (imp_congr H2 H1) inductive Exists {A : Type} (P : A → Prop) : Prop := intro : ∀ (a : A), P a → Exists P --- Remark: we don't mark exists.intro with [intro] because the [intro] --- rules are applied eagerly. -attribute Exists.intro [backward] +attribute Exists.intro [intro] definition exists.intro := @Exists.intro @@ -530,7 +528,7 @@ definition exists_unique {A : Type} (p : A → Prop) := notation `∃!` binders `, ` r:(scoped P, exists_unique P) := r -theorem exists_unique.intro [backward] {A : Type} {p : A → Prop} (w : A) (H1 : p w) (H2 : ∀y, p y → y = w) : +theorem exists_unique.intro [intro] {A : Type} {p : A → Prop} (w : A) (H1 : p w) (H2 : ∀y, p y → y = w) : ∃!x, p x := exists.intro w (and.intro H1 H2) diff --git a/src/emacs/lean-syntax.el b/src/emacs/lean-syntax.el index 7555be368..2a5e56996 100644 --- a/src/emacs/lean-syntax.el +++ b/src/emacs/lean-syntax.el @@ -55,9 +55,9 @@ "class" "parsing_only" "coercion" "unfold_full" "constructor" "reducible" "irreducible" "semireducible" "quasireducible" "wf" "whnf" "multiple_instances" "none" "decls" "declarations" - "coercions" "classes" "symm" "subst" "refl" "trans" "simp" "simps" "congr" "backward" + "coercions" "classes" "symm" "subst" "refl" "trans" "simp" "simps" "congr" "forward" "no_pattern" "notations" "abbreviations" "begin_end_hints" "tactic_hints" - "reduce_hints" "unfold_hints" "aliases" "eqv" "intro" "elim" + "reduce_hints" "unfold_hints" "aliases" "eqv" "intro" "intro!" "elim" "localrefinfo" "recursor")) "lean modifiers") (defconst lean-modifiers-regexp diff --git a/src/frontends/lean/builtin_cmds.cpp b/src/frontends/lean/builtin_cmds.cpp index f2e2df9c5..a1716cb82 100644 --- a/src/frontends/lean/builtin_cmds.cpp +++ b/src/frontends/lean/builtin_cmds.cpp @@ -709,7 +709,7 @@ environment print_cmd(parser & p) { } else if (p.curr_is_token(get_simp_attr_tk())) { p.next(); print_simp_rules(p); - } else if (p.curr_is_token(get_intro_attr_tk())) { + } else if (p.curr_is_token(get_intro_bang_attr_tk())) { p.next(); print_intro_lemmas(p); } else if (p.curr_is_token(get_elim_attr_tk())) { @@ -722,7 +722,7 @@ environment print_cmd(parser & p) { p.next(); p.check_token_next(get_rbracket_tk(), "invalid 'print [light]', ']' expected"); print_light_rules(p); - } else if (p.curr_is_token(get_backward_attr_tk())) { + } else if (p.curr_is_token(get_intro_attr_tk())) { p.next(); print_backward_rules(p); } else if (print_polymorphic(p)) { diff --git a/src/frontends/lean/decl_attributes.cpp b/src/frontends/lean/decl_attributes.cpp index b3e887e86..b76d79997 100644 --- a/src/frontends/lean/decl_attributes.cpp +++ b/src/frontends/lean/decl_attributes.cpp @@ -46,9 +46,9 @@ decl_attributes::decl_attributes(bool is_abbrev, bool persistent): m_recursor = false; m_simp = false; m_congr = false; - m_backward = false; m_forward = false; m_intro = false; + m_intro_bang = false; m_elim = false; m_no_pattern = false; } @@ -97,9 +97,9 @@ void decl_attributes::parse(parser & p) { p.next(); } else if (auto it = parse_priority(p)) { m_priority = *it; - if (!m_is_instance && !m_simp && !m_congr && !m_backward && !m_forward && !m_elim && !m_intro) { + if (!m_is_instance && !m_simp && !m_congr && !m_forward && !m_elim && !m_intro && !m_intro_bang) { throw parser_error("invalid '[priority]' attribute, declaration must be marked as an '[instance]', '[simp]', '[congr]', " - "'[backward]', '[forward]', '[intro]' or '[elim]'", pos); + "'[forward]', '[intro!]', '[intro]' or '[elim]'", pos); } } else if (p.curr_is_token(get_parsing_only_tk())) { if (!m_is_abbrev) @@ -148,9 +148,6 @@ void decl_attributes::parse(parser & p) { p.next(); m_light_arg = p.parse_small_nat(); p.check_token_next(get_rbracket_tk(), "light attribute has form '[light ]'"); - } else if (p.curr_is_token(get_backward_attr_tk())) { - p.next(); - m_backward = true; } else if (p.curr_is_token(get_forward_attr_tk())) { p.next(); m_forward = true; @@ -160,6 +157,9 @@ void decl_attributes::parse(parser & p) { } else if (p.curr_is_token(get_intro_attr_tk())) { p.next(); m_intro = true; + } else if (p.curr_is_token(get_intro_bang_attr_tk())) { + p.next(); + m_intro_bang = true; } else if (p.curr_is_token(get_no_pattern_attr_tk())) { p.next(); m_no_pattern = true; @@ -252,12 +252,6 @@ environment decl_attributes::apply(environment env, io_state const & ios, name c if (m_light_arg) { env = add_light_rule(env, d, *m_light_arg, ns, m_persistent); } - if (m_backward) { - if (m_priority) - env = add_backward_rule(env, d, *m_priority, ns, m_persistent); - else - env = add_backward_rule(env, d, LEAN_BACKWARD_DEFAULT_PRIORITY, ns, m_persistent); - } if (forward) { mk_multipatterns(env, ios, d); // try to create patterns if (m_priority) @@ -266,6 +260,12 @@ environment decl_attributes::apply(environment env, io_state const & ios, name c env = add_forward_lemma(env, d, LEAN_FORWARD_DEFAULT_PRIORITY, ns, m_persistent); } if (m_intro) { + if (m_priority) + env = add_backward_rule(env, d, *m_priority, ns, m_persistent); + else + env = add_backward_rule(env, d, LEAN_BACKWARD_DEFAULT_PRIORITY, ns, m_persistent); + } + if (m_intro_bang) { if (m_priority) env = add_intro_lemma(env, ios, d, *m_priority, ns, m_persistent); else @@ -290,8 +290,8 @@ void decl_attributes::write(serializer & s) const { << m_is_reducible << m_is_irreducible << m_is_semireducible << m_is_quasireducible << m_is_class << m_is_parsing_only << m_has_multiple_instances << m_unfold_full_hint << m_constructor_hint << m_symm << m_trans << m_refl << m_subst << m_recursor - << m_simp << m_congr << m_recursor_major_pos << m_priority << m_backward - << m_forward << m_elim << m_intro << m_no_pattern; + << m_simp << m_congr << m_recursor_major_pos << m_priority + << m_forward << m_elim << m_intro << m_intro_bang << m_no_pattern; write_list(s, m_unfold_hint); } @@ -300,8 +300,8 @@ void decl_attributes::read(deserializer & d) { >> m_is_reducible >> m_is_irreducible >> m_is_semireducible >> m_is_quasireducible >> m_is_class >> m_is_parsing_only >> m_has_multiple_instances >> m_unfold_full_hint >> m_constructor_hint >> m_symm >> m_trans >> m_refl >> m_subst >> m_recursor - >> m_simp >> m_congr >> m_recursor_major_pos >> m_priority >> m_backward - >> m_forward >> m_elim >> m_intro >> m_no_pattern; + >> m_simp >> m_congr >> m_recursor_major_pos >> m_priority + >> m_forward >> m_elim >> m_intro >> m_intro_bang >> m_no_pattern; m_unfold_hint = read_list(d); } } diff --git a/src/frontends/lean/decl_attributes.h b/src/frontends/lean/decl_attributes.h index 1a5df1a48..963ce6f3c 100644 --- a/src/frontends/lean/decl_attributes.h +++ b/src/frontends/lean/decl_attributes.h @@ -31,9 +31,9 @@ class decl_attributes { bool m_recursor; bool m_simp; bool m_congr; - bool m_backward; bool m_forward; bool m_intro; + bool m_intro_bang; bool m_elim; bool m_no_pattern; optional m_recursor_major_pos; diff --git a/src/frontends/lean/token_table.cpp b/src/frontends/lean/token_table.cpp index 36f1e0c9b..09f367ff5 100644 --- a/src/frontends/lean/token_table.cpp +++ b/src/frontends/lean/token_table.cpp @@ -111,8 +111,8 @@ void init_token_table(token_table & t) { "[persistent]", "[visible]", "[instance]", "[trans_instance]", "[light", "[none]", "[class]", "[coercion]", "[reducible]", "[irreducible]", "[semireducible]", "[quasireducible]", "[simp]", "[congr]", "[parsing_only]", "[multiple_instances]", "[symm]", "[trans]", "[refl]", "[subst]", "[recursor", - "evaluate", "check", "eval", "[wf]", "[whnf]", "[priority", "[unfold_full]", "[unfold_hints]", "[backward]", - "[forward]", "[no_pattern]", "[constructor]", "[elim]", "[intro]", "[unfold", "print", + "evaluate", "check", "eval", "[wf]", "[whnf]", "[priority", "[unfold_full]", "[unfold_hints]", "[intro]", + "[forward]", "[no_pattern]", "[constructor]", "[elim]", "[intro!]", "[unfold", "print", "end", "namespace", "section", "prelude", "help", "import", "inductive", "record", "structure", "module", "universe", "universes", "local", "precedence", "reserve", "infixl", "infixr", "infix", "postfix", "prefix", "notation", diff --git a/src/frontends/lean/tokens.cpp b/src/frontends/lean/tokens.cpp index e1f365a49..b00a376a3 100644 --- a/src/frontends/lean/tokens.cpp +++ b/src/frontends/lean/tokens.cpp @@ -121,10 +121,10 @@ static name const * g_subst_tk = nullptr; static name const * g_simp_attr_tk = nullptr; static name const * g_congr_attr_tk = nullptr; static name const * g_light_attr_tk = nullptr; -static name const * g_backward_attr_tk = nullptr; static name const * g_no_pattern_attr_tk = nullptr; static name const * g_forward_attr_tk = nullptr; static name const * g_intro_attr_tk = nullptr; +static name const * g_intro_bang_attr_tk = nullptr; static name const * g_elim_attr_tk = nullptr; static name const * g_recursor_tk = nullptr; static name const * g_attribute_tk = nullptr; @@ -281,10 +281,10 @@ void initialize_tokens() { g_simp_attr_tk = new name{"[simp]"}; g_congr_attr_tk = new name{"[congr]"}; g_light_attr_tk = new name{"[light"}; - g_backward_attr_tk = new name{"[backward]"}; g_no_pattern_attr_tk = new name{"[no_pattern]"}; g_forward_attr_tk = new name{"[forward]"}; g_intro_attr_tk = new name{"[intro]"}; + g_intro_bang_attr_tk = new name{"[intro!]"}; g_elim_attr_tk = new name{"[elim]"}; g_recursor_tk = new name{"[recursor"}; g_attribute_tk = new name{"attribute"}; @@ -442,10 +442,10 @@ void finalize_tokens() { delete g_simp_attr_tk; delete g_congr_attr_tk; delete g_light_attr_tk; - delete g_backward_attr_tk; delete g_no_pattern_attr_tk; delete g_forward_attr_tk; delete g_intro_attr_tk; + delete g_intro_bang_attr_tk; delete g_elim_attr_tk; delete g_recursor_tk; delete g_attribute_tk; @@ -602,10 +602,10 @@ name const & get_subst_tk() { return *g_subst_tk; } name const & get_simp_attr_tk() { return *g_simp_attr_tk; } name const & get_congr_attr_tk() { return *g_congr_attr_tk; } name const & get_light_attr_tk() { return *g_light_attr_tk; } -name const & get_backward_attr_tk() { return *g_backward_attr_tk; } name const & get_no_pattern_attr_tk() { return *g_no_pattern_attr_tk; } name const & get_forward_attr_tk() { return *g_forward_attr_tk; } name const & get_intro_attr_tk() { return *g_intro_attr_tk; } +name const & get_intro_bang_attr_tk() { return *g_intro_bang_attr_tk; } name const & get_elim_attr_tk() { return *g_elim_attr_tk; } name const & get_recursor_tk() { return *g_recursor_tk; } name const & get_attribute_tk() { return *g_attribute_tk; } diff --git a/src/frontends/lean/tokens.h b/src/frontends/lean/tokens.h index 761415e61..c2a506ef7 100644 --- a/src/frontends/lean/tokens.h +++ b/src/frontends/lean/tokens.h @@ -123,10 +123,10 @@ name const & get_subst_tk(); name const & get_simp_attr_tk(); name const & get_congr_attr_tk(); name const & get_light_attr_tk(); -name const & get_backward_attr_tk(); name const & get_no_pattern_attr_tk(); name const & get_forward_attr_tk(); name const & get_intro_attr_tk(); +name const & get_intro_bang_attr_tk(); name const & get_elim_attr_tk(); name const & get_recursor_tk(); name const & get_attribute_tk(); diff --git a/src/frontends/lean/tokens.txt b/src/frontends/lean/tokens.txt index cd1c85207..7736dc3d0 100644 --- a/src/frontends/lean/tokens.txt +++ b/src/frontends/lean/tokens.txt @@ -116,10 +116,10 @@ subst [subst] simp_attr [simp] congr_attr [congr] light_attr [light -backward_attr [backward] no_pattern_attr [no_pattern] -forward_attr [forward] -intro_attr [intro] +forward_attr [forward] +intro_attr [intro] +intro_bang_attr [intro!] elim_attr [elim] recursor [recursor attribute attribute diff --git a/tests/lean/backward_rule1.lean b/tests/lean/backward_rule1.lean index e5e505dc9..e4841e5ea 100644 --- a/tests/lean/backward_rule1.lean +++ b/tests/lean/backward_rule1.lean @@ -1,11 +1,11 @@ constants (A B C : Prop) (H : A → B) (G : A → B → C) constants (T : Type) (f : T → A) -attribute H [backward] -attribute G [backward] -attribute f [backward] +attribute H [intro] +attribute G [intro] +attribute f [intro] print H print G print f -print [backward] +print [intro] diff --git a/tests/lean/run/blast18.lean b/tests/lean/run/blast18.lean index 6bd84f2eb..53311c07b 100644 --- a/tests/lean/run/blast18.lean +++ b/tests/lean/run/blast18.lean @@ -2,15 +2,15 @@ set_option blast.strategy "backward" constants {P Q R S T U : Prop} (Hpq : P → Q) (Hqr : Q → R) (Hrs : R → S) (Hst : S → T) constants (Huq : U → Q) (Hur : U → R) (Hus : U → S) (Hut : U → T) -attribute Hpq [backward] -attribute Hqr [backward] -attribute Hrs [backward] -attribute Hst [backward] +attribute Hpq [intro] +attribute Hqr [intro] +attribute Hrs [intro] +attribute Hst [intro] -attribute Huq [backward] -attribute Hur [backward] -attribute Hus [backward] -attribute Hut [backward] +attribute Huq [intro] +attribute Hur [intro] +attribute Hus [intro] +attribute Hut [intro] definition lemma1 (p : P) : Q := by blast definition lemma2 (p : P) : R := by blast diff --git a/tests/lean/run/blast19.lean b/tests/lean/run/blast19.lean index 870f16b7a..32ff2b8a6 100644 --- a/tests/lean/run/blast19.lean +++ b/tests/lean/run/blast19.lean @@ -2,10 +2,10 @@ set_option blast.strategy "backward" constants {P Q R S T U : Prop} constants (Huq : U → Q) (Hur : U → R) (Hus : U → S) (Hut : U → T) -attribute Huq [backward] -attribute Hur [backward] -attribute Hus [backward] -attribute Hut [backward] +attribute Huq [intro] +attribute Hur [intro] +attribute Hus [intro] +attribute Hut [intro] definition lemma1 : (P → Q) → P → Q := by blast definition lemma2 : (P → Q) → (Q → R) → P → R := by blast diff --git a/tests/lean/run/blast20.lean b/tests/lean/run/blast20.lean index 362455e22..593ab750f 100644 --- a/tests/lean/run/blast20.lean +++ b/tests/lean/run/blast20.lean @@ -12,7 +12,7 @@ by blast example : ∀ (F F' : Prop), F ∧ F' → F := by blast -attribute and.intro [backward] +attribute and.intro [intro] example : ∀ (P Q R : nat → Prop) (F : Prop), (F ∧ (∀ n m, (Q m ∧ R n) → P n)) → (F → R 2) → Q 1 → P 2 ∧ F := diff --git a/tests/lean/run/blast21.lean b/tests/lean/run/blast21.lean index c897154a9..1def7095f 100644 --- a/tests/lean/run/blast21.lean +++ b/tests/lean/run/blast21.lean @@ -9,7 +9,7 @@ constant subtype_refl : ∀ T, subtype T T constant subtype_trans : ∀ S T U, subtype S T → subtype T U → subtype S U -attribute subtype_refl subtype_trans [backward] +attribute subtype_refl subtype_trans [intro] lemma L1 : ∀ T1 T2 T3 T4 T5 T6, subtype T1 T2 → subtype T2 T3 → subtype T3 T4 → subtype T4 T5 → subtype T5 T6 → subtype T1 T6 := by blast diff --git a/tests/lean/run/blast_grind1.lean b/tests/lean/run/blast_grind1.lean index 05f47291a..cce566bb6 100644 --- a/tests/lean/run/blast_grind1.lean +++ b/tests/lean/run/blast_grind1.lean @@ -11,7 +11,7 @@ by blast print ex1 -attribute Exists.intro [intro] +attribute Exists.intro [intro!] -- grind and core_grind only process [intro!] declarations example (p q : nat → Prop) : (∃ x, p x ∧ q x) → (∃ x, q x) ∧ (∃ x, p x) := by blast @@ -27,7 +27,5 @@ by blast example (a : nat) : a = 0 → (λ x, x + a) = (λ x, x + 0) := by blast -attribute Exists.intro [intro] - example (p q : nat → Prop) : (∃ x, p x ∧ q x) → (∃ x, q x) ∧ (∃ x, p x) := by blast