|
1 (* Title: HOL/MicroJava/Comp/TypeInf.thy |
|
2 ID: $Id$ |
|
3 Author: Martin Strecker |
|
4 Copyright GPL 2002 |
|
5 *) |
|
6 |
|
7 (* Exact position in theory hierarchy still to be determined *) |
|
8 theory TypeInf = WellType: |
|
9 |
|
10 |
|
11 |
|
12 (**********************************************************************) |
|
13 ; |
|
14 |
|
15 (*** Inversion of typing rules -- to be moved into WellType.thy |
|
16 Also modify the wtpd_expr_\<dots> proofs in CorrComp.thy ***) |
|
17 |
|
18 lemma NewC_invers: "E\<turnstile>NewC C::T |
|
19 \<Longrightarrow> T = Class C \<and> is_class (prg E) C" |
|
20 by (erule ty_expr.cases, auto) |
|
21 |
|
22 lemma Cast_invers: "E\<turnstile>Cast D e::T |
|
23 \<Longrightarrow> \<exists> C. T = Class D \<and> E\<turnstile>e::Class C \<and> is_class (prg E) D \<and> prg E\<turnstile>C\<preceq>? D" |
|
24 by (erule ty_expr.cases, auto) |
|
25 |
|
26 lemma Lit_invers: "E\<turnstile>Lit x::T |
|
27 \<Longrightarrow> typeof (\<lambda>v. None) x = Some T" |
|
28 by (erule ty_expr.cases, auto) |
|
29 |
|
30 lemma LAcc_invers: "E\<turnstile>LAcc v::T |
|
31 \<Longrightarrow> localT E v = Some T \<and> is_type (prg E) T" |
|
32 by (erule ty_expr.cases, auto) |
|
33 |
|
34 lemma BinOp_invers: "E\<turnstile>BinOp bop e1 e2::T' |
|
35 \<Longrightarrow> \<exists> T. E\<turnstile>e1::T \<and> E\<turnstile>e2::T \<and> |
|
36 (if bop = Eq then T' = PrimT Boolean |
|
37 else T' = T \<and> T = PrimT Integer)" |
|
38 by (erule ty_expr.cases, auto) |
|
39 |
|
40 lemma LAss_invers: "E\<turnstile>v::=e::T' |
|
41 \<Longrightarrow> \<exists> T. v ~= This \<and> E\<turnstile>LAcc v::T \<and> E\<turnstile>e::T' \<and> prg E\<turnstile>T'\<preceq>T" |
|
42 by (erule ty_expr.cases, auto) |
|
43 |
|
44 lemma FAcc_invers: "E\<turnstile>{fd}a..fn::fT |
|
45 \<Longrightarrow> \<exists> C. E\<turnstile>a::Class C \<and> field (prg E,C) fn = Some (fd,fT)" |
|
46 by (erule ty_expr.cases, auto) |
|
47 |
|
48 lemma FAss_invers: "E\<turnstile>{fd}a..fn:=v::T' |
|
49 \<Longrightarrow> \<exists> T. E\<turnstile>{fd}a..fn::T \<and> E\<turnstile>v ::T' \<and> prg E\<turnstile>T'\<preceq>T" |
|
50 by (erule ty_expr.cases, auto) |
|
51 |
|
52 lemma Call_invers: "E\<turnstile>{C}a..mn({pTs'}ps)::rT |
|
53 \<Longrightarrow> \<exists> pTs md. |
|
54 E\<turnstile>a::Class C \<and> E\<turnstile>ps[::]pTs \<and> max_spec (prg E) C (mn, pTs) = {((md,rT),pTs')}" |
|
55 by (erule ty_expr.cases, auto) |
|
56 |
|
57 |
|
58 lemma Nil_invers: "E\<turnstile>[] [::] Ts \<Longrightarrow> Ts = []" |
|
59 by (erule ty_exprs.cases, auto) |
|
60 |
|
61 lemma Cons_invers: "E\<turnstile>e#es[::]Ts \<Longrightarrow> |
|
62 \<exists> T Ts'. Ts = T#Ts' \<and> E \<turnstile>e::T \<and> E \<turnstile>es[::]Ts'" |
|
63 by (erule ty_exprs.cases, auto) |
|
64 |
|
65 |
|
66 lemma Expr_invers: "E\<turnstile>Expr e\<surd> \<Longrightarrow> \<exists> T. E\<turnstile>e::T" |
|
67 by (erule wt_stmt.cases, auto) |
|
68 |
|
69 lemma Comp_invers: "E\<turnstile>s1;; s2\<surd> \<Longrightarrow> E\<turnstile>s1\<surd> \<and> E\<turnstile>s2\<surd>" |
|
70 by (erule wt_stmt.cases, auto) |
|
71 |
|
72 lemma Cond_invers: "E\<turnstile>If(e) s1 Else s2\<surd> |
|
73 \<Longrightarrow> E\<turnstile>e::PrimT Boolean \<and> E\<turnstile>s1\<surd> \<and> E\<turnstile>s2\<surd>" |
|
74 by (erule wt_stmt.cases, auto) |
|
75 |
|
76 lemma Loop_invers: "E\<turnstile>While(e) s\<surd> |
|
77 \<Longrightarrow> E\<turnstile>e::PrimT Boolean \<and> E\<turnstile>s\<surd>" |
|
78 by (erule wt_stmt.cases, auto) |
|
79 |
|
80 |
|
81 (**********************************************************************) |
|
82 |
|
83 |
|
84 declare split_paired_All [simp del] |
|
85 declare split_paired_Ex [simp del] |
|
86 |
|
87 (* Uniqueness of types property *) |
|
88 |
|
89 lemma uniqueness_of_types: " |
|
90 (\<forall> E T1 T2. E\<turnstile>e :: T1 \<longrightarrow> E\<turnstile>e :: T2 \<longrightarrow> T1 = T2) \<and> |
|
91 (\<forall> E Ts1 Ts2. E\<turnstile>es [::] Ts1 \<longrightarrow> E\<turnstile>es [::] Ts2 \<longrightarrow> Ts1 = Ts2)" |
|
92 |
|
93 apply (rule expr.induct) |
|
94 |
|
95 (* NewC *) |
|
96 apply (intro strip) |
|
97 apply (erule ty_expr.cases) apply simp+ |
|
98 apply (erule ty_expr.cases) apply simp+ |
|
99 |
|
100 (* Cast *) |
|
101 apply (intro strip) |
|
102 apply (erule ty_expr.cases) apply simp+ |
|
103 apply (erule ty_expr.cases) apply simp+ |
|
104 |
|
105 (* Lit *) |
|
106 apply (intro strip) |
|
107 apply (erule ty_expr.cases) apply simp+ |
|
108 apply (erule ty_expr.cases) apply simp+ |
|
109 |
|
110 (* BinOp *) |
|
111 apply (intro strip) |
|
112 apply (case_tac binop) |
|
113 (* Eq *) |
|
114 apply (erule ty_expr.cases) apply simp+ |
|
115 apply (erule ty_expr.cases) apply simp+ |
|
116 (* Add *) |
|
117 apply (erule ty_expr.cases) apply simp+ |
|
118 apply (erule ty_expr.cases) apply simp+ |
|
119 |
|
120 (* LAcc *) |
|
121 apply (intro strip) |
|
122 apply (erule ty_expr.cases) apply simp+ |
|
123 apply (erule ty_expr.cases) apply simp+ |
|
124 |
|
125 (* LAss *) |
|
126 apply (intro strip) |
|
127 apply (erule ty_expr.cases) apply simp+ |
|
128 apply (erule ty_expr.cases) apply simp+ |
|
129 |
|
130 |
|
131 (* FAcc *) |
|
132 apply (intro strip) |
|
133 apply (drule FAcc_invers)+ apply (erule exE)+ |
|
134 apply (subgoal_tac "C = Ca", simp) apply blast |
|
135 |
|
136 |
|
137 (* FAss *) |
|
138 apply (intro strip) |
|
139 apply (drule FAss_invers)+ apply (erule exE)+ apply (erule conjE)+ |
|
140 apply (drule FAcc_invers)+ apply (erule exE)+ apply blast |
|
141 |
|
142 |
|
143 (* Call *) |
|
144 apply (intro strip) |
|
145 apply (drule Call_invers)+ apply (erule exE)+ apply (erule conjE)+ |
|
146 apply (subgoal_tac "pTs = pTsa", simp) apply blast |
|
147 |
|
148 (* expression lists *) |
|
149 apply (intro strip) |
|
150 apply (erule ty_exprs.cases)+ apply simp+ |
|
151 |
|
152 apply (intro strip) |
|
153 apply (erule ty_exprs.cases, simp) |
|
154 apply (erule ty_exprs.cases, simp) |
|
155 apply (subgoal_tac "e = ea", simp) apply simp |
|
156 done |
|
157 |
|
158 |
|
159 lemma uniqueness_of_types_expr [rule_format (no_asm)]: " |
|
160 (\<forall> E T1 T2. E\<turnstile>e :: T1 \<longrightarrow> E\<turnstile>e :: T2 \<longrightarrow> T1 = T2)" |
|
161 by (rule uniqueness_of_types [THEN conjunct1]) |
|
162 |
|
163 lemma uniqueness_of_types_exprs [rule_format (no_asm)]: " |
|
164 (\<forall> E Ts1 Ts2. E\<turnstile>es [::] Ts1 \<longrightarrow> E\<turnstile>es [::] Ts2 \<longrightarrow> Ts1 = Ts2)" |
|
165 by (rule uniqueness_of_types [THEN conjunct2]) |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 constdefs |
|
171 inferred_tp :: "[java_mb env, expr] \<Rightarrow> ty" |
|
172 "inferred_tp E e == (SOME T. E\<turnstile>e :: T)" |
|
173 inferred_tps :: "[java_mb env, expr list] \<Rightarrow> ty list" |
|
174 "inferred_tps E es == (SOME Ts. E\<turnstile>es [::] Ts)" |
|
175 |
|
176 (* get inferred type(s) for well-typed term *) |
|
177 lemma inferred_tp_wt: "E\<turnstile>e :: T \<Longrightarrow> (inferred_tp E e) = T" |
|
178 by (auto simp: inferred_tp_def intro: uniqueness_of_types_expr) |
|
179 |
|
180 lemma inferred_tps_wt: "E\<turnstile>es [::] Ts \<Longrightarrow> (inferred_tps E es) = Ts" |
|
181 by (auto simp: inferred_tps_def intro: uniqueness_of_types_exprs) |
|
182 |
|
183 |
|
184 end |
|
185 |