src/HOL/Word/Bit_Comprehension.thy
author desharna
Thu, 08 Oct 2020 16:36:00 +0200
changeset 72399 f8900a5ad4a7
parent 72397 48013583e8e6
child 72488 ee659bca8955
permissions -rw-r--r--
drop obsolete ad hoc support for Satallax isar proof reconstruction
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
70192
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     1
(*  Title:      HOL/Word/Bit_Comprehension.thy
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     2
    Author:     Brian Huffman, PSU; Jeremy Dawson and Gerwin Klein, NICTA
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     3
*)
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     4
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     5
section \<open>Comprehension syntax for bit expressions\<close>
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     6
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     7
theory Bit_Comprehension
72397
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
     8
  imports Word
70192
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
     9
begin
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    10
72397
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    11
class bit_comprehension = ring_bit_operations +
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    12
  fixes set_bits :: \<open>(nat \<Rightarrow> bool) \<Rightarrow> 'a\<close>  (binder \<open>BITS \<close> 10)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    13
  assumes set_bits_bit_eq: \<open>set_bits (bit a) = a\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    14
begin
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    15
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    16
lemma set_bits_False_eq [simp]:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    17
  \<open>(BITS _. False) = 0\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    18
  using set_bits_bit_eq [of 0] by (simp add: bot_fun_def)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    19
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    20
end
70192
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    21
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    22
instantiation int :: bit_comprehension
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    23
begin
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    24
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    25
definition
72397
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    26
  \<open>set_bits f = (
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    27
      if \<exists>n. \<forall>m\<ge>n. f m = f n then
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    28
      let n = LEAST n. \<forall>m\<ge>n. f m = f n
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    29
      in signed_take_bit n (horner_sum of_bool 2 (map f [0..<Suc n]))
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    30
     else 0 :: int)\<close>
70192
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    31
72397
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    32
instance proof
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    33
  fix k :: int
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    34
  from int_bit_bound [of k] 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    35
  obtain n where *: \<open>\<And>m. n \<le> m \<Longrightarrow> bit k m \<longleftrightarrow> bit k n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    36
    and **: \<open>n > 0 \<Longrightarrow> bit k (n - 1) \<noteq> bit k n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    37
    by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    38
  then have ***: \<open>\<exists>n. \<forall>n'\<ge>n. bit k n' \<longleftrightarrow> bit k n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    39
    by meson
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    40
  have l: \<open>(LEAST q. \<forall>m\<ge>q. bit k m \<longleftrightarrow> bit k q) = n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    41
    apply (rule Least_equality)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    42
    using * apply blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    43
    apply (metis "**" One_nat_def Suc_pred le_cases le0 neq0_conv not_less_eq_eq)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    44
    done
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    45
  show \<open>set_bits (bit k) = k\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    46
    apply (simp only: *** set_bits_int_def horner_sum_bit_eq_take_bit l)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    47
    apply simp
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    48
    apply (rule bit_eqI)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    49
    apply (simp add: bit_signed_take_bit_iff min_def)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    50
    using "*" by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    51
