src/HOL/Hoare/Examples.thy
author wenzelm
Wed, 23 Dec 2020 22:25:22 +0100
changeset 72990 db8f94656024
parent 67613 ce654b0e6d69
permissions -rw-r--r--
tuned document, notably authors and sections;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1476
608483c2122a expanded tabs; incorporated Konrad's changes
clasohm
parents: 1374
diff changeset
     1
(*  Title:      HOL/Hoare/Examples.thy
608483c2122a expanded tabs; incorporated Konrad's changes
clasohm
parents: 1374
diff changeset
     2
    Author:     Norbert Galm
5646
7c2ddbaf8b8c New many-sorted version.
nipkow
parents: 1625
diff changeset
     3
    Copyright   1998 TUM
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
     4
*)
1335
5e1c0540f285 New directory.
nipkow
parents:
diff changeset
     5
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
     6
section \<open>Various examples\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
     7
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
     8
theory Examples
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
     9
  imports Hoare_Logic Arith2
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
    10
begin
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    11
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
    12
subsection \<open>Arithmetic\<close>
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
    13
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
    14
subsubsection \<open>Multiplication by successive addition\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    15
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
    16
lemma multiply_by_add: "VARS m s a b
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    17
  {a=A \<and> b=B}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    18
  m := 0; s := 0;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    19
  WHILE m\<noteq>a
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    20
  INV {s=m*b \<and> a=A \<and> b=B}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    21
  DO s := s+b; m := m+(1::nat) OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    22
  {s = A*B}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    23
by vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    24
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    25
lemma multiply_by_add_time: "VARS m s a b t
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    26
  {a=A \<and> b=B \<and> t=0}
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    27
  m := 0; t := t+1; s := 0; t := t+1;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    28
  WHILE m\<noteq>a
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    29
  INV {s=m*b \<and> a=A \<and> b=B \<and> t = 2*m + 2}
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    30
  DO s := s+b; t := t+1; m := m+(1::nat); t := t+1 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    31
  {s = A*B \<and> t = 2*A + 2}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    32
by vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    33
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    34
lemma multiply_by_add2: "VARS M N P :: int
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    35
 {m=M \<and> n=N}
13789
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    36
 IF M < 0 THEN M := -M; N := -N ELSE SKIP FI;
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    37
 P := 0;
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    38
 WHILE 0 < M
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    39
 INV {0 \<le> M \<and> (\<exists>p. p = (if m<0 then -m else m) & p*N = m*n & P = (p-M)*N)}
13789
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    40
 DO P := P+N; M := M - 1 OD
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    41
 {P = m*n}"
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    42
apply vcg_simp
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    43
 apply (auto simp add:int_distrib)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    44
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    45
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    46
lemma multiply_by_add2_time: "VARS M N P t :: int
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    47
 {m=M \<and> n=N \<and> t=0}
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    48
 IF M < 0 THEN M := -M; t := t+1; N := -N; t := t+1 ELSE SKIP FI;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    49
 P := 0; t := t+1;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    50
 WHILE 0 < M
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
    51
 INV {0 \<le> M & (\<exists>p. p = (if m<0 then -m else m) & p*N = m*n & P = (p-M)*N & t \<ge> 0 & t \<le> 2*(p-M)+3)}
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    52
 DO P := P+N; t := t+1; M := M - 1; t := t+1 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    53
 {P = m*n & t \<le> 2*abs m + 3}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    54
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    55
 apply (auto simp add:int_distrib)
13789
d37f66755f47 New example
nipkow
parents: 13737
diff changeset
    56
done
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    57
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    58
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
    59
subsubsection \<open>Euclid's algorithm for GCD\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    60
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
    61
lemma Euclid_GCD: "VARS a b
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    62
 {0<A & 0<B}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    63
 a := A; b := B;
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents: 13789
diff changeset
    64
 WHILE  a \<noteq> b
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    65
 INV {0<a & 0<b & gcd A B = gcd a b}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    66
 DO IF a<b THEN b := b-a ELSE a := a-b FI OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    67
 {a = gcd A B}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    68
apply vcg
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    69
  \<comment> \<open>Now prove the verification conditions\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    70
  apply auto
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    71
  apply(simp add: gcd_diff_r less_imp_le)
