| author | blanchet | 
| Tue, 10 Sep 2013 15:56:51 +0200 | |
| changeset 53503 | d2f21e305d0c | 
| parent 52405 | 3dd63180cdbf | 
| child 54610 | 6593e06445e6 | 
| permissions | -rw-r--r-- | 
| 43150 | 1 | header "A Typed Language" | 
| 2 | ||
| 3 | theory Types imports Star Complex_Main begin | |
| 4 | ||
| 52405 | 5 | text {* We build on @{theory Complex_Main} instead of @{theory Main} to access
 | 
| 6 | the real numbers. *} | |
| 7 | ||
| 43150 | 8 | subsection "Arithmetic Expressions" | 
| 9 | ||
| 10 | datatype val = Iv int | Rv real | |
| 11 | ||
| 45212 | 12 | type_synonym vname = string | 
| 13 | type_synonym state = "vname \<Rightarrow> val" | |
| 43150 | 14 | |
| 51461 
e1e8191c6725
export datatype definition which gets expanded too much in antiquotation
 kleing parents: 
51454diff
changeset | 15 | text_raw{*\snip{aexptDef}{0}{2}{% *}
 | 
| 45212 | 16 | datatype aexp = Ic int | Rc real | V vname | Plus aexp aexp | 
| 51461 
e1e8191c6725
export datatype definition which gets expanded too much in antiquotation
 kleing parents: 
51454diff
changeset | 17 | text_raw{*}%endsnip*}
 | 
| 43150 | 18 | |
| 19 | inductive taval :: "aexp \<Rightarrow> state \<Rightarrow> val \<Rightarrow> bool" where | |
| 20 | "taval (Ic i) s (Iv i)" | | |
| 21 | "taval (Rc r) s (Rv r)" | | |
| 22 | "taval (V x) s (s x)" | | |
| 23 | "taval a1 s (Iv i1) \<Longrightarrow> taval a2 s (Iv i2) | |
| 24 | \<Longrightarrow> taval (Plus a1 a2) s (Iv(i1+i2))" | | |
| 44020 | 25 | "taval a1 s (Rv r1) \<Longrightarrow> taval a2 s (Rv r2) | 
| 43150 | 26 | \<Longrightarrow> taval (Plus a1 a2) s (Rv(r1+r2))" | 
| 27 | ||
| 28 | inductive_cases [elim!]: | |
| 29 | "taval (Ic i) s v" "taval (Rc i) s v" | |
| 30 | "taval (V x) s v" | |
| 31 | "taval (Plus a1 a2) s v" | |
| 32 | ||
| 33 | subsection "Boolean Expressions" | |
| 34 | ||
| 45200 | 35 | datatype bexp = Bc bool | Not bexp | And bexp bexp | Less aexp aexp | 
| 43150 | 36 | |
| 37 | inductive tbval :: "bexp \<Rightarrow> state \<Rightarrow> bool \<Rightarrow> bool" where | |
| 45200 | 38 | "tbval (Bc v) s v" | | 
| 43150 | 39 | "tbval b s bv \<Longrightarrow> tbval (Not b) s (\<not> bv)" | | 
| 44020 | 40 | "tbval b1 s bv1 \<Longrightarrow> tbval b2 s bv2 \<Longrightarrow> tbval (And b1 b2) s (bv1 & bv2)" | | 
| 41 | "taval a1 s (Iv i1) \<Longrightarrow> taval a2 s (Iv i2) \<Longrightarrow> tbval (Less a1 a2) s (i1 < i2)" | | |
| 42 | "taval a1 s (Rv r1) \<Longrightarrow> taval a2 s (Rv r2) \<Longrightarrow> tbval (Less a1 a2) s (r1 < r2)" | |
| 43150 | 43 | |
| 44 | subsection "Syntax of Commands" | |
| 45 | (* a copy of Com.thy - keep in sync! *) | |
| 46 | ||
| 47 | datatype | |
| 48 | com = SKIP | |
| 47818 | 49 |       | Assign vname aexp       ("_ ::= _" [1000, 61] 61)
 | 
| 52046 
bc01725d7918
replaced `;' by `;;' to disambiguate syntax; unexpected slight increase in build time
 nipkow parents: 
51461diff
changeset | 50 |       | Seq    com  com         ("_;; _"  [60, 61] 60)
 | 
| 43150 | 51 |       | If     bexp com com     ("IF _ THEN _ ELSE _"  [0, 0, 61] 61)
 | 
