61 ("(_/ \<turnstile> (_ \<rightarrow>/ _))" [59,0,59] 60) |
61 ("(_/ \<turnstile> (_ \<rightarrow>/ _))" [59,0,59] 60) |
62 where |
62 where |
63 "P \<turnstile> c \<rightarrow> c' = |
63 "P \<turnstile> c \<rightarrow> c' = |
64 (\<exists>i s stk. c = (i,s,stk) \<and> c' = iexec(P!!i) (i,s,stk) \<and> 0 \<le> i \<and> i < size P)" |
64 (\<exists>i s stk. c = (i,s,stk) \<and> c' = iexec(P!!i) (i,s,stk) \<and> 0 \<le> i \<and> i < size P)" |
65 |
65 |
|
66 (* |
66 declare exec1_def [simp] |
67 declare exec1_def [simp] |
|
68 *) |
67 |
69 |
68 lemma exec1I [intro, code_pred_intro]: |
70 lemma exec1I [intro, code_pred_intro]: |
69 "c' = iexec (P!!i) (i,s,stk) \<Longrightarrow> 0 \<le> i \<Longrightarrow> i < size P |
71 "c' = iexec (P!!i) (i,s,stk) \<Longrightarrow> 0 \<le> i \<Longrightarrow> i < size P |
70 \<Longrightarrow> P \<turnstile> (i,s,stk) \<rightarrow> c'" |
72 \<Longrightarrow> P \<turnstile> (i,s,stk) \<rightarrow> c'" |
71 by simp |
73 by (simp add: exec1_def) |
72 |
74 |
73 inductive exec :: "instr list \<Rightarrow> config \<Rightarrow> config \<Rightarrow> bool" |
75 abbreviation |
74 ("(_/ \<turnstile> (_ \<rightarrow>*/ _))" 50) |
76 exec :: "instr list \<Rightarrow> config \<Rightarrow> config \<Rightarrow> bool" ("(_/ \<turnstile> (_ \<rightarrow>*/ _))" 50) |
75 where |
77 where |
76 refl: "P \<turnstile> c \<rightarrow>* c" | |
78 "exec P \<equiv> star (exec1 P)" |
77 step: "P \<turnstile> c \<rightarrow> c' \<Longrightarrow> P \<turnstile> c' \<rightarrow>* c'' \<Longrightarrow> P \<turnstile> c \<rightarrow>* c''" |
79 |
78 |
80 declare star.step[intro] |
79 declare refl[intro] step[intro] |
81 |
80 |
82 lemmas exec_induct = star.induct [of "exec1 P", split_format(complete)] |
81 lemmas exec_induct = exec.induct[split_format(complete)] |
83 |
82 |
84 code_pred exec1 by (metis exec1_def) |
83 code_pred exec by fastforce |
|
84 |
85 |
85 values |
86 values |
86 "{(i,map t [''x'',''y''],stk) | i t stk. |
87 "{(i,map t [''x'',''y''],stk) | i t stk. |
87 [LOAD ''y'', STORE ''x''] \<turnstile> |
88 [LOAD ''y'', STORE ''x''] \<turnstile> |
88 (0, <''x'' := 3, ''y'' := 4>, []) \<rightarrow>* (i,t,stk)}" |
89 (0, <''x'' := 3, ''y'' := 4>, []) \<rightarrow>* (i,t,stk)}" |
89 |
90 |
90 |
91 |
91 subsection{* Verification infrastructure *} |
92 subsection{* Verification infrastructure *} |
92 |
93 |
93 lemma exec_trans: "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> P \<turnstile> c' \<rightarrow>* c'' \<Longrightarrow> P \<turnstile> c \<rightarrow>* c''" |
|
94 by (induction rule: exec.induct) fastforce+ |
|
95 |
|
96 text{* Below we need to argue about the execution of code that is embedded in |
94 text{* Below we need to argue about the execution of code that is embedded in |
97 larger programs. For this purpose we show that execution is preserved by |
95 larger programs. For this purpose we show that execution is preserved by |
98 appending code to the left or right of a program. *} |
96 appending code to the left or right of a program. *} |
99 |
97 |
100 lemma iexec_shift [simp]: |
98 lemma iexec_shift [simp]: |
101 "((n+i',s',stk') = iexec x (n+i,s,stk)) = ((i',s',stk') = iexec x (i,s,stk))" |
99 "((n+i',s',stk') = iexec x (n+i,s,stk)) = ((i',s',stk') = iexec x (i,s,stk))" |
102 by(auto split:instr.split) |
100 by(auto split:instr.split) |
103 |
101 |
104 lemma exec1_appendR: "P \<turnstile> c \<rightarrow> c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow> c'" |
102 lemma exec1_appendR: "P \<turnstile> c \<rightarrow> c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow> c'" |
105 by auto |
103 by (auto simp: exec1_def) |
106 |
104 |
107 lemma exec_appendR: "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow>* c'" |
105 lemma exec_appendR: "P \<turnstile> c \<rightarrow>* c' \<Longrightarrow> P@P' \<turnstile> c \<rightarrow>* c'" |
108 by (induction rule: exec.induct) (fastforce intro: exec1_appendR)+ |
106 by (induction rule: star.induct) (fastforce intro: exec1_appendR)+ |
109 |
107 |
110 lemma exec1_appendL: |
108 lemma exec1_appendL: |
111 fixes i i' :: int |
109 fixes i i' :: int |
112 shows |
110 shows |
113 "P \<turnstile> (i,s,stk) \<rightarrow> (i',s',stk') \<Longrightarrow> |
111 "P \<turnstile> (i,s,stk) \<rightarrow> (i',s',stk') \<Longrightarrow> |
114 P' @ P \<turnstile> (size(P')+i,s,stk) \<rightarrow> (size(P')+i',s',stk')" |
112 P' @ P \<turnstile> (size(P')+i,s,stk) \<rightarrow> (size(P')+i',s',stk')" |
|
113 unfolding exec1_def |
115 by (auto split: instr.split) |
114 by (auto split: instr.split) |
116 |
115 |
117 lemma exec_appendL: |
116 lemma exec_appendL: |
118 fixes i i' :: int |
117 fixes i i' :: int |
119 shows |
118 shows |
235 have "?cc1 @ ?cc2 \<turnstile> (0,s1,stk) \<rightarrow>* (size ?cc1,s2,stk)" |
234 have "?cc1 @ ?cc2 \<turnstile> (0,s1,stk) \<rightarrow>* (size ?cc1,s2,stk)" |
236 using Seq.IH(1) by fastforce |
235 using Seq.IH(1) by fastforce |
237 moreover |
236 moreover |
238 have "?cc1 @ ?cc2 \<turnstile> (size ?cc1,s2,stk) \<rightarrow>* (size(?cc1 @ ?cc2),s3,stk)" |
237 have "?cc1 @ ?cc2 \<turnstile> (size ?cc1,s2,stk) \<rightarrow>* (size(?cc1 @ ?cc2),s3,stk)" |
239 using Seq.IH(2) by fastforce |
238 using Seq.IH(2) by fastforce |
240 ultimately show ?case by simp (blast intro: exec_trans) |
239 ultimately show ?case by simp (blast intro: star_trans) |
241 next |
240 next |
242 case (WhileTrue b s1 c s2 s3) |
241 case (WhileTrue b s1 c s2 s3) |
243 let ?cc = "ccomp c" |
242 let ?cc = "ccomp c" |
244 let ?cb = "bcomp b False (size ?cc + 1)" |
243 let ?cb = "bcomp b False (size ?cc + 1)" |
245 let ?cw = "ccomp(WHILE b DO c)" |
244 let ?cw = "ccomp(WHILE b DO c)" |