16796
140f1e0ea846 generlization of some "nat" theorems
paulson
parents: 16733
diff changeset
    72
 apply(simp add: linorder_not_less gcd_diff_l)
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    73
apply(erule gcd_nnn)
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    74
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
    75
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    76
lemma Euclid_GCD_time: "VARS a b t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    77
 {0<A & 0<B & t=0}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    78
 a := A; t := t+1; b := B; t := t+1; 
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    79
 WHILE  a \<noteq> b
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    80
 INV {0<a & 0<b & gcd A B = gcd a b & a\<le>A & b\<le>B & t \<le> max A B - max a b + 2}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    81
 DO IF a<b THEN b := b-a; t := t+1 ELSE a := a-b; t := t+1 FI OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    82
 {a = gcd A B & t \<le> max A B + 2}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    83
apply vcg
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    84
  \<comment> \<open>Now prove the verification conditions\<close>
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    85
  apply auto
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    86
  apply(simp add: gcd_diff_r less_imp_le)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    87
 apply(simp add: linorder_not_less gcd_diff_l)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    88
apply(erule gcd_nnn)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    89
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
    90
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    91
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
    92
subsubsection \<open>Dijkstra's extension of Euclid's algorithm for simultaneous GCD and SCM\<close>
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    93
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    94
text \<open>
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    95
  From E.W. Disjkstra. Selected Writings on Computing, p 98 (EWD474),
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    96
  where it is given without the invariant. Instead of defining \<open>scm\<close>
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    97
  explicitly we have used the theorem \<open>scm x y = x * y / gcd x y\<close> and avoided
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    98
  division by mupltiplying with \<open>gcd x y\<close>.
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
    99
\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   100
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   101
lemmas distribs =
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   102
  diff_mult_distrib diff_mult_distrib2 add_mult_distrib add_mult_distrib2
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   103
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   104
lemma gcd_scm: "VARS a b x y
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   105
 {0<A & 0<B & a=A & b=B & x=B & y=A}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   106
 WHILE  a ~= b
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   107
 INV {0<a & 0<b & gcd A B = gcd a b & 2*A*B = a*x + b*y}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   108
 DO IF a<b THEN (b := b-a; x := x+y) ELSE (a := a-b; y := y+x) FI OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   109
 {a = gcd A B & 2*A*B = a*(x+y)}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   110
apply vcg
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   111
  apply simp
16796
140f1e0ea846 generlization of some "nat" theorems
paulson
parents: 16733
diff changeset
   112
 apply(simp add: distribs gcd_diff_r linorder_not_less gcd_diff_l)
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   113
apply(simp add: distribs gcd_nnn)
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   114
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   115
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   116
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
   117
subsubsection \<open>Power by iterated squaring and multiplication\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   118
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   119
lemma power_by_mult: "VARS a b c
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   120
 {a=A & b=B}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   121
 c := (1::nat);
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   122
 WHILE b ~= 0
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   123
 INV {A^B = c * a^b}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   124
 DO  WHILE b mod 2 = 0
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   125
     INV {A^B = c * a^b}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   126
     DO  a := a*a; b := b div 2 OD;
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   127
     c := c*a; b := b - 1
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   128
 OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   129
 {c = A^B}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   130
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   131
apply(case_tac "b")
42154
478bdcea240a tuned proofs;
wenzelm
parents: 35316
diff changeset
   132
 apply simp
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   133
apply simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   134
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   135
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   136
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
   137
subsubsection \<open>Factorial\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   138
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   139
lemma factorial: "VARS a b
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   140
 {a=A}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   141
 b := 1;
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   142
 WHILE a > 0
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   143
 INV {fac A = b * fac a}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   144
 DO b := b*a; a := a - 1 OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   145
 {b = fac A}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   146
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   147
apply(clarsimp split: nat_diff_split)
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   148
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   149
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   150
lemma factorial_time: "VARS a b t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   151
 {a=A & t=0}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   152
 b := 1; t := t+1;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   153
 WHILE a > 0
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   154
 INV {fac A = b * fac a & a \<le> A & t = 2*(A-a)+1}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   155
 DO b := b*a; t := t+1; a := a - 1; t := t+1 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   156
 {b = fac A & t = 2*A + 1}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   157
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   158
apply(clarsimp split: nat_diff_split)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   159
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   160
13684
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   161
lemma [simp]: "1 \<le> i \<Longrightarrow> fac (i - Suc 0) * i = fac i"
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   162
by(induct i, simp_all)
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   163
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   164
lemma factorial2: "VARS i f
13684
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   165
 {True}
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   166
 i := (1::nat); f := 1;
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   167
 WHILE i <= n INV {f = fac(i - 1) & 1 <= i & i <= n+1}
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   168
 DO f := f*i; i := i+1 OD
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   169
 {f = fac n}"
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   170
apply vcg_simp
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   171
apply(subgoal_tac "i = Suc n")
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   172
apply simp
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   173
apply arith
48bfc2cc0938 moved fac example
nipkow
parents: 13682
diff changeset
   174
