Added a verified verification-condition generator.
authornipkow
Tue, 23 Jan 1996 10:59:35 +0100
changeset 1447 bc2c0acbbf29
parent 1446 a8387e934fa7
child 1448 77379ae9ff0d
Added a verified verification-condition generator.
src/HOL/IMP/Hoare.ML
src/HOL/IMP/Hoare.thy
src/HOL/IMP/README.html
src/HOL/IMP/ROOT.ML
src/HOL/IMP/VC.ML
src/HOL/IMP/VC.thy
--- a/src/HOL/IMP/Hoare.ML	Sat Jan 20 02:00:11 1996 +0100
+++ b/src/HOL/IMP/Hoare.ML	Tue Jan 23 10:59:35 1996 +0100
@@ -3,55 +3,28 @@
     Author: 	Tobias Nipkow
     Copyright   1995 TUM
 
-Derivation of Hoare rules
+Soundness of Hoare rules wrt denotational semantics
 *)
 
 open Hoare;
 
-Unify.trace_bound := 30;
-Unify.search_bound := 30;
-
-goalw Hoare.thy [spec_def]
-  "!!P.[| !s. P' s --> P s; {{P}}c{{Q}}; !s. Q s --> Q' s |] \
-\  ==> {{P'}}c{{Q'}}";
-by(fast_tac HOL_cs 1);
-bind_thm("hoare_conseq", impI RSN (3,allI RSN (3,impI RS allI RS result())));
-
-goalw Hoare.thy (spec_def::C_simps)  "{{P}} skip {{P}}";
-by(fast_tac comp_cs 1);
-qed"hoare_skip";
-
-goalw Hoare.thy (spec_def::C_simps)
-  "!!P. [| !s. P s --> Q(s[A a s/x]) |] ==> {{P}} x := a {{Q}}";
-by(Asm_full_simp_tac 1);
-qed"hoare_assign";
-
-goalw Hoare.thy (spec_def::C_simps)
-  "!!P. [| {{P}} c {{Q}}; {{Q}} d {{R}} |] ==> {{P}} c;d {{R}}";
-by(fast_tac comp_cs 1);
-qed"hoare_seq";
-
-goalw Hoare.thy (spec_def::C_simps)
-  "!!P. [| {{%s. P s & B b s}} c {{Q}}; {{%s. P s & ~B b s}} d {{Q}} |] ==> \
-\  {{P}} ifc b then c else d {{Q}}";
-by(Simp_tac 1);
-by(fast_tac comp_cs 1);
-qed"hoare_if";
-
-goalw Hoare.thy (spec_def::C_simps)
-  "!!P. [| {{%s. P s & B b s}} c {{P}} |] ==> \
-\  {{P}} while b do c {{%s. P s & ~B b s}}";
+goalw Hoare.thy [spec_def] "!P c Q. ({{P}}c{{Q}}) --> spec P c Q";
+br hoare.mutual_induct 1;
+    by(ALLGOALS Asm_simp_tac);
+  by(fast_tac rel_cs 1);
+ by(fast_tac HOL_cs 1);
 br allI 1;
 br allI 1;
 br impI 1;
 be induct2 1;
-br Gamma_mono 1;
+ br Gamma_mono 1;
 by (rewrite_goals_tac [Gamma_def]);  
 by(eres_inst_tac [("x","a")] allE 1);
 by (safe_tac comp_cs);
-by(ALLGOALS Asm_full_simp_tac);
-qed"hoare_while";
+  by(ALLGOALS Asm_full_simp_tac);
+qed "hoare_sound";
 
+(*
 fun while_tac inv ss i =
   EVERY[res_inst_tac[("P",inv)] hoare_conseq i, atac i, rtac hoare_while i,
         asm_full_simp_tac ss (i+1)];
@@ -75,3 +48,4 @@
 by(while_tac "%s.s z = i + s u & s y = j" ss 3);
 by(hoare_tac ss);
 result();
+*)
--- a/src/HOL/IMP/Hoare.thy	Sat Jan 20 02:00:11 1996 +0100
+++ b/src/HOL/IMP/Hoare.thy	Tue Jan 23 10:59:35 1996 +0100
@@ -3,47 +3,32 @@
     Author: 	Tobias Nipkow
     Copyright   1995 TUM
 
