src/HOL/Imperative_HOL/ex/Imperative_Reverse.thy
author bulwahn
Thu Dec 10 11:58:26 2009 +0100 (2009-12-10 ago)
changeset 34051 1a82e2e29d67
child 36098 53992c639da5
permissions -rw-r--r--
added Imperative_HOL examples; added tail-recursive combinator for monadic heap functions; adopted code generation of references; added lemmas
bulwahn@34051
     1
theory Imperative_Reverse
bulwahn@34051
     2
imports "~~/src/HOL/Imperative_HOL/Imperative_HOL" Subarray
bulwahn@34051
     3
begin
bulwahn@34051
     4
bulwahn@34051
     5
hide (open) const swap rev
bulwahn@34051
     6
bulwahn@34051
     7
fun swap :: "'a\<Colon>heap array \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> unit Heap" where
bulwahn@34051
     8
  "swap a i j = (do
bulwahn@34051
     9
     x \<leftarrow> nth a i;
bulwahn@34051
    10
     y \<leftarrow> nth a j;
bulwahn@34051
    11
     upd i y a;
bulwahn@34051
    12
     upd j x a;
bulwahn@34051
    13
     return ()
bulwahn@34051
    14
   done)"
bulwahn@34051
    15
bulwahn@34051
    16
fun rev :: "'a\<Colon>heap array \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> unit Heap" where
bulwahn@34051
    17
  "rev a i j = (if (i < j) then (do
bulwahn@34051
    18
     swap a i j;
bulwahn@34051
    19
     rev a (i + 1) (j - 1)
bulwahn@34051
    20
   done)
bulwahn@34051
    21
   else return ())"
bulwahn@34051
    22
bulwahn@34051
    23
notation (output) swap ("swap")
bulwahn@34051
    24
notation (output) rev ("rev")
bulwahn@34051
    25
bulwahn@34051
    26
declare swap.simps [simp del] rev.simps [simp del]
bulwahn@34051
    27
bulwahn@34051
    28
lemma swap_pointwise: assumes "crel (swap a i j) h h' r"
bulwahn@34051
    29
  shows "get_array a h' ! k = (if k = i then get_array a h ! j
bulwahn@34051
    30
      else if k = j then get_array a h ! i
bulwahn@34051
    31
      else get_array a h ! k)"
bulwahn@34051
    32
using assms unfolding swap.simps
bulwahn@34051
    33
by (elim crel_elim_all)
bulwahn@34051
    34
 (auto simp: Heap.length_def)
bulwahn@34051
    35
bulwahn@34051
    36
lemma rev_pointwise: assumes "crel (rev a i j) h h' r"
bulwahn@34051
    37
  shows "get_array a h' ! k = (if k < i then get_array a h ! k
bulwahn@34051
    38
      else if j < k then get_array a h ! k
bulwahn@34051
    39
      else get_array a h ! (j - (k - i)))" (is "?P a i j h h'")
bulwahn@34051
    40
