lean4-htt/library/init/lean/name.lean
Leonardo de Moura e9b4b811de chore(library/equations_compiler/util): disable generation of equational lemmas
@kha, `eqn_compiler.lemmas` is false by default.
I will keep them disabled until I remove the inductive compiler.
I'm building the new inductive datatype module (to replace the inductive
compiler), and the lemmas will fail to be proved in the next commits
until the transition is complete.
2018-06-12 13:03:25 -07:00

133 lines
5 KiB
Text

/-
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
-/
prelude
import init.data.string.basic init.coe init.data.uint init.data.to_string
import init.lean.format init.data.hashable
namespace lean
inductive name
| anonymous : name
| mk_string : name → string → name
| mk_numeral : name → nat → name
instance : inhabited name :=
⟨name.anonymous⟩
def mk_str_name (p : name) (s : string) : name :=
name.mk_string p s
def mk_num_name (p : name) (v : nat) : name :=
name.mk_numeral p v
def mk_simple_name (s : string) : name :=
mk_str_name name.anonymous s
instance string_to_name : has_coe string name :=
⟨mk_simple_name⟩
namespace name
private def hash_aux : name → usize → usize
| anonymous r := r
| (mk_string n s) r := hash_aux n (mix_hash r (hash s))
| (mk_numeral n k) r := hash_aux n (mix_hash r (hash k))
-- TODO: mark as opaque and builtin, and add as builtin
protected def hash (n : name) : usize :=
hash_aux n 11
instance : hashable name :=
⟨name.hash⟩
def get_prefix : name → name
| anonymous := anonymous
| (mk_string p s) := p
| (mk_numeral p s) := p
def update_prefix : name → name → name
| anonymous new_p := anonymous
| (mk_string p s) new_p := mk_string new_p s
| (mk_numeral p s) new_p := mk_numeral new_p s
instance has_decidable_eq : decidable_eq name
| anonymous anonymous := is_true rfl
| (mk_string p₁ s₁) (mk_string p₂ s₂) :=
if h₁ : s₁ = s₂ then
match has_decidable_eq p₁ p₂ with
| is_true h₂ := is_true $ h₁ ▸ h₂ ▸ rfl
| is_false h₂ := is_false $ λ h, name.no_confusion h $ λ hp hs, absurd hp h₂
else is_false $ λ h, name.no_confusion h $ λ hp hs, absurd hs h₁
| (mk_numeral p₁ n₁) (mk_numeral p₂ n₂) :=
if h₁ : n₁ = n₂ then
match has_decidable_eq p₁ p₂ with
| is_true h₂ := is_true $ h₁ ▸ h₂ ▸ rfl
| is_false h₂ := is_false $ λ h, name.no_confusion h $ λ hp hs, absurd hp h₂
else is_false $ λ h, name.no_confusion h $ λ hp hs, absurd hs h₁
| anonymous (mk_string _ _) := is_false $ λ h, name.no_confusion h
| anonymous (mk_numeral _ _) := is_false $ λ h, name.no_confusion h
| (mk_string _ _) anonymous := is_false $ λ h, name.no_confusion h
| (mk_string _ _) (mk_numeral _ _) := is_false $ λ h, name.no_confusion h
| (mk_numeral _ _) anonymous := is_false $ λ h, name.no_confusion h
| (mk_numeral _ _) (mk_string _ _) := is_false $ λ h, name.no_confusion h
def replace_prefix : name → name → name → name
| anonymous anonymous new_p := new_p
| anonymous _ _ := anonymous
| n@(mk_string p s) query_p new_p :=
if n = query_p then
new_p
else
mk_string (p.replace_prefix query_p new_p) s
| n@(mk_numeral p s) query_p new_p :=
if n = query_p then
new_p
else
mk_numeral (p.replace_prefix query_p new_p) s
def quick_lt : name → name → bool
| anonymous anonymous := ff
| anonymous _ := tt
| (mk_numeral n v) (mk_numeral n' v') := v < v' || (v = v' && n.quick_lt n')
| (mk_numeral _ _) (mk_string _ _) := tt
| (mk_string n s) (mk_string n' s') := s < s' || (s = s' && n.quick_lt n')
| _ _ := ff
/- Alternative has_lt instance. -/
protected def has_lt_quick : has_lt name :=
⟨λ a b, name.quick_lt a b = tt⟩
instance : decidable_rel (@has_lt.lt name name.has_lt_quick) :=
infer_instance_as (decidable_rel (λ a b, name.quick_lt a b = tt))
def to_string_with_sep (sep : string) : name → string
| anonymous := "[anonymous]"
| (mk_string anonymous s) := s
| (mk_numeral anonymous v) := to_string v
| (mk_string n s) := to_string_with_sep n ++ sep ++ s
| (mk_numeral n v) := to_string_with_sep n ++ sep ++ repr v
protected def to_string : name → string :=
to_string_with_sep "."
instance : has_to_string name :=
⟨name.to_string⟩
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