text\<open>
First of all we provide a store of program variables that occur in any of
the programs considered later. Slightly unexpected things may happen when
attempting to work with undeclared variables. \<close>
record vars =
I :: nat
M :: nat
N :: nat
S :: nat
text\<open>
While all of our variables happen tohave the same type, nothing would
prevent us from working with many-sorted programs as well, or even
polymorphic ones. Alsonote that Isabelle/HOL's extensible record types even
provides simple means to extend the state space later. \<close>
subsection \<open>Basic examples\<close>
text\<open>
We look at few trivialities involving assignment and sequential composition, in order to get an idea of how to work with our formulation of Hoare Logic.
\<^medskip> Using the basic \<open>assign\<close> rule directly is a bit cumbersome. \<close>
text\<open>
Certainly we want the state modification already done, e.g.\ by
simplification. The \<open>hoare\<close> method performs the basic state update for us;
we may apply the Simplifier afterwards to achieve ``obvious'' consequences
as well. \<close>
lemma"\ \\N + 1 = a + 1\ \N := \N + 1 \\N = a + 1\" by hoare
lemma"\ \\N = a\ \N := \N + 1 \\N = a + 1\" by hoare simp
lemma"\ \a = a \ b = b\ \M := a; \N := b \\M = a \ \N = b\" by hoare
lemma"\ \True\ \M := a; \N := b \\M = a \ \N = b\" by hoare
lemma "\ \\M = a \ \N = b\ \<acute>I := \<acute>M; \<acute>M := \<acute>N; \<acute>N := \<acute>I \<lbrace>\<acute>M = b \<and> \<acute>N = a\<rbrace>" by hoare simp
text\<open>
It is important tonote that statements like the following one can only be
proven for each individual program variable. Due to the extra-logical nature
of record fields, we cannot formulate a theorem relating record selectors and updates schematically. \<close>
lemma"\ \\N = a\ \N := \N \\N = a\" by hoare
lemma"\ \\x = a\ \x := \x \\x = a\" oops
lemma "Valid {s. x s = a} (Basic (\s. x_update (x s) s)) {s. x s = n}" \<comment> \<open>same statement without concrete syntax\<close> oops
text\<open> In the following assignments we make use of the consequence rule in order to
achieve the intended precondition. Certainly, the \<open>hoare\<close> method is able to
handle this case, too. \<close>
subsection \<open>Multiplication by addition\<close>
text\<open>
We now do some basic examples of actual \<^verbatim>\<open>WHILE\<close> programs. This one is a
loop for calculating the product of two natural numbers, by iterated
addition. We first give detailed structured proof based on single-step Hoare
rules. \<close>
lemma "\ \\M = 0 \ \S = 0\
WHILE \<acute>M \<noteq> a
DO \<acute>S := \<acute>S + b; \<acute>M := \<acute>M + 1 OD \<lbrace>\<acute>S = a * b\<rbrace>" proof - let"\ _ ?while _" = ?thesis let"\\?inv\" = "\\S = \M * b\"
have"\\M = 0 \ \S = 0\ \ \\?inv\" by auto alsohave"\ \ ?while \\?inv \ \ (\M \ a)\" proof let ?c = "\S := \S + b; \M := \M + 1" have"\\?inv \ \M \ a\ \ \\S + b = (\M + 1) * b\" by auto alsohave"\ \ ?c \\?inv\" by hoare finallyshow"\ \\?inv \ \M \ a\ ?c \\?inv\" . qed alsohave"\ \ \\S = a * b\" by auto finallyshow ?thesis . qed
text\<open>
The subsequent version of the proof applies the \<open>hoare\<close> method to reduce the
Hoare statement to a purely logical problem that can be solved fully
automatically. Note that we haveto specify the \<^verbatim>\<open>WHILE\<close> loop invariant in
the original statement. \<close>
lemma "\ \\M = 0 \ \S = 0\
WHILE \<acute>M \<noteq> a
INV \<lbrace>\<acute>S = \<acute>M * b\<rbrace>
DO \<acute>S := \<acute>S + b; \<acute>M := \<acute>M + 1 OD \<lbrace>\<acute>S = a * b\<rbrace>" by hoare auto
subsection \<open>Summing natural numbers\<close>
text\<open>
We verify an imperative program to sum natural numbers up to a given limit.
First some functional definitionfor proper specification of the problem.
\<^medskip>
The following proofis quite explicit in the individual steps taken, with
the \<open>hoare\<close> method only applied locally to take care of assignment and
sequential composition. Note that we express intermediate proof obligation in pure logic, without referring to the state space. \<close>
theorem "\ \True\ \<acute>S := 0; \<acute>I := 1;
WHILE \<acute>I \<noteq> n
DO \<acute>S := \<acute>S + \<acute>I; \<acute>I := \<acute>I + 1
OD \<lbrace>\<acute>S = (\<Sum>j<n. j)\<rbrace>"
(is"\ _ (_; ?while) _") proof - let ?sum = "\k::nat. \j let ?inv = "\s i::nat. s = ?sum i"
have"\ \True\ \S := 0; \I := 1 \?inv \S \I\" proof - have"True \ 0 = ?sum 1" by simp alsohave"\ \\\ \S := 0; \I := 1 \?inv \S \I\" by hoare finallyshow ?thesis . qed alsohave"\ \ ?while \?inv \S \I \ \ \I \ n\" proof let ?body = "\S := \S + \I; \I := \I + 1" have"?inv s i \ i \ n \ ?inv (s + i) (i + 1)" for s i by simp alsohave"\ \\S + \I = ?sum (\I + 1)\ ?body \?inv \S \I\" by hoare finallyshow"\ \?inv \S \I \ \I \ n\ ?body \?inv \S \I\" . qed alsohave"s = ?sum i \ \ i \ n \ s = ?sum n" for s i by simp finallyshow ?thesis . qed
text\<open>
The next version uses the \<open>hoare\<close> method, while still explaining the
resulting proof obligations in an abstract, structured manner. \<close>
theorem "\ \True\ \<acute>S := 0; \<acute>I := 1;
WHILE \<acute>I \<noteq> n
INV \<lbrace>\<acute>S = (\<Sum>j<\<acute>I. j)\<rbrace>
DO \<acute>S := \<acute>S + \<acute>I; \<acute>I := \<acute>I + 1
OD \<lbrace>\<acute>S = (\<Sum>j<n. j)\<rbrace>" proof - let ?sum = "\k::nat. \j let ?inv = "\s i::nat. s = ?sum i" show ?thesis proof hoare show"?inv 0 1"by simp show"?inv (s + i) (i + 1)"if"?inv s i \ i \ n" for s i using that by simp show"s = ?sum n"if"?inv s i \ \ i \ n" for s i using that by simp qed qed
text\<open>
Certainly, this proof may be done fully automatic as well, provided that the
invariant is given beforehand. \<close>
theorem "\ \True\ \<acute>S := 0; \<acute>I := 1;
WHILE \<acute>I \<noteq> n
INV \<lbrace>\<acute>S = (\<Sum>j<\<acute>I. j)\<rbrace>
DO \<acute>S := \<acute>S + \<acute>I; \<acute>I := \<acute>I + 1
OD \<lbrace>\<acute>S = (\<Sum>j<n. j)\<rbrace>" by hoare auto
subsection \<open>Time\<close>
text\<open>
A simple embedding of time in Hoare logic: function\<open>timeit\<close> inserts an
extra variable to keep track of the elapsed time. \<close>
record tstate = time :: nat
type_synonym'a time = "\time :: nat, \ :: 'a\"
primrec timeit :: "'a time com \ 'a time com" where "timeit (Basic f) = (Basic f; Basic(\s. s\time := Suc (time s)\))"
| "timeit (c1; c2) = (timeit c1; timeit c2)"
| "timeit (Cond b c1 c2) = Cond b (timeit c1) (timeit c2)"
| "timeit (While b iv v c) = While b iv v (timeit c)"
record tvars = tstate +
I :: nat
J :: nat
lemma lem: "(0::nat) < n \ n + n \ Suc (n * n)" by (induct n) simp_all
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.