using assms proof (induct a i j arbitrary: h h' rule: rev.induct)
bulwahn@34051
    41
  case (1 a i j h h'')
bulwahn@34051
    42
  thus ?case
bulwahn@34051
    43
  proof (cases "i < j")
bulwahn@34051
    44
    case True
bulwahn@34051
    45
    with 1[unfolded rev.simps[of a i j]]
bulwahn@34051
    46
    obtain h' where
bulwahn@34051
    47
      swp: "crel (swap a i j) h h' ()"
bulwahn@34051
    48
      and rev: "crel (rev a (i + 1) (j - 1)) h' h'' ()"
bulwahn@34051
    49
      by (auto elim: crel_elim_all)
bulwahn@34051
    50
    from rev 1 True
bulwahn@34051
    51
    have eq: "?P a (i + 1) (j - 1) h' h''" by auto
bulwahn@34051
    52
bulwahn@34051
    53
    have "k < i \<or> i = k \<or> (i < k \<and> k < j) \<or> j = k \<or> j < k" by arith
bulwahn@34051
    54
    with True show ?thesis
bulwahn@34051
    55
      by (elim disjE) (auto simp: eq swap_pointwise[OF swp])
bulwahn@34051
    56
  next
bulwahn@34051
    57
    case False
bulwahn@34051
    58
    with 1[unfolded rev.simps[of a i j]]
bulwahn@34051
    59
    show ?thesis
bulwahn@34051
    60
      by (cases "k = j") (auto elim: crel_elim_all)
bulwahn@34051
    61
  qed
bulwahn@34051
    62
qed
bulwahn@34051
    63
bulwahn@34051
    64
lemma rev_length:
bulwahn@34051
    65
  assumes "crel (rev a i j) h h' r"
bulwahn@34051
    66
  shows "Heap.length a h = Heap.length a h'"
bulwahn@34051
    67
using assms
bulwahn@34051
    68
proof (induct a i j arbitrary: h h' rule: rev.induct)
bulwahn@34051
    69
  case (1 a i j h h'')
bulwahn@34051
    70
  thus ?case
bulwahn@34051
    71
  proof (cases "i < j")
bulwahn@34051
    72
    case True
bulwahn@34051
    73
    with 1[unfolded rev.simps[of a i j]]
bulwahn@34051
    74
    obtain h' where
bulwahn@34051
    75
      swp: "crel (swap a i j) h h' ()"
bulwahn@34051
    76
      and rev: "crel (rev a (i + 1) (j - 1)) h' h'' ()"
bulwahn@34051
    77
      by (auto elim: crel_elim_all)
bulwahn@34051
    78
    from swp rev 1 True show ?thesis
bulwahn@34051
    79
      unfolding swap.simps
bulwahn@34051
    80
      by (elim crel_elim_all) fastsimp
bulwahn@34051
    81
  next
bulwahn@34051
    82
    case False
bulwahn@34051
    83
    with 1[unfolded rev.simps[of a i j]]
bulwahn@34051
    84
    show ?thesis
bulwahn@34051
    85
      by (auto elim: crel_elim_all)
bulwahn@34051
    86
  qed
bulwahn@34051
    87
qed
bulwahn@34051
    88
bulwahn@34051
    89
lemma rev2_rev': assumes "crel (rev a i j) h h' u"
bulwahn@34051
    90
  assumes "j < Heap.length a h"
bulwahn@34051
    91
  shows "subarray i (j + 1) a h' = List.rev (subarray i (j + 1) a h)"
bulwahn@34051
    92
proof - 
bulwahn@34051
    93
  {
bulwahn@34051
    94
    fix k
bulwahn@34051
    95
    assume "k < Suc j - i"
bulwahn@34051
    96
    with rev_pointwise[OF assms(1)] have "get_array a h' ! (i + k) = get_array a h ! (j - k)"
bulwahn@34051
    97
      by auto
bulwahn@34051
    98
  } 
bulwahn@34051
    99
  with assms(2) rev_length[OF assms(1)] show ?thesis
bulwahn@34051
   100
  unfolding subarray_def Heap.length_def
bulwahn@34051
   101
  by (auto simp add: length_sublist' rev_nth min_def nth_sublist' intro!: nth_equalityI)
bulwahn@34051
   102
qed
bulwahn@34051
   103
bulwahn@34051
   104
lemma rev2_rev: 
bulwahn@34051
   105
  assumes "crel (rev a 0 (Heap.length a h - 1)) h h' u"
bulwahn@34051
   106
  shows "get_array a h' = List.rev (get_array a h)"
bulwahn@34051
   107
  using rev2_rev'[OF assms] rev_length[OF assms] assms
bulwahn@34051
   108
    by (cases "Heap.length a h = 0", auto simp add: Heap.length_def
bulwahn@34051
   109
      subarray_def sublist'_all rev.simps[where j=0] elim!: crel_elim_all)
bulwahn@34051
   110
  (drule sym[of "List.length (get_array a h)"], simp)
bulwahn@34051
   111
bulwahn@34051
   112
end