| 52 |       | While  bexp com         ("WHILE _ DO _"  [0, 61] 61)
 | |
| 53 | ||
| 54 | ||
| 55 | subsection "Small-Step Semantics of Commands" | |
| 56 | ||
| 57 | inductive | |
| 58 | small_step :: "(com \<times> state) \<Rightarrow> (com \<times> state) \<Rightarrow> bool" (infix "\<rightarrow>" 55) | |
| 59 | where | |
| 60 | Assign: "taval a s v \<Longrightarrow> (x ::= a, s) \<rightarrow> (SKIP, s(x := v))" | | |
| 61 | ||
| 52046 
bc01725d7918
replaced `;' by `;;' to disambiguate syntax; unexpected slight increase in build time
 nipkow parents: 
51461diff
changeset | 62 | Seq1: "(SKIP;;c,s) \<rightarrow> (c,s)" | | 
| 
bc01725d7918
replaced `;' by `;;' to disambiguate syntax; unexpected slight increase in build time
 nipkow parents: 
51461diff
changeset | 63 | Seq2: "(c1,s) \<rightarrow> (c1',s') \<Longrightarrow> (c1;;c2,s) \<rightarrow> (c1';;c2,s')" | | 
| 43150 | 64 | |
| 65 | IfTrue: "tbval b s True \<Longrightarrow> (IF b THEN c1 ELSE c2,s) \<rightarrow> (c1,s)" | | |
| 66 | IfFalse: "tbval b s False \<Longrightarrow> (IF b THEN c1 ELSE c2,s) \<rightarrow> (c2,s)" | | |
| 67 | ||
| 52046 
bc01725d7918
replaced `;' by `;;' to disambiguate syntax; unexpected slight increase in build time
 nipkow parents: 
51461diff
changeset | 68 | While: "(WHILE b DO c,s) \<rightarrow> (IF b THEN c;; WHILE b DO c ELSE SKIP,s)" | 
| 43150 | 69 | |
| 70 | lemmas small_step_induct = small_step.induct[split_format(complete)] | |
| 71 | ||
| 72 | subsection "The Type System" | |
| 73 | ||
| 74 | datatype ty = Ity | Rty | |
| 75 | ||
| 45212 | 76 | type_synonym tyenv = "vname \<Rightarrow> ty" | 
| 43150 | 77 | |
| 78 | inductive atyping :: "tyenv \<Rightarrow> aexp \<Rightarrow> ty \<Rightarrow> bool" | |
| 79 |   ("(1_/ \<turnstile>/ (_ :/ _))" [50,0,50] 50)
 | |
| 80 | where | |
| 81 | Ic_ty: "\<Gamma> \<turnstile> Ic i : Ity" | | |
| 82 | Rc_ty: "\<Gamma> \<turnstile> Rc r : Rty" | | |
| 83 | V_ty: "\<Gamma> \<turnstile> V x : \<Gamma> x" | | |
| 84 | Plus_ty: "\<Gamma> \<turnstile> a1 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> a2 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> Plus a1 a2 : \<tau>" | |
| 85 | ||
| 86 | text{* Warning: the ``:'' notation leads to syntactic ambiguities,
 | |
| 87 | i.e. multiple parse trees, because ``:'' also stands for set membership. | |
| 88 | In most situations Isabelle's type system will reject all but one parse tree, | |
| 89 | but will still inform you of the potential ambiguity. *} | |
| 90 | ||
| 91 | inductive btyping :: "tyenv \<Rightarrow> bexp \<Rightarrow> bool" (infix "\<turnstile>" 50) | |
| 92 | where | |
| 45200 | 93 | B_ty: "\<Gamma> \<turnstile> Bc v" | | 
| 43150 | 94 | Not_ty: "\<Gamma> \<turnstile> b \<Longrightarrow> \<Gamma> \<turnstile> Not b" | | 
| 95 | And_ty: "\<Gamma> \<turnstile> b1 \<Longrightarrow> \<Gamma> \<turnstile> b2 \<Longrightarrow> \<Gamma> \<turnstile> And b1 b2" | | |
| 96 | Less_ty: "\<Gamma> \<turnstile> a1 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> a2 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> Less a1 a2" | |
| 97 | ||
| 98 | inductive ctyping :: "tyenv \<Rightarrow> com \<Rightarrow> bool" (infix "\<turnstile>" 50) where | |
| 99 | Skip_ty: "\<Gamma> \<turnstile> SKIP" | | |
| 100 | Assign_ty: "\<Gamma> \<turnstile> a : \<Gamma>(x) \<Longrightarrow> \<Gamma> \<turnstile> x ::= a" | | |
| 52046 
bc01725d7918
replaced `;' by `;;' to disambiguate syntax; unexpected slight increase in build time
 nipkow parents: 
