Nominal-General/Atoms.thy
changeset 2568 8193bbaa07fe
parent 2567 41137dc935ff
child 2569 94750b31a97d
equal deleted inserted replaced
2567:41137dc935ff 2568:8193bbaa07fe
     1 (*  Title:      Atoms
       
     2     Authors:    Brian Huffman, Christian Urban
       
     3 
       
     4     Instantiations of concrete atoms 
       
     5 *)
       
     6 theory Atoms
       
     7 imports Nominal2_Base
       
     8 uses "~~/src/Tools/subtyping.ML"
       
     9 begin
       
    10 
       
    11 
       
    12 
       
    13 section {* @{const nat_of} is an example of a function 
       
    14   without finite support *}
       
    15 
       
    16 
       
    17 lemma not_fresh_nat_of:
       
    18   shows "\<not> a \<sharp> nat_of"
       
    19 unfolding fresh_def supp_def
       
    20 proof (clarsimp)
       
    21   assume "finite {b. (a \<rightleftharpoons> b) \<bullet> nat_of \<noteq> nat_of}"
       
    22   hence "finite ({a} \<union> {b. (a \<rightleftharpoons> b) \<bullet> nat_of \<noteq> nat_of})"
       
    23     by simp
       
    24   then obtain b where
       
    25     b1: "b \<noteq> a" and
       
    26     b2: "sort_of b = sort_of a" and
       
    27     b3: "(a \<rightleftharpoons> b) \<bullet> nat_of = nat_of"
       
    28     by (rule obtain_atom) auto
       
    29   have "nat_of a = (a \<rightleftharpoons> b) \<bullet> (nat_of a)" by (simp add: permute_nat_def)
       
    30   also have "\<dots> = ((a \<rightleftharpoons> b) \<bullet> nat_of) ((a \<rightleftharpoons> b) \<bullet> a)" by (simp add: permute_fun_app_eq)
       
    31   also have "\<dots> = nat_of ((a \<rightleftharpoons> b) \<bullet> a)" using b3 by simp
       
    32   also have "\<dots> = nat_of b" using b2 by simp
       
    33   finally have "nat_of a = nat_of b" by simp
       
    34   with b2 have "a = b" by (simp add: atom_components_eq_iff)
       
    35   with b1 show "False" by simp
       
    36 qed
       
    37 
       
    38 lemma supp_nat_of:
       
    39   shows "supp nat_of = UNIV"
       
    40   using not_fresh_nat_of [unfolded fresh_def] by auto
       
    41 
       
    42 
       
    43 section {* Manual instantiation of class @{text at}. *}
       
    44 
       
    45 typedef (open) name = "{a. sort_of a = Sort ''name'' []}"
       
    46 by (rule exists_eq_simple_sort)
       
    47 
       
    48 instantiation name :: at
       
    49 begin
       
    50 
       
    51 definition
       
    52   "p \<bullet> a = Abs_name (p \<bullet> Rep_name a)"
       
    53 
       
    54 definition
       
    55   "atom a = Rep_name a"
       
    56 
       
    57 instance
       
    58 apply (rule at_class)
       
    59 apply (rule type_definition_name)
       
    60 apply (rule atom_name_def)
       
    61 apply (rule permute_name_def)
       
    62 done
       
    63 
       
    64 end
       
    65 
       
    66 lemma sort_of_atom_name: 
       
    67   shows "sort_of (atom (a::name)) = Sort ''name'' []"
       
    68   unfolding atom_name_def using Rep_name by simp
       
    69 
       
    70 text {* Custom syntax for concrete atoms of type at *}
       
    71 
       
    72 term "a:::name"
       
    73 
       
    74 text {* 
       
    75   a:::name stands for (atom a) with a being of concrete atom 
       
    76   type name. The above lemma can therefore also be stated as
       
    77 
       
    78   "sort_of (a:::name) = Sort ''name'' []"
       
    79 
       
    80   This does not work for multi-sorted atoms.
       
    81 *}
       
    82 
       
    83 
       
    84 section {* Automatic instantiation of class @{text at}. *}
       
    85 
       
    86 atom_decl name2
       
    87 
       
    88 lemma sort_of_atom_name2:
       
    89   "sort_of (atom (a::name2)) = Sort ''Atoms.name2'' []"
       
    90 unfolding atom_name2_def 
       
    91 using Rep_name2 
       
    92 by simp
       
    93 
       
    94 text {* example swappings *}
       
    95 lemma
       
    96   fixes a b::"atom"
       
    97   assumes "sort_of a = sort_of b"
       
    98   shows "(a \<rightleftharpoons> b) \<bullet> (a, b) = (b, a)"
       
    99 using assms
       
   100 by simp
       
   101 
       
   102 lemma
       
   103   fixes a b::"name2"
       
   104   shows "(a \<leftrightarrow> b) \<bullet> (a, b) = (b, a)"
       
   105 by simp
       
   106 
       
   107 section {* An example for multiple-sort atoms *}
       
   108 
       
   109 datatype ty =
       
   110   TVar string
       
   111 | Fun ty ty ("_ \<rightarrow> _")
       
   112 
       
   113 primrec
       
   114   sort_of_ty::"ty \<Rightarrow> atom_sort"
       
   115 where
       
   116   "sort_of_ty (TVar s) = Sort ''TVar'' [Sort s []]"
       
   117 | "sort_of_ty (Fun ty1 ty2) = Sort ''Fun'' [sort_of_ty ty1, sort_of_ty ty2]"
       
   118 
       
   119 lemma sort_of_ty_eq_iff:
       
   120   shows "sort_of_ty x = sort_of_ty y \<longleftrightarrow> x = y"
       
   121 apply(induct x arbitrary: y)
       
   122 apply(case_tac [!] y)
       
   123 apply(simp_all)
       
   124 done
       
   125 
       
   126 declare sort_of_ty.simps [simp del]
       
   127 
       
   128 typedef (open) var = "{a. sort_of a \<in> range sort_of_ty}"
       
   129   by (rule_tac x="Atom (sort_of_ty x) y" in exI, simp)
       
   130 
       
   131 instantiation var :: at_base
       
   132 begin
       
   133 
       
   134 definition
       
   135   "p \<bullet> a = Abs_var (p \<bullet> Rep_var a)"
       
   136 
       
   137 definition
       
   138   "atom a = Rep_var a"
       
   139 
       
   140 instance
       
   141 apply (rule at_base_class)
       
   142 apply (rule type_definition_var)
       
   143 apply (rule atom_var_def)
       
   144 apply (rule permute_var_def)
       
   145 done
       
   146 
       
   147 end
       
   148 
       
   149 text {* Constructor for variables. *}
       
   150 
       
   151 definition
       
   152   Var :: "nat \<Rightarrow> ty \<Rightarrow> var"
       
   153 where
       
   154   "Var x t = Abs_var (Atom (sort_of_ty t) x)"
       
   155 
       
   156 lemma Var_eq_iff [simp]:
       
   157   shows "Var x s = Var y t \<longleftrightarrow> x = y \<and> s = t"
       
   158   unfolding Var_def
       
   159   by (auto simp add: Abs_var_inject sort_of_ty_eq_iff)
       
   160 
       
   161 lemma sort_of_atom_var [simp]:
       
   162   "sort_of (atom (Var n ty)) = sort_of_ty ty"
       
   163   unfolding atom_var_def Var_def
       
   164   by (simp add: Abs_var_inverse)
       
   165 
       
   166 lemma 
       
   167   assumes "\<alpha> \<noteq> \<beta>" 
       
   168   shows "(Var x \<alpha> \<leftrightarrow> Var y \<alpha>) \<bullet> (Var x \<alpha>, Var x \<beta>) = (Var y \<alpha>, Var x \<beta>)"
       
   169   using assms by simp
       
   170 
       
   171 text {* Projecting out the type component of a variable. *}
       
   172 
       
   173 definition
       
   174   ty_of :: "var \<Rightarrow> ty"
       
   175 where
       
   176   "ty_of x = inv sort_of_ty (sort_of (atom x))"
       
   177 
       
   178 text {*
       
   179   Functions @{term Var}/@{term ty_of} satisfy many of the same
       
   180   properties as @{term Atom}/@{term sort_of}.
       
   181 *}
       
   182 
       
   183 lemma ty_of_Var [simp]:
       
   184   shows "ty_of (Var x t) = t"
       
   185   unfolding ty_of_def
       
   186   unfolding sort_of_atom_var
       
   187   apply (rule inv_f_f)
       
   188   apply (simp add: inj_on_def sort_of_ty_eq_iff)
       
   189   done
       
   190 
       
   191 lemma ty_of_permute [simp]:
       
   192   shows "ty_of (p \<bullet> x) = ty_of x"
       
   193   unfolding ty_of_def
       
   194   unfolding atom_eqvt [symmetric]
       
   195   by simp
       
   196 
       
   197 
       
   198 section {* Tests with subtyping and automatic coercions *}
       
   199 
       
   200 setup Subtyping.setup
       
   201 
       
   202 atom_decl var1
       
   203 atom_decl var2
       
   204 
       
   205 declare [[coercion "atom::var1\<Rightarrow>atom"]]
       
   206 
       
   207 declare [[coercion "atom::var2\<Rightarrow>atom"]]
       
   208 
       
   209 lemma
       
   210   fixes a::"var1" and b::"var2"
       
   211   shows "a \<sharp> t \<and> b \<sharp> t"
       
   212 oops
       
   213 
       
   214 (* does not yet work: it needs image as
       
   215    coercion map *)
       
   216 
       
   217 lemma
       
   218   fixes as::"var1 set"
       
   219   shows "atom ` as \<sharp>* t"
       
   220 oops
       
   221 
       
   222 end