thys/NatBijection.thy
author Sebastiaan Joosten <sebastiaan.joosten@uibk.ac.at>
Fri, 21 Dec 2018 12:31:36 +0100
changeset 290 6e1c03614d36
parent 254 0546ae452747
permissions -rw-r--r--
Gave lemmas names in Abacus.ty
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
252
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
theory NatBijection
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
imports Main Parity "~~/src/HOL/Library/Discrete"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
begin
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
declare One_nat_def[simp del]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
fun oddfactor :: "nat \<Rightarrow> nat" where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
  [simp del]: "oddfactor n = (if n = 0 then 0 
254
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
     9
                              else if even n then oddfactor (n div 2) else ((n - 1) div 2))"
252
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    10
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
fun evenfactor :: "nat \<Rightarrow> nat" where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
  [simp del]: "evenfactor n = (if n = 0 then 0 
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
                               else if even n then 2 * evenfactor (n div 2) else 1)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
254
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    15
lemma oddfactor [simp]:
252
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
  "oddfactor 0 = 0"
254
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    17
  "odd n \<Longrightarrow> oddfactor n = (n - 1) div 2"
252
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
  "even n \<Longrightarrow> oddfactor n = oddfactor (n div 2)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
by (simp_all add: oddfactor.simps)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
254
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    21
lemma evenfactor [simp]:
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    22
  "evenfactor 0 = 0"
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    23
  "odd n \<Longrightarrow> evenfactor n = 1"
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    24
  "even n \<Longrightarrow> evenfactor n = 2 * evenfactor (n div 2)"
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    25
apply(simp_all add: evenfactor.simps)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    26
apply(case_tac n)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    27
apply(simp_all)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    28
done
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    29
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    30
fun penc :: "(nat \<times> nat) \<Rightarrow> nat" where
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    31
  "penc (m, n) = (2 ^ m) * (2 * n + 1) - 1"
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    32
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    33
fun pdec :: "nat \<Rightarrow> nat \<times> nat" where
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    34
  "pdec z = (Discrete.log (evenfactor (Suc z)), oddfactor (Suc z))"
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    35
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    36
lemma q2: "pdec (penc m) = m"
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    37
apply(case_tac m)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    38
apply(simp)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    39
apply(simp only: penc.simps pdec.simps)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    40
apply(case_tac m)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    41
apply(simp only: penc.simps pdec.simps)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    42
apply(subst y1)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    43
apply(subst y2)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    44
apply(simp)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    45
done
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 252
diff changeset
    46