51461diff
changeset | 101 | Seq_ty: "\<Gamma> \<turnstile> c1 \<Longrightarrow> \<Gamma> \<turnstile> c2 \<Longrightarrow> \<Gamma> \<turnstile> c1;;c2" | | 
| 43150 | 102 | If_ty: "\<Gamma> \<turnstile> b \<Longrightarrow> \<Gamma> \<turnstile> c1 \<Longrightarrow> \<Gamma> \<turnstile> c2 \<Longrightarrow> \<Gamma> \<turnstile> IF b THEN c1 ELSE c2" | | 
| 103 | While_ty: "\<Gamma> \<turnstile> b \<Longrightarrow> \<Gamma> \<turnstile> c \<Longrightarrow> \<Gamma> \<turnstile> WHILE b DO c" | |
| 104 | ||
| 105 | inductive_cases [elim!]: | |
| 52046 
bc01725d7918
replaced `;' by `;;' to disambiguate syntax; unexpected slight increase in build time
 nipkow parents: 
51461diff
changeset | 106 | "\<Gamma> \<turnstile> x ::= a" "\<Gamma> \<turnstile> c1;;c2" | 
| 43150 | 107 | "\<Gamma> \<turnstile> IF b THEN c1 ELSE c2" | 
| 108 | "\<Gamma> \<turnstile> WHILE b DO c" | |
| 109 | ||
| 110 | subsection "Well-typed Programs Do Not Get Stuck" | |
| 111 | ||
| 112 | fun type :: "val \<Rightarrow> ty" where | |
| 113 | "type (Iv i) = Ity" | | |
| 114 | "type (Rv r) = Rty" | |
| 115 | ||
| 116 | lemma [simp]: "type v = Ity \<longleftrightarrow> (\<exists>i. v = Iv i)" | |
| 117 | by (cases v) simp_all | |
| 118 | ||
| 119 | lemma [simp]: "type v = Rty \<longleftrightarrow> (\<exists>r. v = Rv r)" | |
| 120 | by (cases v) simp_all | |
| 121 | ||
| 122 | definition styping :: "tyenv \<Rightarrow> state \<Rightarrow> bool" (infix "\<turnstile>" 50) | |
| 123 | where "\<Gamma> \<turnstile> s \<longleftrightarrow> (\<forall>x. type (s x) = \<Gamma> x)" | |
| 124 | ||
| 125 | lemma apreservation: | |
| 126 | "\<Gamma> \<turnstile> a : \<tau> \<Longrightarrow> taval a s v \<Longrightarrow> \<Gamma> \<turnstile> s \<Longrightarrow> type v = \<tau>" | |
| 45015 | 127 | apply(induction arbitrary: v rule: atyping.induct) | 
| 44890 
22f665a2e91c
new fastforce replacing fastsimp - less confusing name
 nipkow parents: 
44020diff
changeset | 128 | apply (fastforce simp: styping_def)+ | 
| 43150 | 129 | done | 
| 130 | ||
| 131 | lemma aprogress: "\<Gamma> \<turnstile> a : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> s \<Longrightarrow> \<exists>v. taval a s v" | |
| 45015 | 132 | proof(induction rule: atyping.induct) | 
| 43150 | 133 | case (Plus_ty \<Gamma> a1 t a2) | 
| 134 | then obtain v1 v2 where v: "taval a1 s v1" "taval a2 s v2" by blast | |
| 135 | show ?case | |
| 136 | proof (cases v1) | |
| 137 | case Iv | |
| 45015 | 138 | with Plus_ty v show ?thesis | 
| 44890 
22f665a2e91c
new fastforce replacing fastsimp - less confusing name
 nipkow parents: 
44020diff
changeset | 139 | by(fastforce intro: taval.intros(4) dest!: apreservation) | 
| 43150 | 140 | next | 
| 141 | case Rv | |
| 45015 | 142 | with Plus_ty v show ?thesis | 
| 44890 
22f665a2e91c
new fastforce replacing fastsimp - less confusing name
 nipkow parents: 
