936
|
1 |
(* Title: HOL/IMP/Hoare.ML
|
|
2 |
ID:
|
|
3 |
Author: Tobias Nipkow
|
|
4 |
Copyright 1995 TUM
|
|
5 |
|
|
6 |
Derivation of Hoare rules
|
|
7 |
*)
|
|
8 |
|
|
9 |
open Hoare;
|
|
10 |
|
|
11 |
Unify.trace_bound := 30;
|
|
12 |
Unify.search_bound := 30;
|
|
13 |
|
|
14 |
goalw Hoare.thy [spec_def]
|
|
15 |
"!!P.[| !s. P' s --> P s; {{P}}c{{Q}}; !s. Q s --> Q' s |] \
|
|
16 |
\ ==> {{P'}}c{{Q'}}";
|
|
17 |
by(fast_tac HOL_cs 1);
|
|
18 |
bind_thm("hoare_conseq", impI RSN (3,allI RSN (3,impI RS allI RS result())));
|
|
19 |
|
|
20 |
goalw Hoare.thy (spec_def::C_simps) "{{P}} skip {{P}}";
|
|
21 |
by(fast_tac comp_cs 1);
|
|
22 |
qed"hoare_skip";
|
|
23 |
|
|
24 |
goalw Hoare.thy (spec_def::C_simps)
|
|
25 |
"!!P. [| !s. P s --> Q(s[A a s/x]) |] ==> {{P}} x := a {{Q}}";
|
|
26 |
by(asm_full_simp_tac prod_ss 1);
|
|
27 |
qed"hoare_assign";
|
|
28 |
|
|
29 |
goalw Hoare.thy (spec_def::C_simps)
|
|
30 |
"!!P. [| {{P}} c {{Q}}; {{Q}} d {{R}} |] ==> {{P}} c;d {{R}}";
|
|
31 |
by(fast_tac comp_cs 1);
|
|
32 |
qed"hoare_seq";
|
|
33 |
|
|
34 |
goalw Hoare.thy (spec_def::C_simps)
|
|
35 |
"!!P. [| {{%s. P s & B b s}} c {{Q}}; {{%s. P s & ~B b s}} d {{Q}} |] ==> \
|
|
36 |
\ {{P}} ifc b then c else d {{Q}}";
|
|
37 |
by(simp_tac prod_ss 1);
|
|
38 |
by(fast_tac comp_cs 1);
|
|
39 |
qed"hoare_if";
|
|
40 |
|
|
41 |
val major::prems = goal Hoare.thy
|
|
42 |
"[| <a,b> :lfp f; mono f; \
|
|
43 |
\ !!a b. <a,b> : f(lfp f Int Collect(split P)) ==> P a b |] ==> P a b";
|
|
44 |
by(res_inst_tac [("c1","P")] (split RS subst) 1);
|
|
45 |
br (major RS induct) 1;
|
|
46 |
brs prems 1;
|
|
47 |
by(res_inst_tac[("p","x")]PairE 1);
|
|
48 |
by(hyp_subst_tac 1);
|
|
49 |
by(asm_simp_tac (prod_ss addsimps prems) 1);
|
|
50 |
qed"induct2";
|
|
51 |
|
|
52 |
goalw Hoare.thy (spec_def::C_simps)
|
|
53 |
"!!P. [| {{%s. P s & B b s}} c {{P}} |] ==> \
|
|
54 |
\ {{P}} while b do c {{%s. P s & ~B b s}}";
|
|
55 |
br allI 1;
|
|
56 |
br allI 1;
|
|
57 |
br impI 1;
|
|
58 |
be induct2 1;
|
|
59 |
br Gamma_mono 1;
|
|
60 |
by (rewrite_goals_tac [Gamma_def]);
|
|
61 |
by(eres_inst_tac [("x","a")] allE 1);
|
|
62 |
by (safe_tac comp_cs);
|
|
63 |
by(ALLGOALS(asm_full_simp_tac prod_ss));
|
|
64 |
qed"hoare_while";
|
|
65 |
|
|
66 |
fun while_tac inv ss i =
|
|
67 |
EVERY[res_inst_tac[("P",inv)] hoare_conseq i, atac i, rtac hoare_while i,
|
|
68 |
asm_full_simp_tac ss (i+1)];
|
|
69 |
|
|
70 |
fun assign_tac ss = EVERY'[rtac hoare_assign, simp_tac ss,
|
|
71 |
TRY o (strip_tac THEN' atac)];
|
|
72 |
|
|
73 |
fun hoare_tac ss =
|
|
74 |
REPEAT(STATE(fn th => FIRST'[rtac hoare_seq, assign_tac ss] (nprems_of th)));
|
|
75 |
|
|
76 |
(* example *)
|
|
77 |
val prems = goal Hoare.thy
|
|
78 |
"[| u ~= y; u ~= z; y ~= z |] ==> \
|
|
79 |
\ {{%s.s(x)=i & s(y)=j}} \
|
|
80 |
\ z := X x; (u := N 0; \
|
|
81 |
\ while noti(ROp op = (X u) (X y)) \
|
|
82 |
\ do (u := Op1 Suc (X u); z := Op1 Suc (X z))) \
|
|
83 |
\ {{%s. s(z)=i+j}}";
|
|
84 |
val ss = arith_ss addsimps (eq_sym_conv::assign_def::prems@A_simps@B_simps);
|
|
85 |
by(hoare_tac ss);
|
|
86 |
by(while_tac "%s.s z = i + s u & s y = j" ss 3);
|
|
87 |
by(hoare_tac ss);
|
|
88 |
result();
|