qed
70192
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    52
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    53
end
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    54
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    55
lemma int_set_bits_K_False [simp]: "(BITS _. False) = (0 :: int)"
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    56
  by (simp add: set_bits_int_def)
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    57
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    58
lemma int_set_bits_K_True [simp]: "(BITS _. True) = (-1 :: int)"
72397
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    59
  by (simp add: set_bits_int_def)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    60
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    61
instantiation word :: (len) bit_comprehension
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    62
begin
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    63
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    64
definition word_set_bits_def:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    65
  \<open>(BITS n. P n) = (horner_sum of_bool 2 (map P [0..<LENGTH('a)]) :: 'a word)\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    66
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    67
instance by standard
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    68
  (simp add: word_set_bits_def horner_sum_bit_eq_take_bit)
70192
b4bf82ed0ad5 separate type class for bit comprehension
haftmann
parents:
diff changeset
    69
72081
e4d42f5766dc clearer separation of pre-word bit list material
haftmann
parents: 72027
diff changeset
    70
end
72397
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    71
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    72
lemma bit_set_bits_word_iff:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    73
  \<open>bit (set_bits P :: 'a::len word) n \<longleftrightarrow> n < LENGTH('a) \<and> P n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    74
  by (auto simp add: word_set_bits_def bit_horner_sum_bit_word_iff)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    75
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    76
lemma set_bits_K_False [simp]:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    77
  \<open>set_bits (\<lambda>_. False) = (0 :: 'a :: len word)\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    78
  by (rule bit_word_eqI) (simp add: bit_set_bits_word_iff)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    79
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    80
lemma set_bits_int_unfold':
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    81
  \<open>set_bits f =
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    82
    (if \<exists>n. \<forall>n'\<ge>n. \<not> f n' then
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    83
      let n = LEAST n. \<forall>n'\<ge>n. \<not> f n'
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    84
      in horner_sum of_bool 2 (map f [0..<n])
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    85
     else if \<exists>n. \<forall>n'\<ge>n. f n' then
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    86
      let n = LEAST n. \<forall>n'\<ge>n. f n'
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    87
      in signed_take_bit n (horner_sum of_bool 2 (map f [0..<n] @ [True]))
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    88
     else 0 :: int)\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    89
proof (cases \<open>\<exists>n. \<forall>m\<ge>n. f m \<longleftrightarrow> f n\<close>)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    90
  case True
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    91
  then obtain q where q: \<open>\<forall>m\<ge>q. f m \<longleftrightarrow> f q\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    92
    by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    93
  define n where \<open>n = (LEAST n. \<forall>m\<ge>n. f m \<longleftrightarrow> f n)\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    94
  have \<open>\<forall>m\<ge>n. f m \<longleftrightarrow> f n\<close> 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    95
    unfolding n_def
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    96
    using q by (rule LeastI [of _ q])
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    97
  then have n: \<open>\<And>m. n \<le> m \<Longrightarrow> f m \<longleftrightarrow> f n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    98
    by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
    99
  from n_def have n_eq: \<open>(LEAST q. \<forall>m\<ge>q. f m \<longleftrightarrow> f n) = n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   100
    by (smt Least_equality Least_le \<open>\<forall>m\<ge>n. f m = f n\<close> dual_order.refl le_refl n order_refl)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   101
  show ?thesis
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   102
  proof (cases \<open>f n\<close>)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   103
    case False
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   104
    with n have *: \<open>\<exists>n. \<forall>n'\<ge>n. \<not> f n'\<close> 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   105
      by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   106
    have **: \<open>(LEAST n. \<forall>n'\<ge>n. \<not> f n') = n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   107
      using False n_eq by simp
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   108
    from * False show ?thesis
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   109
    apply (simp add: set_bits_int_def n_def [symmetric] ** del: upt.upt_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   110
    apply (auto simp add: take_bit_horner_sum_bit_eq
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   111
      bit_horner_sum_bit_iff take_map
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   112
      signed_take_bit_def set_bits_int_def
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   113
      horner_sum_bit_eq_take_bit simp del: upt.upt_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   114
    done
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   115
  next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   116
    case True
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   117
    with n have *: \<open>\<exists>n. \<forall>n'\<ge>n. f n'\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   118
      by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   119
    have ***: \<open>\<not> (\<exists>n. \<forall>n'\<ge>n. \<not> f n')\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   120
      apply (rule ccontr)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   121
      using * nat_le_linear by auto 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   122
    have **: \<open>(LEAST n. \<forall>n'\<ge>n. f n') = n\<close>
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   123
      using True n_eq by simp
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   124
    from * *** True show ?thesis
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   125
    apply (simp add: set_bits_int_def n_def [symmetric] ** del: upt.upt_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   126
    apply (auto simp add: take_bit_horner_sum_bit_eq
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   127
      bit_horner_sum_bit_iff take_map
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   128
      signed_take_bit_def set_bits_int_def
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   129
      horner_sum_bit_eq_take_bit nth_append simp del: upt.upt_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   130
    done
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   131
  qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   132
next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   133
  case False
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   134
  then show ?thesis
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   135
    by (auto simp add: set_bits_int_def)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   136
qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   137
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   138
inductive wf_set_bits_int :: "(nat \<Rightarrow> bool) \<Rightarrow> bool" 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   139
  for f :: "nat \<Rightarrow> bool"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   140
where
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   141
  zeros: "\<forall>n' \<ge> n. \<not> f n' \<Longrightarrow> wf_set_bits_int f"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   142
| ones: "\<forall>n' \<ge> n. f n' \<Longrightarrow> wf_set_bits_int f"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   143
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   144
lemma wf_set_bits_int_simps: "wf_set_bits_int f \<longleftrightarrow> (\<exists>n. (\<forall>n'\<ge>n. \<not> f n') \<or> (\<forall>n'\<ge>n. f n'))"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   145
by(auto simp add: wf_set_bits_int.simps)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   146
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   147
lemma wf_set_bits_int_const [simp]: "wf_set_bits_int (\<lambda>_. b)"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   148
by(cases b)(auto intro: wf_set_bits_int.intros)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   149
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   150
lemma wf_set_bits_int_fun_upd [simp]: 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   151
  "wf_set_bits_int (f(n := b)) \<longleftrightarrow> wf_set_bits_int f" (is "?lhs \<longleftrightarrow> ?rhs")
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   152
proof
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   153
  assume ?lhs
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   154
  then obtain n'
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   155
    where "(\<forall>n''\<ge>n'. \<not> (f(n := b)) n'') \<or> (\<forall>n''\<ge>n'. (f(n := b)) n'')"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   156
    by(auto simp add: wf_set_bits_int_simps)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   157
  hence "(\<forall>n''\<ge>max (Suc n) n'. \<not> f n'') \<or> (\<forall>n''\<ge>max (Suc n) n'. f n'')" by auto
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   158
  thus ?rhs by(auto simp only: wf_set_bits_int_simps)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   159
next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   160
  assume ?rhs
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   161
  then obtain n' where "(\<forall>n''\<ge>n'. \<not> f n'') \<or> (\<forall>n''\<ge>n'. f n'')" (is "?wf f n'")
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   162
    by(auto simp add: wf_set_bits_int_simps)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   163
  hence "?wf (f(n := b)) (max (Suc n) n')" by auto
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   164
  thus ?lhs by(auto simp only: wf_set_bits_int_simps)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   165
qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   166
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   167
lemma wf_set_bits_int_Suc [simp]:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   168
  "wf_set_bits_int (\<lambda>n. f (Suc n)) \<longleftrightarrow> wf_set_bits_int f" (is "?lhs \<longleftrightarrow> ?rhs")
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   169
by(auto simp add: wf_set_bits_int_simps intro: le_SucI dest: Suc_le_D)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   170
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   171
context
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   172
  fixes f
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   173
  assumes wff: "wf_set_bits_int f"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   174
begin
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   175
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   176
lemma int_set_bits_unfold_BIT:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   177
  "set_bits f = of_bool (f 0) + (2 :: int) * set_bits (f \<circ> Suc)"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   178
using wff proof cases
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   179
  case (zeros n)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   180
  show ?thesis
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   181
  proof(cases "\<forall>n. \<not> f n")
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   182
    case True
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   183
    hence "f = (\<lambda>_. False)" by auto
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   184
    thus ?thesis using True by(simp add: o_def)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   185
  next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   186
    case False
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   187
    then obtain n' where "f n'" by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   188
    with zeros have "(LEAST n. \<forall>n'\<ge>n. \<not> f n') = Suc (LEAST n. \<forall>n'\<ge>Suc n. \<not> f n')"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   189
      by(auto intro: Least_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   190
    also have "(\<lambda>n. \<forall>n'\<ge>Suc n. \<not> f n') = (\<lambda>n. \<forall>n'\<ge>n. \<not> f (Suc n'))" by(auto dest: Suc_le_D)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   191
    also from zeros have "\<forall>n'\<ge>n. \<not> f (Suc n')" by auto
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   192
    ultimately show ?thesis using zeros
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   193
      apply (simp (no_asm_simp) add: set_bits_int_unfold' exI
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   194
        del: upt.upt_Suc flip: map_map split del: if_split)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   195
      apply (simp only: map_Suc_upt upt_conv_Cons)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   196
      apply simp
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   197
      done
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   198
  qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   199
next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   200
  case (ones n)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   201
  show ?thesis
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   202
  proof(cases "\<forall>n. f n")
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   203
    case True
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   204
    hence "f = (\<lambda>_. True)" by auto
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   205
    thus ?thesis using True by(simp add: o_def)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   206
  next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   207
    case False
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   208
    then obtain n' where "\<not> f n'" by blast
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   209
    with ones have "(LEAST n. \<forall>n'\<ge>n. f n') = Suc (LEAST n. \<forall>n'\<ge>Suc n. f n')"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   210
      by(auto intro: Least_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   211
    also have "(\<lambda>n. \<forall>n'\<ge>Suc n. f n') = (\<lambda>n. \<forall>n'\<ge>n. f (Suc n'))" by(auto dest: Suc_le_D)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   212
    also from ones have "\<forall>n'\<ge>n. f (Suc n')" by auto
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   213
    moreover from ones have "(\<exists>n. \<forall>n'\<ge>n. \<not> f n') = False"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   214
      by(auto intro!: exI[where x="max n m" for n m] simp add: max_def split: if_split_asm)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   215
    moreover hence "(\<exists>n. \<forall>n'\<ge>n. \<not> f (Suc n')) = False"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   216
      by(auto elim: allE[where x="Suc n" for n] dest: Suc_le_D)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   217
    ultimately show ?thesis using ones
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   218
      apply (simp (no_asm_simp) add: set_bits_int_unfold' exI split del: if_split)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   219
      apply (auto simp add: Let_def hd_map map_tl[symmetric] map_map[symmetric] map_Suc_upt upt_conv_Cons signed_take_bit_Suc
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   220
        not_le simp del: map_map)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   221
      done
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   222
  qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   223
qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   224
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   225
lemma bin_last_set_bits [simp]:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   226
  "bin_last (set_bits f) = f 0"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   227
  by (subst int_set_bits_unfold_BIT) simp_all
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   228
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   229
lemma bin_rest_set_bits [simp]:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   230
  "bin_rest (set_bits f) = set_bits (f \<circ> Suc)"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   231
  by (subst int_set_bits_unfold_BIT) simp_all
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   232
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   233
lemma bin_nth_set_bits [simp]:
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   234
  "bin_nth (set_bits f) m = f m"
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   235
using wff proof (induction m arbitrary: f)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   236
  case 0 
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   237
  then show ?case
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   238
    by (simp add: Bit_Comprehension.bin_last_set_bits)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   239
next
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   240
  case Suc
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   241
  from Suc.IH [of "f \<circ> Suc"] Suc.prems show ?case
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   242
    by (simp add: Bit_Comprehension.bin_rest_set_bits comp_def bit_Suc)
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   243
qed
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   244
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   245
end
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   246
48013583e8e6 factored out bit comprehension
haftmann
parents: 72128
diff changeset
   247
end