-Semantic embedding of Hoare logic
+Inductive definition of Hoare logic
 *)
 
 Hoare = Denotation +
+
+types assn = state => bool
+
 consts
+  hoare :: "(assn * com * assn) set"
   spec :: [state=>bool,com,state=>bool] => bool
-(* syntax "@spec" :: [bool,com,bool] => bool *)
-          ("{{(1_)}}/ (_)/ {{(1_)}}" 10)
 defs
   spec_def "spec P c Q == !s t. (s,t) : C(c) --> P s --> Q t"
-end
-(* Pretty-printing of assertions.
-   Not very helpful as long as programs are not pretty-printed.
-ML
 
-local open Syntax
-
-fun is_loc a = let val ch = hd(explode a)
-               in ord "A" <= ord ch andalso ord ch <= ord "Z" end;
-
-fun tr(s$t,i) = tr(s,i)$tr(t,i)
-  | tr(Abs(x,T,u),i) = Abs(x,T,tr(u,i+1))
-  | tr(t as Free(a,T),i) = if is_loc a then Bound(i) $ free(a) else t
-  | tr(t,_) = t;
+syntax "@hoare" :: [bool,com,bool] => bool ("{{(1_)}}/ (_)/ {{(1_)}}" 10)
+translations "{{P}}c{{Q}}" == "(P,c,Q) : hoare"
 
-fun cond_tr(p) = Abs("",dummyT,tr(p,0))
-
-fun spec_tr[p,c,q] = const"spec" $ cond_tr p $ c $ cond_tr q;
-
-fun tr'(t as (Bound j $ (u as Free(a,_))),i) = if i=j then u else t
-  | tr'(s$t,i) = tr'(s,i)$tr'(t,i)
-  | tr'(Abs(x,T,u),i) = Abs(x,T,tr'(u,i+1))
-  | tr'(t,_) = t;
-
-fun spec_tr'[Abs(_,_,p),c,Abs(_,_,q)] =
-  const"@spec" $ tr'(p,0) $ c $ tr'(q,0);
-
-in
-
-val parse_translation = [("@spec", spec_tr)];
-val print_translation = [("spec", spec_tr')];
+inductive "hoare"
+intrs
+  hoare_skip "{{P}}skip{{P}}"
+  hoare_ass  "{{%s.P(s[A a s/x])}} x:=a {{P}}"
+  hoare_semi "[| {{P}}c{{Q}}; {{Q}}d{{R}} |] ==> {{P}} c;d {{R}}"
+  hoare_if   "[| {{%s. P s & B b s}}c{{Q}}; {{%s. P s & ~B b s}}d{{Q}} |] ==>
+              {{P}} ifc b then c else d {{Q}}"
+  hoare_while "[| {{%s. P s & B b s}} c {{P}} |] ==>
+	       {{P}} while b do c {{%s. P s & ~B b s}}"
+  hoare_conseq "[| !s. P' s --> P s; {{P}}c{{Q}}; !s. Q s --> Q' s |] ==>
+		{{P'}}c{{Q'}}"
 
 end
-*)
--- a/src/HOL/IMP/README.html	Sat Jan 20 02:00:11 1996 +0100
+++ b/src/HOL/IMP/README.html	Tue Jan 23 10:59:35 1996 +0100
@@ -1,20 +1,21 @@
 <HTML><HEAD><TITLE>HOL/IMP/ReadMe</TITLE></HEAD><BODY>
 
-<H2>IMP --- A <KBD>while</KBD>-Language and its 3 Semantics</H2>
+<H2>IMP --- A <KBD>while</KBD>-language and its 3 Semantics</H2>
 
 The formalization of the denotational, operational and axiomatic semantics of
 a simple while-language, including
 <UL>
 <LI> an equivalence proof between denotational and operational semantics and
-<LI> the derivation of the Hoare rules from the denotational semantics.
+<LI> a soundness proof of the Hoare rules w.r.t. the denotational semantics.
 </UL>
 The whole development essentially formalizes/transcribes chapters 2, 5 and 6 of
 <P>
 <KBD>
-@book{Winskel,author={Glynn Winskel},
-title={The Formal Semantics of Programming Languages},
-publisher={MIT Press},year=1993}
+@book{Winskel, author = {Glynn Winskel},
+title = {The Formal Semantics of Programming Languages},
+publisher = {MIT Press}, year = 1993}
 </KBD>
 <P>
-Here is the documentation.
+In addition, a verification-condition-generator is proved sound and complete
+w.r.t. the Hoare rules.
 </BODY></HTML>
--- a/src/HOL/IMP/ROOT.ML	Sat Jan 20 02:00:11 1996 +0100
+++ b/src/HOL/IMP/ROOT.ML	Tue Jan 23 10:59:35 1996 +0100
@@ -10,4 +10,4 @@
 proof_timing := true;
 time_use_thy "Properties";
 time_use_thy "Equiv";
-time_use_thy "Hoare";
+time_use_thy "VC";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/IMP/VC.ML	Tue Jan 23 10:59:35 1996 +0100
@@ -0,0 +1,79 @@
+(*  Title: 	HOL/IMP/VC.ML
+    ID:         $Id$
+    Author: 	Tobias Nipkow
+    Copyright   1996 TUM
+
+Soundness and completeness of vc
+*)
+
+open VC;
+
+val lemma = prove_goal HOL.thy "!s.P s --> P s" (K[fast_tac HOL_cs 1]);
+
+goal VC.thy "!Q. (!s. vc c Q s) --> ({{wp c Q}} (astrip c) {{Q}})";
+by(acom.induct_tac "c" 1);
+    by(ALLGOALS Simp_tac);
+    by(fast_tac (HOL_cs addIs hoare.intrs) 1);
+   by(fast_tac (HOL_cs addIs hoare.intrs) 1);
+  by(fast_tac (HOL_cs addIs hoare.intrs) 1);
+ (* if *)
+ br allI 1;
+ br impI 1;
+ brs hoare.intrs 1;
+  brs hoare.intrs 1;
+    by(fast_tac HOL_cs 2);
+   by(fast_tac HOL_cs 1);
+  by(fast_tac HOL_cs 1);
+ brs hoare.intrs 1;
+   by(fast_tac HOL_cs 2);
+  by(fast_tac HOL_cs 1);
+ by(fast_tac HOL_cs 1);
+(* while *)
+by(safe_tac HOL_cs);
+brs hoare.intrs 1;
+  br lemma 1;
+ brs hoare.intrs 1;
+ brs hoare.intrs 1;
+   by(fast_tac HOL_cs 2);
+  by(ALLGOALS(fast_tac HOL_cs));
+qed "vc_sound";
+
+goal VC.thy "!P Q. (!s. P s --> Q s) --> (!s. wp c P s --> wp c Q s)";
+by(acom.induct_tac "c" 1);
+    by(ALLGOALS Asm_simp_tac);
+by(EVERY1[rtac allI, rtac allI, rtac impI]);
+by(EVERY1[etac allE, etac allE, etac mp]);
+by(EVERY1[etac allE, etac allE, etac mp, atac]);
+bind_thm("wp_mono", result() RS spec RS spec RS mp RS spec RS mp);
+
+goal VC.thy "!P Q. (!s. P s --> Q s) --> (!s. vc c P s --> vc c Q s)";
+by(acom.induct_tac "c" 1);
+    by(ALLGOALS Asm_simp_tac);
+by(safe_tac HOL_cs);
+by(EVERY[etac allE 1,etac allE 1,etac impE 1,etac allE 2,etac mp 2,atac 2]);
+by(fast_tac (HOL_cs addEs [wp_mono]) 1);
+bind_thm("vc_mono", result() RS spec RS spec RS mp RS spec RS mp);
+
+goal VC.thy
+  "!P c Q. ({{P}}c{{Q}}) --> \
+\          (? ac. astrip ac = c & (!s. P s --> wp ac Q s) & (!s. vc ac Q s))";
+br hoare.mutual_induct 1;
+     by(res_inst_tac [("x","Askip")] exI 1);
+     by(Simp_tac 1);
+    by(res_inst_tac [("x","Aass x a")] exI 1);
+    by(Simp_tac 1);
+   by(SELECT_GOAL(safe_tac HOL_cs)1);
+   by(res_inst_tac [("x","Asemi ac aca")] exI 1);
+   by(Asm_simp_tac 1);
+   by(fast_tac (HOL_cs addSEs [wp_mono,vc_mono]) 1);
+  by(SELECT_GOAL(safe_tac HOL_cs)1);
+  by(res_inst_tac [("x","Aif b ac aca")] exI 1);
+  by(Asm_simp_tac 1);
+ by(SELECT_GOAL(safe_tac HOL_cs)1);
+ by(res_inst_tac [("x","Awhile b P ac")] exI 1);
+ by(Asm_simp_tac 1);
+by(SELECT_GOAL(safe_tac HOL_cs)1);
+by(res_inst_tac [("x","ac")] exI 1);
+by(Asm_simp_tac 1);
+by(fast_tac (HOL_cs addSEs [wp_mono,vc_mono]) 1);
+qed "vc_complete";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/IMP/VC.thy	Tue Jan 23 10:59:35 1996 +0100
@@ -0,0 +1,45 @@
+(*  Title: 	HOL/IMP/VC.thy
+    ID:         $Id$
+    Author: 	Tobias Nipkow
+    Copyright   1996 TUM
+
+acom: annotated commands
+vc:   verification-conditions
+wp:   weakest (liberal) precondition
+*)
+
+VC  =  Hoare +
+
+datatype  acom = Askip
+               | Aass   loc aexp
+               | Asemi  acom acom
+               | Aif    bexp acom acom
+               | Awhile bexp assn acom
+
+consts
+  vc,wp :: acom => assn => assn
+  astrip :: acom => com
+
+primrec wp acom
+  wp_Askip  "wp Askip Q = Q"
+  wp_Aass   "wp (Aass x a) Q = (%s.Q(s[A a s/x]))"
+  wp_Asemi  "wp (Asemi c d) Q = wp c (wp d Q)"
+  wp_Aif    "wp (Aif b c d) Q = (%s. (B b s-->wp c Q s)&(~B b s-->wp d Q s))" 
+  wp_Awhile "wp (Awhile b I c) Q = I"
+
+primrec vc acom
+  vc_Askip  "vc Askip Q = (%s.True)"
+  vc_Aass   "vc (Aass x a) Q = (%s.True)"
+  vc_Asemi  "vc (Asemi c d) Q = (%s. vc c (wp d Q) s & vc d Q s)"
+  vc_Aif    "vc (Aif b c d) Q = (%s. vc c Q s & vc d Q s)" 
+  vc_Awhile "vc (Awhile b I c) Q = (%s. (I s & ~B b s --> Q s) &
+                              (I s & B b s --> wp c I s) & vc c I s)"
+
+primrec astrip acom
+  astrip_Askip  "astrip Askip = skip"
+  astrip_Aass   "astrip (Aass x a) = (x:=a)"
+  astrip_Asemi  "astrip (Asemi c d) = (astrip c;astrip d)"
+  astrip_Aif    "astrip (Aif b c d) = ifC b (astrip c) (astrip d)"
+  astrip_Awhile "astrip (Awhile b I c) = whileC b (astrip c)"
+  
+end