44020diff
changeset | 143 | by(fastforce intro: taval.intros(5) dest!: apreservation) | 
| 43150 | 144 | qed | 
| 145 | qed (auto intro: taval.intros) | |
| 146 | ||
| 147 | lemma bprogress: "\<Gamma> \<turnstile> b \<Longrightarrow> \<Gamma> \<turnstile> s \<Longrightarrow> \<exists>v. tbval b s v" | |
| 45015 | 148 | proof(induction rule: btyping.induct) | 
| 43150 | 149 | case (Less_ty \<Gamma> a1 t a2) | 
| 150 | then obtain v1 v2 where v: "taval a1 s v1" "taval a2 s v2" | |
| 151 | by (metis aprogress) | |
| 152 | show ?case | |
| 153 | proof (cases v1) | |
| 154 | case Iv | |
| 155 | with Less_ty v show ?thesis | |
| 44890 
22f665a2e91c
new fastforce replacing fastsimp - less confusing name
 nipkow parents: 
44020diff
changeset | 156 | by (fastforce intro!: tbval.intros(4) dest!:apreservation) | 
| 43150 | 157 | next | 
| 158 | case Rv | |
| 159 | with Less_ty v show ?thesis | |
| 44890 
22f665a2e91c
new fastforce replacing fastsimp - less confusing name
 nipkow parents: 
44020diff
changeset | 160 | by (fastforce intro!: tbval.intros(5) dest!:apreservation) | 
| 43150 | 161 | qed | 
| 162 | qed (auto intro: tbval.intros) | |
| 163 | ||
| 164 | theorem progress: | |
| 165 | "\<Gamma> \<turnstile> c \<Longrightarrow> \<Gamma> \<turnstile> s \<Longrightarrow> c \<noteq> SKIP \<Longrightarrow> \<exists>cs'. (c,s) \<rightarrow> cs'" | |
| 45015 | 166 | proof(induction rule: ctyping.induct) | 
| 43150 | 167 | case Skip_ty thus ?case by simp | 
| 168 | next | |
| 169 | case Assign_ty | |
| 170 | thus ?case by (metis Assign aprogress) | |
| 171 | next | |
| 47818 | 172 | case Seq_ty thus ?case by simp (metis Seq1 Seq2) | 
| 43150 | 173 | next | 
| 174 | case (If_ty \<Gamma> b c1 c2) | |
| 175 | then obtain bv where "tbval b s bv" by (metis bprogress) | |
| 176 | show ?case | |
| 177 | proof(cases bv) | |
| 178 | assume "bv" | |
| 179 | with `tbval b s bv` show ?case by simp (metis IfTrue) | |
| 180 | next | |
| 181 | assume "\<not>bv" | |
| 182 | with `tbval b s bv` show ?case by simp (metis IfFalse) | |
| 183 | qed | |
| 184 | next | |
| 185 | case While_ty show ?case by (metis While) | |
| 186 | qed | |
| 187 | ||
| 188 | theorem styping_preservation: | |
| 189 | "(c,s) \<rightarrow> (c',s') \<Longrightarrow> \<Gamma> \<turnstile> c \<Longrightarrow> \<Gamma> \<turnstile> s \<Longrightarrow> \<Gamma> \<turnstile> s'" | |
| 45015 | 190 | proof(induction rule: small_step_induct) | 
| 43150 | 191 | case Assign thus ?case | 
| 192 | by (auto simp: styping_def) (metis Assign(1,3) apreservation) | |
| 193 | qed auto | |
| 194 | ||
| 195 | theorem ctyping_preservation: | |
| 196 | "(c,s) \<rightarrow> (c',s') \<Longrightarrow> \<Gamma> \<turnstile> c \<Longrightarrow> \<Gamma> \<turnstile> c'" | |
| 197 | by (induct rule: small_step_induct) (auto simp: ctyping.intros) | |
| 198 | ||
| 199 | abbreviation small_steps :: "com * state \<Rightarrow> com * state \<Rightarrow> bool" (infix "\<rightarrow>*" 55) | |
| 200 | where "x \<rightarrow>* y == star small_step x y" | |
| 201 | ||
| 202 | theorem type_sound: | |
| 203 | "(c,s) \<rightarrow>* (c',s') \<Longrightarrow> \<Gamma> \<turnstile> c \<Longrightarrow> \<Gamma> \<turnstile> s \<Longrightarrow> c' \<noteq> SKIP | |
| 204 | \<Longrightarrow> \<exists>cs''. (c',s') \<rightarrow> cs''" | |
| 45015 | 205 | apply(induction rule:star_induct) | 
| 43150 | 206 | apply (metis progress) | 
| 207 | by (metis styping_preservation ctyping_preservation) | |
| 208 | ||
| 209 | end |