done
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   175
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   176
lemma factorial2_time: "VARS i f t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   177
 {t=0}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   178
 i := (1::nat); t := t+1; f := 1; t := t+1;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   179
 WHILE i \<le> n INV {f = fac(i - 1) & 1 \<le> i & i \<le> n+1 & t = 2*(i-1)+2}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   180
 DO f := f*i; t := t+1; i := i+1; t := t+1 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   181
 {f = fac n & t = 2*n+2}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   182
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   183
 apply auto
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   184
apply(subgoal_tac "i = Suc n")
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   185
 apply simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   186
apply arith
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   187
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   188
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   189
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
   190
subsubsection \<open>Square root\<close>
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   191
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   192
\<comment> \<open>the easy way:\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   193
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   194
lemma sqrt: "VARS r x
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   195
 {True}
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   196
 r := (0::nat);
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   197
 WHILE (r+1)*(r+1) <= X
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   198
 INV {r*r \<le> X}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   199
 DO r := r+1 OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   200
 {r*r <= X & X < (r+1)*(r+1)}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   201
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   202
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   203
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   204
lemma sqrt_time: "VARS r t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   205
 {t=0}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   206
 r := (0::nat); t := t+1;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   207
 WHILE (r+1)*(r+1) <= X
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   208
 INV {r*r \<le> X & t = r+1}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   209
 DO r := r+1; t := t+1 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   210
 {r*r <= X & X < (r+1)*(r+1) & (t-1)*(t-1) \<le> X}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   211
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   212
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   213
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   214
\<comment> \<open>without multiplication\<close>
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   215
lemma sqrt_without_multiplication: "VARS u w r
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   216
 {x=X}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   217
 u := 1; w := 1; r := (0::nat);
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   218
 WHILE w <= X
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   219
 INV {u = r+r+1 & w = (r+1)*(r+1) & r*r <= X}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   220
 DO r := r + 1; w := w + u + 2; u := u + 2 OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   221
 {r*r <= X & X < (r+1)*(r+1)}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   222
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   223
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   224
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   225
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
   226
