All theorems are proved without using the tactic framework. Thus, we can define `fin/uint32/uint64` types and their operations before we define the tactic framework.
112 lines
3.7 KiB
Text
112 lines
3.7 KiB
Text
/-
|
||
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import init.data.ordering.basic init.coe init.data.to_string
|
||
|
||
/-- Reflect a C++ name object. The VM replaces it with the C++ implementation. -/
|
||
inductive name
|
||
| anonymous : name
|
||
| mk_string : string → name → name
|
||
| mk_numeral : uint32 → name → name
|
||
|
||
/-- Gadget for automatic parameter support. This is similar to the opt_param gadget, but it uses
|
||
the tactic declaration names tac_name to synthesize the argument.
|
||
Like opt_param, this gadget only affects elaboration.
|
||
For example, the tactic will *not* be invoked during type class resolution. -/
|
||
@[reducible] def {u} auto_param (α : Sort u) (tac_name : name) : Sort u :=
|
||
α
|
||
|
||
@[simp] lemma {u} auto_param_eq (α : Sort u) (n : name) : auto_param α n = α :=
|
||
rfl
|
||
|
||
instance : inhabited name :=
|
||
⟨name.anonymous⟩
|
||
|
||
def mk_str_name (n : name) (s : string) : name :=
|
||
name.mk_string s n
|
||
|
||
def mk_num_name (n : name) (v : nat) : name :=
|
||
name.mk_numeral (uint32.of_nat v) n
|
||
|
||
def mk_simple_name (s : string) : name :=
|
||
mk_str_name name.anonymous s
|
||
|
||
instance string_to_name : has_coe string name :=
|
||
⟨mk_simple_name⟩
|
||
|
||
infix ` <.> `:65 := mk_str_name
|
||
|
||
open name
|
||
|
||
def name.get_prefix : name → name
|
||
| anonymous := anonymous
|
||
| (mk_string s p) := p
|
||
| (mk_numeral s p) := p
|
||
|
||
def name.update_prefix : name → name → name
|
||
| anonymous new_p := anonymous
|
||
| (mk_string s p) new_p := mk_string s new_p
|
||
| (mk_numeral s p) new_p := mk_numeral s new_p
|
||
|
||
/- The (decidable_eq string) has not been defined yet.
|
||
So, we disable the use of if-then-else when compiling the following definitions. -/
|
||
set_option eqn_compiler.ite false
|
||
|
||
def name.to_string_with_sep (sep : string) : name → string
|
||
| anonymous := "[anonymous]"
|
||
| (mk_string s anonymous) := s
|
||
| (mk_numeral v anonymous) := repr v
|
||
| (mk_string s n) := name.to_string_with_sep n ++ sep ++ s
|
||
| (mk_numeral v n) := name.to_string_with_sep n ++ sep ++ repr v
|
||
|
||
private def name.components' : name -> list name
|
||
| anonymous := []
|
||
| (mk_string s n) := mk_string s anonymous :: name.components' n
|
||
| (mk_numeral v n) := mk_numeral v anonymous :: name.components' n
|
||
|
||
def name.components (n : name) : list name :=
|
||
(name.components' n).reverse
|
||
|
||
protected def name.to_string : name → string :=
|
||
name.to_string_with_sep "."
|
||
|
||
instance : has_to_string name :=
|
||
⟨name.to_string⟩
|
||
|
||
/- TODO(Leo): provide a definition in Lean. -/
|
||
meta constant name.has_decidable_eq : decidable_eq name
|
||
/- Both cmp and lex_cmp are total orders, but lex_cmp implements a lexicographical order. -/
|
||
meta constant name.cmp : name → name → ordering
|
||
meta constant name.lex_cmp : name → name → ordering
|
||
meta constant name.append : name → name → name
|
||
meta constant name.is_internal : name → bool
|
||
|
||
protected meta def name.lt (a b : name) : Prop :=
|
||
name.cmp a b = ordering.lt
|
||
|
||
meta instance : decidable_rel name.lt :=
|
||
λ a b, ordering.decidable_eq _ _
|
||
|
||
meta instance : has_lt name :=
|
||
⟨name.lt⟩
|
||
|
||
attribute [instance] name.has_decidable_eq
|
||
|
||
meta instance : has_append name :=
|
||
⟨name.append⟩
|
||
|
||
/-- `name.append_after n i` return a name of the form n_i -/
|
||
meta constant name.append_after : name → nat → name
|
||
|
||
meta def name.is_prefix_of : name → name → bool
|
||
| p name.anonymous := ff
|
||
| p n :=
|
||
if p = n then tt else name.is_prefix_of p n.get_prefix
|
||
|
||
meta def name.replace_prefix : name → name → name → name
|
||
| anonymous p p' := anonymous
|
||
| (mk_string s c) p p' := if c = p then mk_string s p' else mk_string s (name.replace_prefix c p p')
|
||
| (mk_numeral v c) p p' := if c = p then mk_numeral v p' else mk_numeral v (name.replace_prefix c p p')
|