31 |
29 |
32 |
30 |
33 subsection {* Commands *} |
31 subsection {* Commands *} |
34 |
32 |
35 text{* Execution of commands *} |
33 text{* Execution of commands *} |
36 consts exec :: "((exp*state) * (nat*state)) set => ((com*state)*state)set" |
|
37 |
|
38 abbreviation |
|
39 exec_rel ("_/ -[_]-> _" [50,0,50] 50) |
|
40 "csig -[eval]-> s == (csig,s) \<in> exec eval" |
|
41 |
34 |
42 abbreviation (input) |
35 abbreviation (input) |
43 generic_rel ("_/ -|[_]-> _" [50,0,50] 50) |
36 generic_rel ("_/ -|[_]-> _" [50,0,50] 50) where |
44 "esig -|[eval]-> ns == (esig,ns) \<in> eval" |
37 "esig -|[eval]-> ns == (esig,ns) \<in> eval" |
45 |
38 |
46 text{*Command execution. Natural numbers represent Booleans: 0=True, 1=False*} |
39 text{*Command execution. Natural numbers represent Booleans: 0=True, 1=False*} |
47 inductive "exec eval" |
40 |
48 intros |
41 inductive_set |
49 Skip: "(SKIP,s) -[eval]-> s" |
42 exec :: "((exp*state) * (nat*state)) set => ((com*state)*state)set" |
50 |
43 and exec_rel :: "com * state => ((exp*state) * (nat*state)) set => state => bool" |
51 Assign: "(e,s) -|[eval]-> (v,s') ==> (x := e, s) -[eval]-> s'(x:=v)" |
44 ("_/ -[_]-> _" [50,0,50] 50) |
52 |
45 for eval :: "((exp*state) * (nat*state)) set" |
53 Semi: "[| (c0,s) -[eval]-> s2; (c1,s2) -[eval]-> s1 |] |
46 where |
|
47 "csig -[eval]-> s == (csig,s) \<in> exec eval" |
|
48 |
|
49 | Skip: "(SKIP,s) -[eval]-> s" |
|
50 |
|
51 | Assign: "(e,s) -|[eval]-> (v,s') ==> (x := e, s) -[eval]-> s'(x:=v)" |
|
52 |
|
53 | Semi: "[| (c0,s) -[eval]-> s2; (c1,s2) -[eval]-> s1 |] |
54 ==> (c0 ;; c1, s) -[eval]-> s1" |
54 ==> (c0 ;; c1, s) -[eval]-> s1" |
55 |
55 |
56 IfTrue: "[| (e,s) -|[eval]-> (0,s'); (c0,s') -[eval]-> s1 |] |
56 | IfTrue: "[| (e,s) -|[eval]-> (0,s'); (c0,s') -[eval]-> s1 |] |
57 ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1" |
57 ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1" |
58 |
58 |
59 IfFalse: "[| (e,s) -|[eval]-> (Suc 0, s'); (c1,s') -[eval]-> s1 |] |
59 | IfFalse: "[| (e,s) -|[eval]-> (Suc 0, s'); (c1,s') -[eval]-> s1 |] |
60 ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1" |
60 ==> (IF e THEN c0 ELSE c1, s) -[eval]-> s1" |
61 |
61 |
62 WhileFalse: "(e,s) -|[eval]-> (Suc 0, s1) |
62 | WhileFalse: "(e,s) -|[eval]-> (Suc 0, s1) |
63 ==> (WHILE e DO c, s) -[eval]-> s1" |
63 ==> (WHILE e DO c, s) -[eval]-> s1" |
64 |
64 |
65 WhileTrue: "[| (e,s) -|[eval]-> (0,s1); |
65 | WhileTrue: "[| (e,s) -|[eval]-> (0,s1); |
66 (c,s1) -[eval]-> s2; (WHILE e DO c, s2) -[eval]-> s3 |] |
66 (c,s1) -[eval]-> s2; (WHILE e DO c, s2) -[eval]-> s3 |] |
67 ==> (WHILE e DO c, s) -[eval]-> s3" |
67 ==> (WHILE e DO c, s) -[eval]-> s3" |
68 |
68 |
69 declare exec.intros [intro] |
69 declare exec.intros [intro] |
70 |
70 |
77 and exec_WHILE_case: "(WHILE b DO c,s) -[eval]-> t" |
77 and exec_WHILE_case: "(WHILE b DO c,s) -[eval]-> t" |
78 |
78 |
79 |
79 |
80 text{*Justifies using "exec" in the inductive definition of "eval"*} |
80 text{*Justifies using "exec" in the inductive definition of "eval"*} |
81 lemma exec_mono: "A<=B ==> exec(A) <= exec(B)" |
81 lemma exec_mono: "A<=B ==> exec(A) <= exec(B)" |
82 apply (unfold exec.defs ) |
82 apply (rule subsetI) |
83 apply (rule lfp_mono) |
83 apply (simp add: split_paired_all) |
84 apply (assumption | rule basic_monos)+ |
84 apply (erule exec.induct) |
85 done |
85 apply blast+ |
|
86 done |
|
87 |
|
88 lemma [pred_set_conv]: |
|
89 "((\<lambda>x x' y y'. ((x, x'), (y, y')) \<in> R) <= (\<lambda>x x' y y'. ((x, x'), (y, y')) \<in> S)) = (R <= S)" |
|
90 by (auto simp add: le_fun_def le_bool_def) |
|
91 |
|
92 lemma [pred_set_conv]: |
|
93 "((\<lambda>x x' y. ((x, x'), y) \<in> R) <= (\<lambda>x x' y. ((x, x'), y) \<in> S)) = (R <= S)" |
|
94 by (auto simp add: le_fun_def le_bool_def) |
86 |
95 |
87 ML {* |
96 ML {* |
88 Unify.trace_bound := 30; |
97 Unify.trace_bound := 30; |
89 Unify.search_bound := 60; |
98 Unify.search_bound := 60; |
90 *} |
99 *} |
100 |
109 |
101 |
110 |
102 subsection {* Expressions *} |
111 subsection {* Expressions *} |
103 |
112 |
104 text{* Evaluation of arithmetic expressions *} |
113 text{* Evaluation of arithmetic expressions *} |
105 consts |
114 |
|
115 inductive_set |
106 eval :: "((exp*state) * (nat*state)) set" |
116 eval :: "((exp*state) * (nat*state)) set" |
107 |
117 and eval_rel :: "[exp*state,nat*state] => bool" (infixl "-|->" 50) |
108 abbreviation |
118 where |
109 eval_rel :: "[exp*state,nat*state] => bool" (infixl "-|->" 50) |
119 "esig -|-> ns == (esig, ns) \<in> eval" |
110 "esig -|-> ns == (esig, ns) \<in> eval" |
120 |
111 |
121 | N [intro!]: "(N(n),s) -|-> (n,s)" |
112 inductive eval |
122 |
113 intros |
123 | X [intro!]: "(X(x),s) -|-> (s(x),s)" |
114 N [intro!]: "(N(n),s) -|-> (n,s)" |
124 |
115 |
125 | Op [intro]: "[| (e0,s) -|-> (n0,s0); (e1,s0) -|-> (n1,s1) |] |
116 X [intro!]: "(X(x),s) -|-> (s(x),s)" |
|
117 |
|
118 Op [intro]: "[| (e0,s) -|-> (n0,s0); (e1,s0) -|-> (n1,s1) |] |
|
119 ==> (Op f e0 e1, s) -|-> (f n0 n1, s1)" |
126 ==> (Op f e0 e1, s) -|-> (f n0 n1, s1)" |
120 |
127 |
121 valOf [intro]: "[| (c,s) -[eval]-> s0; (e,s0) -|-> (n,s1) |] |
128 | valOf [intro]: "[| (c,s) -[eval]-> s0; (e,s0) -|-> (n,s1) |] |
122 ==> (VALOF c RESULTIS e, s) -|-> (n, s1)" |
129 ==> (VALOF c RESULTIS e, s) -|-> (n, s1)" |
123 |
130 |
124 monos exec_mono |
131 monos exec_mono |
125 |
132 |
126 |
133 |
133 |
140 |
134 lemma var_assign_eval [intro!]: "(X x, s(x:=n)) -|-> (n, s(x:=n))" |
141 lemma var_assign_eval [intro!]: "(X x, s(x:=n)) -|-> (n, s(x:=n))" |
135 by (rule fun_upd_same [THEN subst], fast) |
142 by (rule fun_upd_same [THEN subst], fast) |
136 |
143 |
137 |
144 |
138 text{* Make the induction rule look nicer -- though eta_contract makes the new |
145 text{* Make the induction rule look nicer -- though @{text eta_contract} makes the new |
139 version look worse than it is...*} |
146 version look worse than it is...*} |
140 |
147 |
141 lemma split_lemma: |
148 lemma split_lemma: |
142 "{((e,s),(n,s')). P e s n s'} = Collect (split (%v. split (split P v)))" |
149 "{((e,s),(n,s')). P e s n s'} = Collect (split (%v. split (split P v)))" |
143 by auto |
150 by auto |
165 apply (frule Int_lower1 [THEN exec_mono, THEN subsetD]) |
172 apply (frule Int_lower1 [THEN exec_mono, THEN subsetD]) |
166 apply (auto simp add: split_lemma) |
173 apply (auto simp add: split_lemma) |
167 done |
174 done |
168 |
175 |
169 |
176 |
170 text{*Lemma for Function_eval. The major premise is that (c,s) executes to s1 |
177 text{*Lemma for @{text Function_eval}. The major premise is that @{text "(c,s)"} executes to @{text "s1"} |
171 using eval restricted to its functional part. Note that the execution |
178 using eval restricted to its functional part. Note that the execution |
172 (c,s) -[eval]-> s2 can use unrestricted eval! The reason is that |
179 @{text "(c,s) -[eval]-> s2"} can use unrestricted @{text eval}! The reason is that |
173 the execution (c,s) -[eval Int {...}]-> s1 assures us that execution is |
180 the execution @{text "(c,s) -[eval Int {...}]-> s1"} assures us that execution is |
174 functional on the argument (c,s). |
181 functional on the argument @{text "(c,s)"}. |
175 *} |
182 *} |
176 lemma com_Unique: |
183 lemma com_Unique: |
177 "(c,s) -[eval Int {((e,s),(n,t)). \<forall>nt'. (e,s) -|-> nt' --> (n,t)=nt'}]-> s1 |
184 "(c,s) -[eval Int {((e,s),(n,t)). \<forall>nt'. (e,s) -|-> nt' --> (n,t)=nt'}]-> s1 |
178 ==> \<forall>s2. (c,s) -[eval]-> s2 --> s2=s1" |
185 ==> \<forall>s2. (c,s) -[eval]-> s2 --> s2=s1" |
179 apply (induct set: exec) |
186 apply (induct set: exec) |