diff --git a/library/init/lean/name.lean b/library/init/lean/name.lean index de9f79d4ae..ab86a5596f 100644 --- a/library/init/lean/name.lean +++ b/library/init/lean/name.lean @@ -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 diff --git a/src/library/comp_val.cpp b/src/library/comp_val.cpp index b74cc426f3..b4ef9b812c 100644 --- a/src/library/comp_val.cpp +++ b/src/library/comp_val.cpp @@ -207,6 +207,54 @@ optional 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 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 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 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(); } diff --git a/src/library/constants.cpp b/src/library/constants.cpp index 51c825c6be..3e12b2952f 100644 --- a/src/library/constants.cpp +++ b/src/library/constants.cpp @@ -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; } diff --git a/src/library/constants.h b/src/library/constants.h index 7088475867..eb0fadb838 100644 --- a/src/library/constants.h +++ b/src/library/constants.h @@ -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(); diff --git a/src/library/constants.txt b/src/library/constants.txt index db3d2e8e27..d12d428c05 100644 --- a/src/library/constants.txt +++ b/src/library/constants.txt @@ -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 diff --git a/src/library/equations_compiler/util.cpp b/src/library/equations_compiler/util.cpp index c8bb0b4ea1..b3596ea772 100644 --- a/src/library/equations_compiler/util.cpp +++ b/src/library/equations_compiler/util.cpp @@ -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; } diff --git a/src/library/util.cpp b/src/library/util.cpp index 1e35871859..63cb46b00c 100644 --- a/src/library/util.cpp +++ b/src/library/util.cpp @@ -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_lit_to_name(expr const & name_lit) { if (auto str = to_string(app_arg(name_lit))) return optional(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(*p, n->get_unsigned_int())); + } return optional(); }