src/HOL/Isar_examples/W_correct.thy
changeset 10007 64bf7da1994a
parent 9659 b9cf6801f3da
child 10146 e89309dde9d3
equal deleted inserted replaced
10006:ede5f78b9398 10007:64bf7da1994a
     3     Author:     Markus Wenzel, TU Muenchen
     3     Author:     Markus Wenzel, TU Muenchen
     4 
     4 
     5 Correctness of Milner's type inference algorithm W (let-free version).
     5 Correctness of Milner's type inference algorithm W (let-free version).
     6 *)
     6 *)
     7 
     7 
     8 header {* Milner's type inference algorithm~W (let-free version) *};
     8 header {* Milner's type inference algorithm~W (let-free version) *}
     9 
     9 
    10 theory W_correct = Main + Type:;
    10 theory W_correct = Main + Type:
    11 
    11 
    12 text_raw {*
    12 text_raw {*
    13   \footnote{Based upon \url{http://isabelle.in.tum.de/library/HOL/W0}
    13   \footnote{Based upon \url{http://isabelle.in.tum.de/library/HOL/W0}
    14   by Dieter Nazareth and Tobias Nipkow.}
    14   by Dieter Nazareth and Tobias Nipkow.}
    15 *};
    15 *}
    16 
    16 
    17 
    17 
    18 subsection "Mini ML with type inference rules";
    18 subsection "Mini ML with type inference rules"
    19 
    19 
    20 datatype
    20 datatype
    21   expr = Var nat | Abs expr | App expr expr;
    21   expr = Var nat | Abs expr | App expr expr
    22 
    22 
    23 
    23 
    24 text {* Type inference rules. *};
    24 text {* Type inference rules. *}
    25 
    25 
    26 consts
    26 consts
    27   has_type :: "(typ list * expr * typ) set";
    27   has_type :: "(typ list * expr * typ) set"
    28 
    28 
    29 syntax
    29 syntax
    30   "_has_type" :: "[typ list, expr, typ] => bool"
    30   "_has_type" :: "[typ list, expr, typ] => bool"
    31     ("((_) |-/ (_) :: (_))" [60, 0, 60] 60);
    31     ("((_) |-/ (_) :: (_))" [60, 0, 60] 60)
    32 translations
    32 translations
    33   "a |- e :: t" == "(a,e,t) : has_type";
    33   "a |- e :: t" == "(a,e,t) : has_type"
    34 
    34 
    35 inductive has_type
    35 inductive has_type
    36   intros [simp]
    36   intros [simp]
    37     Var: "n < length a ==> a |- Var n :: a ! n"
    37     Var: "n < length a ==> a |- Var n :: a ! n"
    38     Abs: "t1#a |- e :: t2 ==> a |- Abs e :: t1 -> t2"
    38     Abs: "t1#a |- e :: t2 ==> a |- Abs e :: t1 -> t2"
    39     App: "a |- e1 :: t2 -> t1 ==> a |- e2 :: t2
    39     App: "a |- e1 :: t2 -> t1 ==> a |- e2 :: t2
    40       ==> a |- App e1 e2 :: t1";
    40       ==> a |- App e1 e2 :: t1"
    41 
    41 
    42 
    42 
    43 text {* Type assigment is closed wrt.\ substitution. *};
    43 text {* Type assigment is closed wrt.\ substitution. *}
    44 
    44 
    45 lemma has_type_subst_closed: "a |- e :: t ==> $s a |- e :: $s t";
    45 lemma has_type_subst_closed: "a |- e :: t ==> $s a |- e :: $s t"
    46 proof -;
    46 proof -
    47   assume "a |- e :: t";
    47   assume "a |- e :: t"
    48   thus ?thesis (is "?P a e t");
    48   thus ?thesis (is "?P a e t")
    49   proof (induct (open) ?P a e t);
    49   proof (induct (open) ?P a e t)
    50     case Var;
    50     case Var
    51     hence "n < length (map ($ s) a)"; by simp;
    51     hence "n < length (map ($ s) a)" by simp
    52     hence "map ($ s) a |- Var n :: map ($ s) a ! n";
    52     hence "map ($ s) a |- Var n :: map ($ s) a ! n"
    53       by (rule has_type.Var);
    53       by (rule has_type.Var)
    54     also; have "map ($ s) a ! n = $ s (a ! n)";
    54     also have "map ($ s) a ! n = $ s (a ! n)"
    55       by (rule nth_map);
    55       by (rule nth_map)
    56     also; have "map ($ s) a = $ s a";
    56     also have "map ($ s) a = $ s a"
    57       by (simp only: app_subst_list);
    57       by (simp only: app_subst_list)
    58     finally; show "?P a (Var n) (a ! n)"; .;
    58     finally show "?P a (Var n) (a ! n)" .
    59   next;
    59   next
    60     case Abs;
    60     case Abs
    61     hence "$ s t1 # map ($ s) a |- e :: $ s t2";
    61     hence "$ s t1 # map ($ s) a |- e :: $ s t2"
    62       by (simp add: app_subst_list);
    62       by (simp add: app_subst_list)
    63     hence "map ($ s) a |- Abs e :: $ s t1 -> $ s t2";
    63     hence "map ($ s) a |- Abs e :: $ s t1 -> $ s t2"
    64       by (rule has_type.Abs);
    64       by (rule has_type.Abs)
    65     thus "?P a (Abs e) (t1 -> t2)";
    65     thus "?P a (Abs e) (t1 -> t2)"
    66       by (simp add: app_subst_list);
    66       by (simp add: app_subst_list)
    67   next;
    67   next
    68     case App;
    68     case App
    69     thus "?P a (App e1 e2) t1"; by simp;
    69     thus "?P a (App e1 e2) t1" by simp
    70   qed;
    70   qed
    71 qed;
    71 qed
    72 
    72 
    73 
    73 
    74 subsection {* Type inference algorithm W *};
    74 subsection {* Type inference algorithm W *}
    75 
    75 
    76 consts
    76 consts
    77   W :: "[expr, typ list, nat] => (subst * typ * nat) maybe";
    77   W :: "[expr, typ list, nat] => (subst * typ * nat) maybe"
    78 
    78 
    79 primrec
    79 primrec
    80   "W (Var i) a n =
    80   "W (Var i) a n =
    81     (if i < length a then Ok (id_subst, a ! i, n) else Fail)"
    81     (if i < length a then Ok (id_subst, a ! i, n) else Fail)"
    82   "W (Abs e) a n =
    82   "W (Abs e) a n =
    84      Ok (s, (s n) -> t, m))"
    84      Ok (s, (s n) -> t, m))"
    85   "W (App e1 e2) a n =
    85   "W (App e1 e2) a n =
    86     ((s1, t1, m1) := W e1 a n;
    86     ((s1, t1, m1) := W e1 a n;
    87      (s2, t2, m2) := W e2 ($s1 a) m1;
    87      (s2, t2, m2) := W e2 ($s1 a) m1;
    88      u := mgu ($ s2 t1) (t2 -> TVar m2);
    88      u := mgu ($ s2 t1) (t2 -> TVar m2);
    89      Ok ($u o $s2 o s1, $u (TVar m2), Suc m2))";
    89      Ok ($u o $s2 o s1, $u (TVar m2), Suc m2))"
    90 
    90 
    91 
    91 
    92 subsection {* Correctness theorem *};
    92 subsection {* Correctness theorem *}
    93 
    93 
    94 theorem W_correct: "W e a n = Ok (s, t, m) ==> $ s a |- e :: t";
    94 theorem W_correct: "W e a n = Ok (s, t, m) ==> $ s a |- e :: t"
    95 proof -;
    95 proof -
    96   assume W_ok: "W e a n = Ok (s, t, m)";
    96   assume W_ok: "W e a n = Ok (s, t, m)"
    97   have "ALL a s t m n. Ok (s, t, m) = W e a n --> $ s a |- e :: t"
    97   have "ALL a s t m n. Ok (s, t, m) = W e a n --> $ s a |- e :: t"
    98     (is "?P e");
    98     (is "?P e")
    99   proof (induct (stripped) e);
    99   proof (induct (stripped) e)
   100     fix a s t m n;
   100     fix a s t m n
   101     {
   101     {
   102       fix i;
   102       fix i
   103       assume "Ok (s, t, m) = W (Var i) a n";
   103       assume "Ok (s, t, m) = W (Var i) a n"
   104       thus "$ s a |- Var i :: t"; by (simp split: if_splits);
   104       thus "$ s a |- Var i :: t" by (simp split: if_splits)
   105     next;
   105     next
   106       fix e; assume hyp: "?P e";
   106       fix e assume hyp: "?P e"
   107       assume "Ok (s, t, m) = W (Abs e) a n";
   107       assume "Ok (s, t, m) = W (Abs e) a n"
   108       then; obtain t' where "t = s n -> t'"
   108       then obtain t' where "t = s n -> t'"
   109 	  and "Ok (s, t', m) = W e (TVar n # a) (Suc n)";
   109 	  and "Ok (s, t', m) = W e (TVar n # a) (Suc n)"
   110 	by (auto split: bind_splits);
   110 	by (auto split: bind_splits)
   111       with hyp; show "$ s a |- Abs e :: t";
   111       with hyp show "$ s a |- Abs e :: t"
   112 	by (force intro: has_type.Abs);
   112 	by (force intro: has_type.Abs)
   113     next;
   113     next
   114       fix e1 e2; assume hyp1: "?P e1" and hyp2: "?P e2";
   114       fix e1 e2 assume hyp1: "?P e1" and hyp2: "?P e2"
   115       assume "Ok (s, t, m) = W (App e1 e2) a n";
   115       assume "Ok (s, t, m) = W (App e1 e2) a n"
   116       then; obtain s1 t1 n1 s2 t2 n2 u where
   116       then obtain s1 t1 n1 s2 t2 n2 u where
   117           s: "s = $ u o $ s2 o s1"
   117           s: "s = $ u o $ s2 o s1"
   118           and t: "t = u n2"
   118           and t: "t = u n2"
   119           and mgu_ok: "mgu ($ s2 t1) (t2 -> TVar n2) = Ok u"
   119           and mgu_ok: "mgu ($ s2 t1) (t2 -> TVar n2) = Ok u"
   120           and W1_ok: "W e1 a n = Ok (s1, t1, n1)"
   120           and W1_ok: "W e1 a n = Ok (s1, t1, n1)"
   121           and W2_ok: "W e2 ($ s1 a) n1 = Ok (s2, t2, n2)";
   121           and W2_ok: "W e2 ($ s1 a) n1 = Ok (s2, t2, n2)"
   122 	by (auto split: bind_splits);
   122 	by (auto split: bind_splits)
   123       show "$ s a |- App e1 e2 :: t";
   123       show "$ s a |- App e1 e2 :: t"
   124       proof (rule has_type.App);
   124       proof (rule has_type.App)
   125         from s; have s': "$ u ($ s2 ($ s1 a)) = $s a";
   125         from s have s': "$ u ($ s2 ($ s1 a)) = $s a"
   126           by (simp add: subst_comp_tel o_def);
   126           by (simp add: subst_comp_tel o_def)
   127         show "$s a |- e1 :: $ u t2 -> t";
   127         show "$s a |- e1 :: $ u t2 -> t"
   128         proof -;
   128         proof -
   129           from hyp1 W1_ok [symmetric]; have "$ s1 a |- e1 :: t1";
   129           from hyp1 W1_ok [symmetric] have "$ s1 a |- e1 :: t1"
   130             by blast;
   130             by blast
   131           hence "$ u ($ s2 ($ s1 a)) |- e1 :: $ u ($ s2 t1)";
   131           hence "$ u ($ s2 ($ s1 a)) |- e1 :: $ u ($ s2 t1)"
   132             by (intro has_type_subst_closed);
   132             by (intro has_type_subst_closed)
   133           with s' t mgu_ok; show ?thesis; by simp;
   133           with s' t mgu_ok show ?thesis by simp
   134         qed;
   134         qed
   135         show "$ s a |- e2 :: $ u t2";
   135         show "$ s a |- e2 :: $ u t2"
   136         proof -;
   136         proof -
   137           from hyp2 W2_ok [symmetric];
   137           from hyp2 W2_ok [symmetric]
   138           have "$ s2 ($ s1 a) |- e2 :: t2"; by blast;
   138           have "$ s2 ($ s1 a) |- e2 :: t2" by blast
   139           hence "$ u ($ s2 ($ s1 a)) |- e2 :: $ u t2";
   139           hence "$ u ($ s2 ($ s1 a)) |- e2 :: $ u t2"
   140             by (rule has_type_subst_closed);
   140             by (rule has_type_subst_closed)
   141           with s'; show ?thesis; by simp;
   141           with s' show ?thesis by simp
   142         qed;
   142         qed
   143       qed;
   143       qed
   144     };
   144     }
   145   qed;
   145   qed
   146   with W_ok [symmetric]; show ?thesis; by blast;
   146   with W_ok [symmetric] show ?thesis by blast
   147 qed;
   147 qed
   148 
   148 
   149 end;
   149 end