subsection \<open>Lists\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   227
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   228
lemma imperative_reverse: "VARS y x
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   229
 {x=X}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   230
 y:=[];
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   231
 WHILE x ~= []
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   232
 INV {rev(x)@y = rev(X)}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   233
 DO y := (hd x # y); x := tl x OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   234
 {y=rev(X)}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   235
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   236
 apply(simp add: neq_Nil_conv)
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   237
 apply auto
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   238
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   239
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   240
lemma imperative_reverse_time: "VARS y x t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   241
 {x=X & t=0}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   242
 y:=[]; t := t+1;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   243
 WHILE x ~= []
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   244
 INV {rev(x)@y = rev(X) & t = 2*(length y) + 1}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   245
 DO y := (hd x # y); t := t+1; x := tl x; t := t+1 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   246
 {y=rev(X) & t = 2*length X + 1}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   247
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   248
 apply(simp add: neq_Nil_conv)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   249
 apply auto
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   250
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   251
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   252
lemma imperative_append: "VARS x y
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   253
 {x=X & y=Y}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   254
 x := rev(x);
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   255
 WHILE x~=[]
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   256
 INV {rev(x)@y = X@Y}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   257
 DO y := (hd x # y);
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   258
    x := tl x
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   259
 OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   260
 {y = X@Y}"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   261
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   262
apply(simp add: neq_Nil_conv)
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   263
apply auto
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   264
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   265
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   266
lemma imperative_append_time_no_rev: "VARS x y t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   267
 {x=X & y=Y}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   268
 x := rev(x); t := 0;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   269
 WHILE x~=[]
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   270
 INV {rev(x)@y = X@Y & length x \<le> length X & t = 2 * (length X - length x)}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   271
 DO y := (hd x # y); t := t+1;
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   272
    x := tl x; t := t+1
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   273
 OD
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   274
 {y = X@Y & t = 2 * length X}"
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   275
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   276
apply(simp add: neq_Nil_conv)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   277
apply auto
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   278
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   279
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   280
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
   281
subsection \<open>Arrays\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   282
72990
db8f94656024 tuned document, notably authors and sections;
wenzelm
parents: 67613
diff changeset
   283
subsubsection \<open>Search for a key\<close>
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   284
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   285
lemma zero_search: "VARS A i
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   286
 {True}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   287
 i := 0;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   288
 WHILE i < length A & A!i \<noteq> key
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   289
 INV {\<forall>j. j<i --> A!j \<noteq> key}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   290
 DO i := i+1 OD
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   291
 {(i < length A --> A!i = key) &
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   292
  (i = length A --> (\<forall>j. j < length A \<longrightarrow> A!j \<noteq> key))}"
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   293
apply vcg_simp
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   294
apply(blast elim!: less_SucE)
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   295
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   296
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   297
lemma zero_search_time: "VARS A i t
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   298
 {t=0}
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   299
 i := 0; t := t+1;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   300
 WHILE i < length A \<and> A!i \<noteq> key
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   301
 INV {(\<forall>j. j<i \<longrightarrow> A!j \<noteq> key) \<and> i \<le> length A \<and> t = i+1}
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   302
 DO i := i+1; t := t+1 OD
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   303
 {(i < length A \<longrightarrow> A!i = key) \<and>
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   304
  (i = length A \<longrightarrow> (\<forall>j. j < length A --> A!j \<noteq> key)) \<and> t \<le> length A + 1}"
63106
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   305
apply vcg_simp
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   306
apply(blast elim!: less_SucE)
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   307
done
412140038d3c added timing lemmas
nipkow
parents: 62390
diff changeset
   308
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   309
text \<open>
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   310
  The \<open>partition\<close> procedure for quicksort.
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   311
    \<^item> \<open>A\<close> is the array to be sorted (modelled as a list).
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   312
    \<^item> Elements of \<open>A\<close> must be of class order to infer at the end
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   313
      that the elements between u and l are equal to pivot.
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   314
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   315
  Ambiguity warnings of parser are due to \<open>:=\<close> being used
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   316
  both for assignment and list update.
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   317
\<close>
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   318
lemma lem: "m - Suc 0 < n ==> m < Suc n"
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   319
by arith
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   320
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   321
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   322
lemma Partition:
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   323
"[| leq == \<lambda>A i. \<forall>k. k<i \<longrightarrow> A!k \<le> pivot;
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   324
    geq == \<lambda>A i. \<forall>k. i<k \<and> k<length A \<longrightarrow> pivot \<le> A!k |] ==>
13737
e564c3d2d174 added a few lemmas
nipkow
parents: 13684
diff changeset
   325
 VARS A u l
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   326
 {0 < length(A::('a::order)list)}
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   327
 l := 0; u := length A - Suc 0;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   328
 WHILE l \<le> u
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   329
  INV {leq A l \<and> geq A u \<and> u<length A \<and> l\<le>length A}
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   330
  DO WHILE l < length A \<and> A!l \<le> pivot
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   331
     INV {leq A l & geq A u \<and> u<length A \<and> l\<le>length A}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   332
     DO l := l+1 OD;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   333
     WHILE 0 < u & pivot \<le> A!u
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   334
     INV {leq A l & geq A u  \<and> u<length A \<and> l\<le>length A}
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   335
     DO u := u - 1 OD;
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   336
     IF l \<le> u THEN A := A[l := A!u, u := A!l] ELSE SKIP FI
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   337
  OD
67613
ce654b0e6d69 more symbols;
wenzelm
parents: 67410
diff changeset
   338
 {leq A u & (\<forall>k. u<k \<and> k<l --> A!k = pivot) \<and> geq A l}"
67410
64d928bacddd prefer formal comments;
wenzelm
parents: 63106
diff changeset
   339
\<comment> \<open>expand and delete abbreviations first\<close>
58860
fee7cfa69c50 eliminated spurious semicolons;
wenzelm
parents: 42154
diff changeset
   340
apply (simp)
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   341
apply (erule thin_rl)+
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   342
apply vcg_simp
16733
236dfafbeb63 linear arithmetic now takes "&" in assumptions apart.
nipkow
parents: 16417
diff changeset
   343
   apply (force simp: neq_Nil_conv)
236dfafbeb63 linear arithmetic now takes "&" in assumptions apart.
nipkow
parents: 16417
diff changeset
   344
  apply (blast elim!: less_SucE intro: Suc_leI)
236dfafbeb63 linear arithmetic now takes "&" in assumptions apart.
nipkow
parents: 16417
diff changeset
   345
 apply (blast elim!: less_SucE intro: less_imp_diff_less dest: lem)
236dfafbeb63 linear arithmetic now takes "&" in assumptions apart.
nipkow
parents: 16417
diff changeset
   346
apply (force simp: nth_list_update)
13682
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   347
done
91674c8a008b conversion ML -> thy
nipkow
parents: 5646
diff changeset
   348
62390
842917225d56 more canonical names
nipkow
parents: 58860
diff changeset
   349
end