src/HOL/MiniML/Instance.thy
changeset 14422 b8da5f258b04
parent 5184 9b8547a9496a
equal deleted inserted replaced
14421:ee97b6463cb4 14422:b8da5f258b04
     4    Copyright  1996 TU Muenchen
     4    Copyright  1996 TU Muenchen
     5 
     5 
     6 Instances of type schemes
     6 Instances of type schemes
     7 *)
     7 *)
     8 
     8 
     9 Instance = Type + 
     9 theory Instance = Type:
    10 
    10 
    11   
    11   
    12 (* generic instances of a type scheme *)
    12 (* generic instances of a type scheme *)
    13 
    13 
    14 consts
    14 consts
    15   bound_typ_inst :: [subst, type_scheme] => typ
    15   bound_typ_inst :: "[subst, type_scheme] => typ"
    16 
    16 
    17 primrec
    17 primrec
    18   "bound_typ_inst S (FVar n) = (TVar n)"
    18   "bound_typ_inst S (FVar n) = (TVar n)"
    19   "bound_typ_inst S (BVar n) = (S n)"
    19   "bound_typ_inst S (BVar n) = (S n)"
    20   "bound_typ_inst S (sch1 =-> sch2) = ((bound_typ_inst S sch1) -> (bound_typ_inst S sch2))"
    20   "bound_typ_inst S (sch1 =-> sch2) = ((bound_typ_inst S sch1) -> (bound_typ_inst S sch2))"
    21 
    21 
    22 consts
    22 consts
    23   bound_scheme_inst :: [nat => type_scheme, type_scheme] => type_scheme
    23   bound_scheme_inst :: "[nat => type_scheme, type_scheme] => type_scheme"
    24 
    24 
    25 primrec
    25 primrec
    26   "bound_scheme_inst S (FVar n) = (FVar n)"
    26   "bound_scheme_inst S (FVar n) = (FVar n)"
    27   "bound_scheme_inst S (BVar n) = (S n)"
    27   "bound_scheme_inst S (BVar n) = (S n)"
    28   "bound_scheme_inst S (sch1 =-> sch2) = ((bound_scheme_inst S sch1) =-> (bound_scheme_inst S sch2))"
    28   "bound_scheme_inst S (sch1 =-> sch2) = ((bound_scheme_inst S sch1) =-> (bound_scheme_inst S sch2))"
    29   
    29   
    30 consts
    30 consts
    31   "<|" :: [typ, type_scheme] => bool (infixr 70)
    31   "<|" :: "[typ, type_scheme] => bool" (infixr 70)
    32 defs
    32 defs
    33   is_bound_typ_instance "t <| sch == ? S. t = (bound_typ_inst S sch)" 
    33   is_bound_typ_instance: "t <| sch == ? S. t = (bound_typ_inst S sch)" 
    34 
    34 
    35 instance type_scheme :: ord
    35 instance type_scheme :: ord ..
    36 defs le_type_scheme_def "sch' <= (sch::type_scheme) == !t. t <| sch' --> t <| sch"
    36 defs le_type_scheme_def: "sch' <= (sch::type_scheme) == !t. t <| sch' --> t <| sch"
    37 
    37 
    38 consts
    38 consts
    39   subst_to_scheme :: [nat => type_scheme, typ] => type_scheme
    39   subst_to_scheme :: "[nat => type_scheme, typ] => type_scheme"
    40 
    40 
    41 primrec
    41 primrec
    42   "subst_to_scheme B (TVar n) = (B n)"
    42   "subst_to_scheme B (TVar n) = (B n)"
    43   "subst_to_scheme B (t1 -> t2) = ((subst_to_scheme B t1) =-> (subst_to_scheme B t2))"
    43   "subst_to_scheme B (t1 -> t2) = ((subst_to_scheme B t1) =-> (subst_to_scheme B t2))"
    44   
    44   
    45 instance list :: (ord)ord
    45 instance list :: (ord)ord ..
    46 defs le_env_def
    46 defs le_env_def:
    47   "A <= B == length B = length A & (!i. i < length A --> A!i <= B!i)"
    47   "A <= B == length B = length A & (!i. i < length A --> A!i <= B!i)"
    48 
    48 
       
    49 
       
    50 (* lemmatas for instatiation *)
       
    51 
       
    52 
       
    53 (* lemmatas for bound_typ_inst *)
       
    54 
       
    55 lemma bound_typ_inst_mk_scheme: "bound_typ_inst S (mk_scheme t) = t"
       
    56 apply (induct_tac "t")
       
    57 apply (simp_all (no_asm_simp))
       
    58 done
       
    59 
       
    60 declare bound_typ_inst_mk_scheme [simp]
       
    61 
       
    62 lemma bound_typ_inst_composed_subst: "bound_typ_inst ($S o R) ($S sch) = $S (bound_typ_inst R sch)"
       
    63 apply (induct_tac "sch")
       
    64 apply simp_all
       
    65 done
       
    66 
       
    67 declare bound_typ_inst_composed_subst [simp]
       
    68 
       
    69 lemma bound_typ_inst_eq: "S = S' ==> sch = sch' ==> bound_typ_inst S sch = bound_typ_inst S' sch'"
       
    70 apply simp
       
    71 done
       
    72 
       
    73 
       
    74 
       
    75 (* lemmatas for bound_scheme_inst *)
       
    76 
       
    77 lemma bound_scheme_inst_mk_scheme: "bound_scheme_inst B (mk_scheme t) = mk_scheme t"
       
    78 apply (induct_tac "t")
       
    79 apply (simp (no_asm))
       
    80 apply (simp (no_asm_simp))
       
    81 done
       
    82 
       
    83 declare bound_scheme_inst_mk_scheme [simp]
       
    84 
       
    85 lemma substitution_lemma: "$S (bound_scheme_inst B sch) = (bound_scheme_inst ($S o B) ($ S sch))"
       
    86 apply (induct_tac "sch")
       
    87 apply (simp (no_asm))
       
    88 apply (simp (no_asm))
       
    89 apply (simp (no_asm_simp))
       
    90 done
       
    91 
       
    92 lemma bound_scheme_inst_type [rule_format (no_asm)]: "!t. mk_scheme t = bound_scheme_inst B sch -->  
       
    93           (? S. !x:bound_tv sch. B x = mk_scheme (S x))"
       
    94 apply (induct_tac "sch")
       
    95 apply (simp (no_asm))
       
    96 apply safe
       
    97 apply (rule exI)
       
    98 apply (rule ballI)
       
    99 apply (rule sym)
       
   100 apply simp
       
   101 apply simp
       
   102 apply (drule mk_scheme_Fun)
       
   103 apply (erule exE)+
       
   104 apply (erule conjE)
       
   105 apply (drule sym)
       
   106 apply (drule sym)
       
   107 apply (drule mp, fast)+
       
   108 apply safe
       
   109 apply (rename_tac S1 S2)
       
   110 apply (rule_tac x = "%x. if x:bound_tv type_scheme1 then (S1 x) else (S2 x) " in exI)
       
   111 apply auto
       
   112 done
       
   113 
       
   114 
       
   115 (* lemmas for subst_to_scheme *)
       
   116 
       
   117 lemma subst_to_scheme_inverse [rule_format (no_asm)]: "new_tv n sch --> subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k)  
       
   118                                                   (bound_typ_inst (%k. TVar (k + n)) sch) = sch"
       
   119 apply (induct_tac "sch")
       
   120 apply (simp (no_asm) add: le_def)
       
   121 apply (simp (no_asm) add: le_add2 diff_add_inverse2)
       
   122 apply (simp (no_asm_simp))
       
   123 done
       
   124 
       
   125 lemma aux: "t = t' ==>  
       
   126       subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) t =  
       
   127       subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) t'"
       
   128 apply fast
       
   129 done
       
   130 
       
   131 lemma aux2 [rule_format]: "new_tv n sch -->  
       
   132       subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) (bound_typ_inst S sch) =  
       
   133        bound_scheme_inst ((subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k)) o S) sch"
       
   134 apply (induct_tac "sch")
       
   135 apply auto
       
   136 done
       
   137 
       
   138 
       
   139 (* lemmata for <= *)
       
   140 
       
   141 lemma le_type_scheme_def2: 
       
   142   "!!(sch::type_scheme) sch'.  
       
   143    (sch' <= sch) = (? B. sch' = bound_scheme_inst B sch)"
       
   144 
       
   145 apply (unfold le_type_scheme_def is_bound_typ_instance)
       
   146 apply (rule iffI)
       
   147 apply (cut_tac sch = "sch" in fresh_variable_type_schemes)
       
   148 apply (cut_tac sch = "sch'" in fresh_variable_type_schemes)
       
   149 apply (drule make_one_new_out_of_two)
       
   150 apply assumption
       
   151 apply (erule_tac V = "? n. new_tv n sch'" in thin_rl)
       
   152 apply (erule exE)
       
   153 apply (erule allE)
       
   154 apply (drule mp)
       
   155 apply (rule_tac x = " (%k. TVar (k + n))" in exI)
       
   156 apply (rule refl)
       
   157 apply (erule exE)
       
   158 apply (erule conjE)+
       
   159 apply (drule_tac n = "n" in aux)
       
   160 apply (simp add: subst_to_scheme_inverse)
       
   161 apply (rule_tac x = " (subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k)) o S" in exI)
       
   162 apply (simp (no_asm_simp) add: aux2)
       
   163 apply safe
       
   164 apply (rule_tac x = "%n. bound_typ_inst S (B n) " in exI)
       
   165 apply (induct_tac "sch")
       
   166 apply (simp (no_asm))
       
   167 apply (simp (no_asm))
       
   168 apply (simp (no_asm_simp))
       
   169 done
       
   170 
       
   171 lemma le_type_eq_is_bound_typ_instance [rule_format (no_asm)]: "(mk_scheme t) <= sch = t <| sch"
       
   172 apply (unfold is_bound_typ_instance)
       
   173 apply (simp (no_asm) add: le_type_scheme_def2)
       
   174 apply (rule iffI)
       
   175 apply (erule exE)
       
   176 apply (frule bound_scheme_inst_type)
       
   177 apply (erule exE)
       
   178 apply (rule exI)
       
   179 apply (rule mk_scheme_injective)
       
   180 apply simp
       
   181 apply (rotate_tac 1)
       
   182 apply (rule mp)
       
   183 prefer 2 apply (assumption)
       
   184 apply (induct_tac "sch")
       
   185 apply (simp (no_asm))
       
   186 apply simp
       
   187 apply fast
       
   188 apply (intro strip)
       
   189 apply simp
       
   190 apply (erule exE)
       
   191 apply simp
       
   192 apply (rule exI)
       
   193 apply (induct_tac "sch")
       
   194 apply (simp (no_asm))
       
   195 apply (simp (no_asm))
       
   196 apply simp
       
   197 done
       
   198 
       
   199 lemma le_env_Cons: 
       
   200   "(sch # A <= sch' # B) = (sch <= (sch'::type_scheme) & A <= B)"
       
   201 apply (unfold le_env_def)
       
   202 apply (simp (no_asm))
       
   203 apply (rule iffI)
       
   204  apply clarify
       
   205  apply (rule conjI) 
       
   206   apply (erule_tac x = "0" in allE)
       
   207   apply simp
       
   208  apply (rule conjI, assumption)
       
   209  apply clarify
       
   210  apply (erule_tac x = "Suc i" in allE) 
       
   211  apply simp
       
   212 apply (rule conjI)
       
   213  apply fast
       
   214 apply (rule allI)
       
   215 apply (induct_tac "i")
       
   216 apply (simp_all (no_asm_simp))
       
   217 done
       
   218 declare le_env_Cons [iff]
       
   219 
       
   220 lemma is_bound_typ_instance_closed_subst: "t <| sch ==> $S t <| $S sch"
       
   221 apply (unfold is_bound_typ_instance)
       
   222 apply (erule exE)
       
   223 apply (rename_tac "SA") 
       
   224 apply (simp)
       
   225 apply (rule_tac x = "$S o SA" in exI)
       
   226 apply (simp (no_asm))
       
   227 done
       
   228 
       
   229 lemma S_compatible_le_scheme: "!!(sch::type_scheme) sch'. sch' <= sch ==> $S sch' <= $ S sch"
       
   230 apply (simp add: le_type_scheme_def2)
       
   231 apply (erule exE)
       
   232 apply (simp add: substitution_lemma)
       
   233 apply fast
       
   234 done
       
   235 
       
   236 lemma S_compatible_le_scheme_lists: 
       
   237  "!!(A::type_scheme list) A'. A' <= A ==> $S A' <= $ S A"
       
   238 apply (unfold le_env_def app_subst_list)
       
   239 apply (simp (no_asm) cong add: conj_cong)
       
   240 apply (fast intro!: S_compatible_le_scheme)
       
   241 done
       
   242 
       
   243 lemma bound_typ_instance_trans: "[| t <| sch; sch <= sch' |] ==> t <| sch'"
       
   244 apply (unfold le_type_scheme_def)
       
   245 apply fast
       
   246 done
       
   247 
       
   248 lemma le_type_scheme_refl: "sch <= (sch::type_scheme)"
       
   249 apply (unfold le_type_scheme_def)
       
   250 apply fast
       
   251 done
       
   252 declare le_type_scheme_refl [iff]
       
   253 
       
   254 lemma le_env_refl: "A <= (A::type_scheme list)"
       
   255 apply (unfold le_env_def)
       
   256 apply fast
       
   257 done
       
   258 declare le_env_refl [iff]
       
   259 
       
   260 lemma bound_typ_instance_BVar: "sch <= BVar n"
       
   261 apply (unfold le_type_scheme_def is_bound_typ_instance)
       
   262 apply (intro strip)
       
   263 apply (rule_tac x = "%a. t" in exI)
       
   264 apply (simp (no_asm))
       
   265 done
       
   266 declare bound_typ_instance_BVar [iff]
       
   267 
       
   268 lemma le_FVar: 
       
   269  "(sch <= FVar n) = (sch = FVar n)"
       
   270 apply (unfold le_type_scheme_def is_bound_typ_instance)
       
   271 apply (induct_tac "sch")
       
   272   apply (simp (no_asm))
       
   273  apply (simp (no_asm))
       
   274  apply fast
       
   275 apply simp
       
   276 apply fast
       
   277 done
       
   278 declare le_FVar [simp]
       
   279 
       
   280 lemma not_FVar_le_Fun: "~(FVar n <= sch1 =-> sch2)"
       
   281 apply (unfold le_type_scheme_def is_bound_typ_instance)
       
   282 apply (simp (no_asm))
       
   283 done
       
   284 declare not_FVar_le_Fun [iff]
       
   285 
       
   286 lemma not_BVar_le_Fun: "~(BVar n <= sch1 =-> sch2)"
       
   287 apply (unfold le_type_scheme_def is_bound_typ_instance)
       
   288 apply (simp (no_asm))
       
   289 apply (rule_tac x = "TVar n" in exI)
       
   290 apply (simp (no_asm))
       
   291 apply fast
       
   292 done
       
   293 declare not_BVar_le_Fun [iff]
       
   294 
       
   295 lemma Fun_le_FunD: 
       
   296   "(sch1 =-> sch2 <= sch1' =-> sch2') ==> sch1 <= sch1' & sch2 <= sch2'"
       
   297 apply (unfold le_type_scheme_def is_bound_typ_instance)
       
   298 apply (fastsimp)
       
   299 done
       
   300 
       
   301 lemma scheme_le_Fun [rule_format (no_asm)]: "(sch' <= sch1 =-> sch2) --> (? sch'1 sch'2. sch' = sch'1 =-> sch'2)"
       
   302 apply (induct_tac "sch'")
       
   303 apply (simp (no_asm_simp))
       
   304 apply (simp (no_asm_simp))
       
   305 apply fast
       
   306 done
       
   307 
       
   308 lemma le_type_scheme_free_tv [rule_format (no_asm)]: "!sch'::type_scheme. sch <= sch' --> free_tv sch' <= free_tv sch"
       
   309 apply (induct_tac "sch")
       
   310   apply (rule allI)
       
   311   apply (induct_tac "sch'")
       
   312     apply (simp (no_asm))
       
   313    apply (simp (no_asm))
       
   314   apply (simp (no_asm))
       
   315  apply (rule allI)
       
   316  apply (induct_tac "sch'")
       
   317    apply (simp (no_asm))
       
   318   apply (simp (no_asm))
       
   319  apply (simp (no_asm))
       
   320 apply (rule allI)
       
   321 apply (induct_tac "sch'")
       
   322   apply (simp (no_asm))
       
   323  apply (simp (no_asm))
       
   324 apply simp
       
   325 apply (intro strip)
       
   326 apply (drule Fun_le_FunD)
       
   327 apply fast
       
   328 done
       
   329 
       
   330 lemma le_env_free_tv [rule_format (no_asm)]: "!A::type_scheme list. A <= B --> free_tv B <= free_tv A"
       
   331 apply (induct_tac "B")
       
   332  apply (simp (no_asm))
       
   333 apply (rule allI)
       
   334 apply (induct_tac "A")
       
   335  apply (simp (no_asm) add: le_env_def)
       
   336 apply (simp (no_asm))
       
   337 apply (fast dest: le_type_scheme_free_tv)
       
   338 done
       
   339 
       
   340 
    49 end
   341 end