src/HOL/ex/InductiveInvariant_examples.thy
author krauss
Tue, 28 Sep 2010 09:54:07 +0200
changeset 39754 150f831ce4a3
parent 32960 69916a850301
permissions -rw-r--r--
no longer declare .psimps rules as [simp]. This regularly caused confusion (e.g., they show up in simp traces when the regular simp rules are disabled). In the few places where the rules are used, explicitly mentioning them actually clarifies the proof text.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32960
69916a850301 eliminated hard tabulators, guessing at each author's individual tab-width;
wenzelm
parents: 19769
diff changeset
     1
(*
69916a850301 eliminated hard tabulators, guessing at each author's individual tab-width;
wenzelm
parents: 19769
diff changeset
     2
    Author:     Sava Krsti\'{c} and John Matthews
17388
495c799df31d tuned headers etc.;
wenzelm
parents: 16417
diff changeset
     3
*)
15636
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
     4
17388
495c799df31d tuned headers etc.;
wenzelm
parents: 16417
diff changeset
     5
header {* Example use if an inductive invariant to solve termination conditions *}
495c799df31d tuned headers etc.;
wenzelm
parents: 16417
diff changeset
     6
495c799df31d tuned headers etc.;
wenzelm
parents: 16417
diff changeset
     7
theory InductiveInvariant_examples imports InductiveInvariant  begin
15636
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
     8
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
     9
text "A simple example showing how to use an inductive invariant
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    10
      to solve termination conditions generated by recdef on
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    11
      nested recursive function definitions."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    12
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    13
consts g :: "nat => nat"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    14
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    15
recdef (permissive) g "less_than"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    16
  "g 0 = 0"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    17
  "g (Suc n) = g (g n)"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    18
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    19
text "We can prove the unsolved termination condition for
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    20
      g by showing it is an inductive invariant."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    21
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    22
recdef_tc g_tc[simp]: g
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    23
apply (rule allI)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    24
apply (rule_tac x=n in tfl_indinv_wfrec [OF g_def])
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    25
apply (auto simp add: indinv_def split: nat.split)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    26
apply (frule_tac x=nat in spec)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    27
apply (drule_tac x="f nat" in spec)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    28
by auto
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    29
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    30
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    31
text "This declaration invokes Isabelle's simplifier to
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    32
      remove any termination conditions before adding
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    33
      g's rules to the simpset."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    34
declare g.simps [simplified, simp]
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    35
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    36
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    37
text "This is an example where the termination condition generated
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    38
      by recdef is not itself an inductive invariant."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    39
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    40
consts g' :: "nat => nat"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    41
recdef (permissive) g' "less_than"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    42
  "g' 0 = 0"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    43
  "g' (Suc n) = g' n + g' (g' n)"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    44
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    45
thm g'.simps
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    46
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    47
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    48
text "The strengthened inductive invariant is as follows
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    49
      (this invariant also works for the first example above):"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    50
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    51
lemma g'_inv: "g' n = 0"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    52
thm tfl_indinv_wfrec [OF g'_def]
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    53
apply (rule_tac x=n in tfl_indinv_wfrec [OF g'_def])
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    54
by (auto simp add: indinv_def split: nat.split)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    55
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    56
recdef_tc g'_tc[simp]: g'
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    57
by (simp add: g'_inv)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    58
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    59
text "Now we can remove the termination condition from
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    60
      the rules for g' ."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    61
thm g'.simps [simplified]
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    62
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    63
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    64
text {* Sometimes a recursive definition is partial, that is, it
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    65
        is only meant to be invoked on "good" inputs. As a contrived
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    66
        example, we will define a new version of g that is only
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    67
        well defined for even inputs greater than zero. *}
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    68
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    69
consts g_even :: "nat => nat"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    70
recdef (permissive) g_even "less_than"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    71
  "g_even (Suc (Suc 0)) = 3"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    72
  "g_even n = g_even (g_even (n - 2) - 1)"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    73
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    74
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    75
text "We can prove a conditional version of the unsolved termination
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    76
      condition for @{term g_even} by proving a stronger inductive invariant."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    77
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    78
lemma g_even_indinv: "\<exists>k. n = Suc (Suc (2*k)) ==> g_even n = 3"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    79
apply (rule_tac D="{n. \<exists>k. n = Suc (Suc (2*k))}" and x=n in tfl_indinv_on_wfrec [OF g_even_def])
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    80
apply (auto simp add: indinv_on_def split: nat.split)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    81
by (case_tac ka, auto)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    82
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    83
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    84
text "Now we can prove that the second recursion equation for @{term g_even}
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    85
      holds, provided that n is an even number greater than two."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    86
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    87
theorem g_even_n: "\<exists>k. n = 2*k + 4 ==> g_even n = g_even (g_even (n - 2) - 1)"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    88
apply (subgoal_tac "(\<exists>k. n - 2 = 2*k + 2) & (\<exists>k. n = 2*k + 2)")
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    89
by (auto simp add: g_even_indinv, arith)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    90
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    91
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    92
text "McCarthy's ninety-one function. This function requires a
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    93
      non-standard measure to prove termination."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    94
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    95
consts ninety_one :: "nat => nat"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    96
recdef (permissive) ninety_one "measure (%n. 101 - n)"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    97
  "ninety_one x = (if 100 < x
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    98
                     then x - 10
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
    99
                     else (ninety_one (ninety_one (x+11))))"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   100
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   101
text "To discharge the termination condition, we will prove
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   102
      a strengthened inductive invariant:
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   103
         S x y == x < y + 11"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   104
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   105
lemma ninety_one_inv: "n < ninety_one n + 11"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   106
apply (rule_tac x=n in tfl_indinv_wfrec [OF ninety_one_def])
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   107
apply force
19769
c40ce2de2020 Added [simp]-lemmas "in_inv_image" and "in_lex_prod" in the spirit of "in_measure".
krauss
parents: 19623
diff changeset
   108
apply (auto simp add: indinv_def)
15636
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   109
apply (frule_tac x="x+11" in spec)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   110
apply (frule_tac x="f (x + 11)" in spec)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   111
by arith
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   112
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   113
text "Proving the termination condition using the
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   114
      strengthened inductive invariant."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   115
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   116
recdef_tc ninety_one_tc[rule_format]: ninety_one
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   117
apply clarify
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   118
by (cut_tac n="x+11" in ninety_one_inv, arith)
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   119
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   120
text "Now we can remove the termination condition from
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   121
      the simplification rule for @{term ninety_one}."
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   122
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   123
theorem def_ninety_one:
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   124
"ninety_one x = (if 100 < x
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   125
                   then x - 10
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   126
                   else ninety_one (ninety_one (x+11)))"
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   127
by (subst ninety_one.simps,
19769
c40ce2de2020 Added [simp]-lemmas "in_inv_image" and "in_lex_prod" in the spirit of "in_measure".
krauss
parents: 19623
diff changeset
   128
    simp add: ninety_one_tc)
15636
57c437b70521 converted from DOS to UNIX format
paulson
parents: 14244
diff changeset
   129
17388
495c799df31d tuned headers etc.;
wenzelm
parents: 16417
diff changeset
   130
end