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:
Leonardo de Moura 2018-06-06 09:18:59 -07:00
parent e160154d14
commit 441b9077b2
7 changed files with 109 additions and 0 deletions

View file

@ -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

View file

@ -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();
}

View file

@ -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; }

View file

@ -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();

View file

@ -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

View file

@ -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;
}

View file

@ -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>();
}