252
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
lemma oddfactor_odd:
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
  "oddfactor n = 0 \<or> odd (oddfactor n)" 
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
apply(induct n rule: nat_less_induct)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
apply(case_tac "n = 0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
apply(case_tac "odd n")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
apply(auto)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57
lemma bigger: "oddfactor (Suc n) > 0"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
apply(induct n rule: nat_less_induct)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
apply(case_tac "n = 0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
apply(case_tac "odd n")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
apply(auto)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
apply(drule_tac x="n div 2" in spec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
apply(drule mp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
apply(auto)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    66
by (smt numeral_2_eq_2 odd_nat_plus_one_div_two)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    67
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
fun pencode :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
  "pencode m n = (2 ^ m) * (2 * n + 1) - 1"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
fun pdecode2 :: "nat \<Rightarrow> nat" where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
  "pdecode2 z = (oddfactor (Suc z) - 1) div 2"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    73
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
fun pdecode1 :: "nat \<Rightarrow> nat" where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
  "pdecode1 z = Discrete.log ((Suc z) div (oddfactor (Suc z)))"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    76
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
lemma k:
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
  "odd n \<Longrightarrow> oddfactor (2 ^ m * n) = n"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    79
apply(induct m)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
apply(simp_all)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    81
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
lemma ww: "\<exists>k. n = 2 ^ k * oddfactor n"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
apply(induct n rule: nat_less_induct)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    85
apply(case_tac "n=0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
apply(case_tac "odd n")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
apply(rule_tac x="0" in exI)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    91
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    92
apply(drule_tac x="n div 2" in spec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    93
apply(erule impE)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    95
apply(erule exE)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
apply(rule_tac x="Suc k" in exI)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    97
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
by (metis div_mult_self2_is_id even_mult_two_ex nat_mult_assoc nat_mult_commute zero_neq_numeral)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   101
lemma test: "x = y \<Longrightarrow> 2 * x = 2 * y"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   102
by simp
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
lemma m: "0 < n ==> 2 ^ Discrete.log (n div (oddfactor n)) = n div (oddfactor n)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
apply(induct n rule: nat_less_induct)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   106
apply(case_tac "n=0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   107
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   108
apply(case_tac "odd n")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   109
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   110
apply(drule_tac x="n div 2" in spec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   111
apply(drule mp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   112
apply(auto)[1]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   113
apply(drule mp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   114
apply (metis One_nat_def Suc_lessI div_2_gt_zero odd_1_nat)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   115
apply(subst (asm) oddfactor(3)[symmetric])
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   116
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   117
apply(subst (asm) oddfactor(3)[symmetric])
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   118
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   119
apply(subgoal_tac "n div 2 div oddfactor n = n div (oddfactor n) div 2")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   120
prefer 2
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   121
apply (metis div_mult2_eq nat_mult_commute)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   122
apply(simp only: log_half)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   123
apply(case_tac "n div oddfactor n = 0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   124
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   125
apply(simp del: oddfactor)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   126
apply(drule test)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   127
apply(subst (asm) power.simps(2)[symmetric])
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   128
apply(subgoal_tac "Suc (Discrete.log (n div oddfactor n) - 1) = Discrete.log (n div oddfactor n)")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   129
prefer 2
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   130
apply (smt log.simps Suc_1 div_less div_mult_self1_is_id log_half log_zero numeral_1_eq_Suc_0 numeral_One odd_1_nat odd_nat_plus_one_div_two one_less_numeral_iff power_one_right semiring_norm(76))
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   131
apply(simp only: One_nat_def)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   132
apply(subst dvd_mult_div_cancel)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   133
apply (smt Suc_1 div_by_0 div_mult_self2_is_id oddfactor_odd dvd_power even_Suc even_numeral_nat even_product_nat nat_even_iff_2_dvd power_0 ww)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   134
apply(simp (no_asm))
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   135
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   136
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   137
lemma m1: "n div oddfactor n * oddfactor n = n"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   138
apply(induct n rule: nat_less_induct)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   139
apply(case_tac "n=0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   140
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   141
apply(case_tac "odd n")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   142
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   143
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   144
apply(drule_tac x="n div 2" in spec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   145
apply(drule mp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   146
apply(auto)[1]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   147
by (metis add_eq_if diff_add_inverse oddfactor(3) mod_eq_0_iff mult_div_cancel nat_mult_commute ww)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   148
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   149
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   150
lemma m2: "0 < n ==> 2 ^ Discrete.log (n div (oddfactor n)) * (oddfactor n) = n"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   151
apply(subst m)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   152
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   153
apply(subst m1)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   154
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   155
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   156
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   157
lemma y1:
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   158
  "pdecode2 (pencode m n) = n"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   159
apply(simp del: One_nat_def)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   160
apply(subst k)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   161
apply(auto)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   162
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   163
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   164
lemma y2:
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   165
  "pdecode1 (pencode m n) = m"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   166
apply(simp only: pdecode1.simps pencode.simps)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   167
apply(subst Suc_diff_1)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   168
apply(auto)[1]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   169
apply(subst Suc_diff_1)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   170
apply(auto)[1]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   171
apply(subst k)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   172
apply(auto)[1]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   173
by (metis Suc_eq_plus1 Suc_neq_Zero comm_semiring_1_class.normalizing_semiring_rules(7) div_mult_self1_is_id log_exp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   174
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   175
lemma yy: 
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   176
  "pencode (pdecode1 m) (pdecode2 m) = m"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   177
apply(induct m rule: nat_less_induct)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   178
apply(simp (no_asm))
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   179
apply(case_tac "n = 0")
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   180
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   181
apply(subst dvd_mult_div_cancel)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   182
using oddfactor_odd
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   183
apply -
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   184
apply(drule_tac x="Suc n" in meta_spec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   185
apply(erule disjE)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   186
apply(auto)[1]
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   187
apply (metis One_nat_def even_num_iff nat_even_iff_2_dvd odd_pos)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   188
using bigger
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   189
apply -
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   190
apply(rotate_tac 3)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   191
apply(drule_tac x="n" in meta_spec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   192
apply(simp del: pencode.simps pdecode2.simps pdecode1.simps One_nat_def add: One_nat_def[symmetric])
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   193
apply(subst m2)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   194
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   195
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   196
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   197
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   198
fun penc where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   199
 "penc (m, n) = pencode m n"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   200
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   201
fun pdec where
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   202
 "pdec m = (pdecode1 m, pdecode2 m)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   203
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   204
lemma q1: "penc (pdec m) = m"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   205
apply(simp only: penc.simps pdec.simps)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   206
apply(rule yy)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   207
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   208
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   209
lemma q2: "pdec (penc m) = m"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   210
apply(simp only: penc.simps pdec.simps)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   211
apply(case_tac m)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   212
apply(simp only: penc.simps pdec.simps)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   213
apply(subst y1)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   214
apply(subst y2)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   215
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   216
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   217
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   218
lemma inj_penc: "inj_on penc A"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   219
apply(rule inj_on_inverseI)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   220
apply(rule q2)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   221
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   222
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   223
lemma inj_pdec: "inj_on pdec A"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   224
apply(rule inj_on_inverseI)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   225
apply(rule q1)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   226
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   227
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   228
lemma surj_penc: "surj penc"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   229
apply(rule surjI)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   230
apply(rule q1)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   231
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   232
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   233
lemma surj_pdec: "surj pdec"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   234
apply(rule surjI)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   235
apply(rule q2)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   236
done
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   237
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   238
lemma 
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   239
  "bij pdec"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   240
by(simp add: bij_def surj_pdec inj_pdec)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   241
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   242
lemma 
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   243
  "bij penc"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   244
by(simp add: bij_def surj_penc inj_penc)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   245
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   246
lemma "a \<le> penc (a, 0)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   247
apply(induct a)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   248
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   249
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   250
by (smt nat_one_le_power)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   251
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   252
lemma "penc(a, 0) \<le> penc (a, b)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   253
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   254
by (metis diff_le_mono le_add1 mult_2_right mult_le_mono1 nat_add_commute nat_mult_1 nat_mult_commute)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   255
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   256
lemma "b \<le> penc (a, b)"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   257
apply(simp)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   258
proof -
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   259
  have f1: "(1\<Colon>nat) + 1 = 2"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   260
    by (metis mult_2 nat_mult_1_right)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   261
  have f2: "\<And>x\<^isub>1 x\<^isub>2. (x\<^isub>1\<Colon>nat) \<le> x\<^isub>1 * x\<^isub>2 \<or> \<not> 1 \<le> x\<^isub>2"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   262
    by (metis mult_le_mono2 nat_mult_1_right)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   263
  have "1 + (b + b) \<le> 1 + b \<longrightarrow> b \<le> (1 + (b + b)) * (1 + 1) ^ a - 1"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   264
    by (metis le_add1 le_trans nat_add_left_cancel_le)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   265
  hence "(1 + (b + b)) * (1 + 1) ^ a \<le> 1 + b \<longrightarrow> b \<le> (1 + (b + b)) * (1 + 1) ^ a - 1"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   266
    using f2 by (metis le_add1 le_trans one_le_power)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   267
  hence "b \<le> 2 ^ a * (b + b + 1) - 1"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   268
    using f1 by (metis le_diff_conv nat_add_commute nat_le_linear nat_mult_commute)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   269
  thus "b \<le> 2 ^ a * (2 * b + 1) - 1"
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   270
    by (metis mult_2)
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   271
qed
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   272
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   273
415e3082ccbc added first version of natbiject
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   274
end