feat(library/comp_val): add mk_name_val_ne_proof
We need this procedure otherwise it takes forever to prove equation lemmas for definitions such as: ``` def macros : name → option macro | `lambda := some lambda_macro | `intro_x := some intro_x_macro | _ := none ``` We never experienced this problem in Lean3 because we used `name` literals only occurred in patterns of *meta* definitions. So, no equation lemma was generated. @kha `def macros` was taking more than 1 second to elaborate on my machine. It is now instantaneous.
This commit is contained in:
parent
e160154d14
commit
441b9077b2
7 changed files with 109 additions and 0 deletions
|
|
@ -117,5 +117,17 @@ instance : has_to_string name :=
|
|||
instance : has_to_format name :=
|
||||
⟨λ n, n.to_string⟩
|
||||
|
||||
theorem mk_string_ne_mk_string_of_ne_prefix {p₁ : name} (s₁ : string) {p₂ : name} (s₂ : string) : p₁ ≠ p₂ → mk_string p₁ s₁ ≠ mk_string p₂ s₂ :=
|
||||
λ h₁ h₂, name.no_confusion h₂ (λ h _, absurd h h₁)
|
||||
|
||||
theorem mk_string_ne_mk_string_of_ne_string (p₁ : name) {s₁ : string} (p₂ : name) {s₂ : string} : s₁ ≠ s₂ → mk_string p₁ s₁ ≠ mk_string p₂ s₂ :=
|
||||
λ h₁ h₂, name.no_confusion h₂ (λ _ h, absurd h h₁)
|
||||
|
||||
theorem mk_numeral_ne_mk_numeral_of_ne_prefix {p₁ : name} (n₁ : nat) {p₂ : name} (n₂ : nat) : p₁ ≠ p₂ → mk_numeral p₁ n₁ ≠ mk_numeral p₂ n₂ :=
|
||||
λ h₁ h₂, name.no_confusion h₂ (λ h _, absurd h h₁)
|
||||
|
||||
theorem mk_numeral_ne_mk_numeral_of_ne_numeral (p₁ : name) {n₁ : nat} (p₂ : name) {n₂ : nat} : n₁ ≠ n₂ → mk_numeral p₁ n₁ ≠ mk_numeral p₂ n₂ :=
|
||||
λ h₁ h₂, name.no_confusion h₂ (λ _ h, absurd h h₁)
|
||||
|
||||
end name
|
||||
end lean
|
||||
|
|
|
|||
|
|
@ -207,6 +207,54 @@ optional<expr> mk_string_val_ne_proof(expr a, expr b) {
|
|||
return none_expr();
|
||||
}
|
||||
|
||||
static expr mk_name_no_confusion(expr const & a, expr const & b) {
|
||||
return mk_app(mk_constant(get_lean_name_no_confusion_name(), {mk_level_zero()}),
|
||||
mk_false(), a, b);
|
||||
}
|
||||
|
||||
optional<expr> mk_name_val_ne_proof(expr const & a, expr const & b) {
|
||||
if (is_constant(a, get_lean_name_anonymous_name())) {
|
||||
if (is_app_of(b, get_lean_name_mk_string_name(), 2)) {
|
||||
return some_expr(mk_name_no_confusion(a, b));
|
||||
} else if (is_app_of(b, get_lean_name_mk_numeral_name(), 2)) {
|
||||
return some_expr(mk_name_no_confusion(a, b));
|
||||
}
|
||||
} else if (is_app_of(a, get_lean_name_mk_string_name(), 2)) {
|
||||
if (is_constant(b, get_lean_name_anonymous_name())) {
|
||||
return some_expr(mk_name_no_confusion(a, b));
|
||||
} else if (is_app_of(b, get_lean_name_mk_string_name())) {
|
||||
if (auto h = mk_string_val_ne_proof(app_arg(a), app_arg(b))) {
|
||||
return some_expr(mk_app({mk_constant(get_lean_name_mk_string_ne_mk_string_of_ne_string_name()),
|
||||
app_arg(app_fn(a)), app_arg(a),
|
||||
app_arg(app_fn(b)), app_arg(b), *h}));
|
||||
} else if (auto h = mk_name_val_ne_proof(app_arg(app_fn(a)), app_arg(app_fn(b)))) {
|
||||
return some_expr(mk_app({mk_constant(get_lean_name_mk_string_ne_mk_string_of_ne_prefix_name()),
|
||||
app_arg(app_fn(a)), app_arg(a),
|
||||
app_arg(app_fn(b)), app_arg(b), *h}));
|
||||
}
|
||||
} else if (is_app_of(b, get_lean_name_mk_numeral_name(), 2)) {
|
||||
return some_expr(mk_name_no_confusion(a, b));
|
||||
}
|
||||
} else if (is_app_of(a, get_lean_name_mk_numeral_name(), 2)) {
|
||||
if (is_constant(b, get_lean_name_anonymous_name())) {
|
||||
return some_expr(mk_name_no_confusion(a, b));
|
||||
} else if (is_app_of(b, get_lean_name_mk_string_name())) {
|
||||
return some_expr(mk_name_no_confusion(a, b));
|
||||
} else if (is_app_of(b, get_lean_name_mk_numeral_name(), 2)) {
|
||||
if (auto h = mk_nat_val_ne_proof(app_arg(a), app_arg(b))) {
|
||||
return some_expr(mk_app({mk_constant(get_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral_name()),
|
||||
app_arg(app_fn(a)), app_arg(a),
|
||||
app_arg(app_fn(b)), app_arg(b), *h}));
|
||||
} else if (auto h = mk_name_val_ne_proof(app_arg(app_fn(a)), app_arg(app_fn(b)))) {
|
||||
return some_expr(mk_app({mk_constant(get_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix_name()),
|
||||
app_arg(app_fn(a)), app_arg(a),
|
||||
app_arg(app_fn(b)), app_arg(b), *h}));
|
||||
}
|
||||
}
|
||||
}
|
||||
return none_expr();
|
||||
}
|
||||
|
||||
optional<expr> mk_val_ne_proof(type_context_old & ctx, expr const & a, expr const & b) {
|
||||
expr type = ctx.infer(a);
|
||||
if (ctx.is_def_eq(type, mk_nat_type()))
|
||||
|
|
@ -215,6 +263,8 @@ optional<expr> mk_val_ne_proof(type_context_old & ctx, expr const & a, expr cons
|
|||
return mk_char_val_ne_proof(a, b);
|
||||
if (ctx.is_def_eq(type, mk_constant(get_string_name())))
|
||||
return mk_string_val_ne_proof(a, b);
|
||||
if (ctx.is_def_eq(type, mk_constant(get_lean_name_name())))
|
||||
return mk_name_val_ne_proof(a, b);
|
||||
return none_expr();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,9 +137,15 @@ name const * g_list_cons = nullptr;
|
|||
name const * g_match_failed = nullptr;
|
||||
name const * g_monad = nullptr;
|
||||
name const * g_monad_fail = nullptr;
|
||||
name const * g_lean_name = nullptr;
|
||||
name const * g_lean_name_anonymous = nullptr;
|
||||
name const * g_lean_name_mk_numeral = nullptr;
|
||||
name const * g_lean_name_mk_string = nullptr;
|
||||
name const * g_lean_name_no_confusion = nullptr;
|
||||
name const * g_lean_name_mk_string_ne_mk_string_of_ne_prefix = nullptr;
|
||||
name const * g_lean_name_mk_string_ne_mk_string_of_ne_string = nullptr;
|
||||
name const * g_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix = nullptr;
|
||||
name const * g_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral = nullptr;
|
||||
name const * g_nat = nullptr;
|
||||
name const * g_nat_succ = nullptr;
|
||||
name const * g_nat_zero = nullptr;
|
||||
|
|
@ -383,9 +389,15 @@ void initialize_constants() {
|
|||
g_match_failed = new name{"match_failed"};
|
||||
g_monad = new name{"monad"};
|
||||
g_monad_fail = new name{"monad_fail"};
|
||||
g_lean_name = new name{"lean", "name"};
|
||||
g_lean_name_anonymous = new name{"lean", "name", "anonymous"};
|
||||
g_lean_name_mk_numeral = new name{"lean", "name", "mk_numeral"};
|
||||
g_lean_name_mk_string = new name{"lean", "name", "mk_string"};
|
||||
g_lean_name_no_confusion = new name{"lean", "name", "no_confusion"};
|
||||
g_lean_name_mk_string_ne_mk_string_of_ne_prefix = new name{"lean", "name", "mk_string_ne_mk_string_of_ne_prefix"};
|
||||
g_lean_name_mk_string_ne_mk_string_of_ne_string = new name{"lean", "name", "mk_string_ne_mk_string_of_ne_string"};
|
||||
g_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix = new name{"lean", "name", "mk_numeral_ne_mk_numeral_of_ne_prefix"};
|
||||
g_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral = new name{"lean", "name", "mk_numeral_ne_mk_numeral_of_ne_numeral"};
|
||||
g_nat = new name{"nat"};
|
||||
g_nat_succ = new name{"nat", "succ"};
|
||||
g_nat_zero = new name{"nat", "zero"};
|
||||
|
|
@ -630,9 +642,15 @@ void finalize_constants() {
|
|||
delete g_match_failed;
|
||||
delete g_monad;
|
||||
delete g_monad_fail;
|
||||
delete g_lean_name;
|
||||
delete g_lean_name_anonymous;
|
||||
delete g_lean_name_mk_numeral;
|
||||
delete g_lean_name_mk_string;
|
||||
delete g_lean_name_no_confusion;
|
||||
delete g_lean_name_mk_string_ne_mk_string_of_ne_prefix;
|
||||
delete g_lean_name_mk_string_ne_mk_string_of_ne_string;
|
||||
delete g_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix;
|
||||
delete g_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral;
|
||||
delete g_nat;
|
||||
delete g_nat_succ;
|
||||
delete g_nat_zero;
|
||||
|
|
@ -876,9 +894,15 @@ name const & get_list_cons_name() { return *g_list_cons; }
|
|||
name const & get_match_failed_name() { return *g_match_failed; }
|
||||
name const & get_monad_name() { return *g_monad; }
|
||||
name const & get_monad_fail_name() { return *g_monad_fail; }
|
||||
name const & get_lean_name_name() { return *g_lean_name; }
|
||||
name const & get_lean_name_anonymous_name() { return *g_lean_name_anonymous; }
|
||||
name const & get_lean_name_mk_numeral_name() { return *g_lean_name_mk_numeral; }
|
||||
name const & get_lean_name_mk_string_name() { return *g_lean_name_mk_string; }
|
||||
name const & get_lean_name_no_confusion_name() { return *g_lean_name_no_confusion; }
|
||||
name const & get_lean_name_mk_string_ne_mk_string_of_ne_prefix_name() { return *g_lean_name_mk_string_ne_mk_string_of_ne_prefix; }
|
||||
name const & get_lean_name_mk_string_ne_mk_string_of_ne_string_name() { return *g_lean_name_mk_string_ne_mk_string_of_ne_string; }
|
||||
name const & get_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix_name() { return *g_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix; }
|
||||
name const & get_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral_name() { return *g_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral; }
|
||||
name const & get_nat_name() { return *g_nat; }
|
||||
name const & get_nat_succ_name() { return *g_nat_succ; }
|
||||
name const & get_nat_zero_name() { return *g_nat_zero; }
|
||||
|
|
|
|||
|
|
@ -139,9 +139,15 @@ name const & get_list_cons_name();
|
|||
name const & get_match_failed_name();
|
||||
name const & get_monad_name();
|
||||
name const & get_monad_fail_name();
|
||||
name const & get_lean_name_name();
|
||||
name const & get_lean_name_anonymous_name();
|
||||
name const & get_lean_name_mk_numeral_name();
|
||||
name const & get_lean_name_mk_string_name();
|
||||
name const & get_lean_name_no_confusion_name();
|
||||
name const & get_lean_name_mk_string_ne_mk_string_of_ne_prefix_name();
|
||||
name const & get_lean_name_mk_string_ne_mk_string_of_ne_string_name();
|
||||
name const & get_lean_name_mk_numeral_ne_mk_numeral_of_ne_prefix_name();
|
||||
name const & get_lean_name_mk_numeral_ne_mk_numeral_of_ne_numeral_name();
|
||||
name const & get_nat_name();
|
||||
name const & get_nat_succ_name();
|
||||
name const & get_nat_zero_name();
|
||||
|
|
|
|||
|
|
@ -132,9 +132,15 @@ list.cons
|
|||
match_failed
|
||||
monad
|
||||
monad_fail
|
||||
lean.name
|
||||
lean.name.anonymous
|
||||
lean.name.mk_numeral
|
||||
lean.name.mk_string
|
||||
lean.name.no_confusion
|
||||
lean.name.mk_string_ne_mk_string_of_ne_prefix
|
||||
lean.name.mk_string_ne_mk_string_of_ne_string
|
||||
lean.name.mk_numeral_ne_mk_numeral_of_ne_prefix
|
||||
lean.name.mk_numeral_ne_mk_numeral_of_ne_numeral
|
||||
nat
|
||||
nat.succ
|
||||
nat.zero
|
||||
|
|
|
|||
|
|
@ -405,6 +405,11 @@ static lbool compare_values(expr const & a, expr const & b) {
|
|||
return to_lbool(*v1 == *v2);
|
||||
}}
|
||||
|
||||
if (auto v1 = name_lit_to_name(a)) {
|
||||
if (auto v2 = name_lit_to_name(b)) {
|
||||
return to_lbool(*v1 == *v2);
|
||||
}}
|
||||
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ Author: Leonardo de Moura
|
|||
#include "library/replace_visitor.h"
|
||||
#include "library/type_context.h"
|
||||
#include "library/string.h"
|
||||
#include "library/num.h"
|
||||
#include "version.h"
|
||||
#include "githash.h" // NOLINT
|
||||
|
||||
|
|
@ -1102,6 +1103,11 @@ optional<name> name_lit_to_name(expr const & name_lit) {
|
|||
if (auto str = to_string(app_arg(name_lit)))
|
||||
return optional<name>(name(*p, str->c_str()));
|
||||
}
|
||||
if (is_app_of(name_lit, get_lean_name_mk_numeral_name(), 2)) {
|
||||
if (auto p = name_lit_to_name(app_arg(app_fn(name_lit))))
|
||||
if (auto n = to_num(app_arg(name_lit)))
|
||||
return optional<name>(name(*p, n->get_unsigned_int()));
|
||||
}
|
||||
return optional<name>();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue