thys/UF_Rec.thy
changeset 246 e113420a2fce
child 248 aea02b5a58d2
equal deleted inserted replaced
245:af60d84e0677 246:e113420a2fce
       
     1 theory UF_Rec
       
     2 imports Recs
       
     3 begin
       
     4 
       
     5 section {* Universal Function *}
       
     6 
       
     7 text {* @{text "NextPrime x"} returns the first prime number after @{text "x"}. *}
       
     8 
       
     9 fun NextPrime ::"nat \<Rightarrow> nat"
       
    10   where
       
    11   "NextPrime x = (LEAST y. y \<le> Suc (fact x) \<and> x < y \<and> prime y)"
       
    12 
       
    13 definition rec_nextprime :: "recf"
       
    14   where
       
    15   "rec_nextprime = (let conj1 = CN rec_le [Id 2 0, CN S [CN rec_fact [Id 2 1]]] in
       
    16                     let conj2 = CN rec_less [Id 2 1, Id 2 0] in
       
    17                     let conj3 = CN rec_prime [Id 2 0] in 
       
    18                     let conjs = CN rec_conj [CN rec_conj [conj2, conj1], conj3]
       
    19                     in MN (CN rec_not [conjs]))"
       
    20 
       
    21 lemma nextprime_lemma [simp]:
       
    22   "rec_eval rec_nextprime [x] = NextPrime x"
       
    23 by (simp add: rec_nextprime_def Let_def)
       
    24 
       
    25 
       
    26 fun Pi :: "nat \<Rightarrow> nat"
       
    27   where
       
    28   "Pi 0 = 2" |
       
    29   "Pi (Suc x) = NextPrime (Pi x)"
       
    30 
       
    31 definition 
       
    32   "rec_pi = PR (constn 2) (CN rec_nextprime [Id 2 1])"
       
    33 
       
    34 lemma pi_lemma [simp]:
       
    35   "rec_eval rec_pi [x] = Pi x"
       
    36 by (induct x) (simp_all add: rec_pi_def)
       
    37 
       
    38 
       
    39 
       
    40 text{* coding of the configuration *}
       
    41 
       
    42 text {*
       
    43   @{text "Entry sr i"} returns the @{text "i"}-th entry of a list of natural 
       
    44   numbers encoded by number @{text "sr"} using Godel's coding.
       
    45   *}
       
    46 fun Entry where
       
    47   "Entry sr i = Lo sr (Pi (Suc i))"
       
    48 
       
    49 definition 
       
    50   "rec_entry = CN rec_lo [Id 2 0, CN rec_pi [CN S [Id 2 1]]]"
       
    51 
       
    52 lemma entry_lemma [simp]:
       
    53   "rec_eval rec_entry [sr, i] = Entry sr i"
       
    54 by(simp add: rec_entry_def)
       
    55 
       
    56 
       
    57 fun Listsum2 :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
    58   where
       
    59   "Listsum2 xs 0 = 0"
       
    60 | "Listsum2 xs (Suc n) = Listsum2 xs n + xs ! n"
       
    61 
       
    62 fun rec_listsum2 :: "nat \<Rightarrow> nat \<Rightarrow> recf"
       
    63   where
       
    64   "rec_listsum2 vl 0 = CN Z [Id vl 0]"
       
    65 | "rec_listsum2 vl (Suc n) = CN rec_add [rec_listsum2 vl n, Id vl n]"
       
    66 
       
    67 lemma listsum2_lemma [simp]: 
       
    68   "length xs = vl \<Longrightarrow> rec_eval (rec_listsum2 vl n) xs = Listsum2 xs n"
       
    69 by (induct n) (simp_all)
       
    70 
       
    71 text {*
       
    72   @{text "Strt"} corresponds to the @{text "strt"} function on page 90 of the 
       
    73   B book, but this definition generalises the original one to deal with multiple 
       
    74   input arguments.
       
    75   *}
       
    76 fun Strt' :: "nat list \<Rightarrow> nat \<Rightarrow> nat"
       
    77   where
       
    78   "Strt' xs 0 = 0"
       
    79 | "Strt' xs (Suc n) = (let dbound = Listsum2 xs n + n 
       
    80                        in Strt' xs n + (2 ^ (xs ! n + dbound) - 2 ^ dbound))"
       
    81 
       
    82 fun Strt :: "nat list \<Rightarrow> nat"
       
    83   where
       
    84   "Strt xs = (let ys = map Suc xs in Strt' ys (length ys))"
       
    85 
       
    86 fun rec_strt' :: "nat \<Rightarrow> nat \<Rightarrow> recf"
       
    87   where
       
    88   "rec_strt' xs 0 = Z"
       
    89 | "rec_strt' xs (Suc n) = 
       
    90       (let dbound = CN rec_add [rec_listsum2 xs n, constn n] in
       
    91        let t1 = CN rec_power [constn 2, dbound] in
       
    92        let t2 = CN rec_power [constn 2, CN rec_add [Id xs n, dbound]] in
       
    93        CN rec_add [rec_strt' xs n, CN rec_minus [t2, t1]])"
       
    94 
       
    95 fun rec_map :: "recf \<Rightarrow> nat \<Rightarrow> recf list"
       
    96   where
       
    97   "rec_map rf vl = map (\<lambda>i. CN rf [Id vl i]) [0..<vl]"
       
    98 
       
    99 fun rec_strt :: "nat \<Rightarrow> recf"
       
   100   where
       
   101   "rec_strt xs = CN (rec_strt' xs xs) (rec_map S xs)"
       
   102 
       
   103 lemma strt'_lemma [simp]:
       
   104   "length xs = vl \<Longrightarrow> rec_eval (rec_strt' vl n) xs = Strt' xs n"
       
   105 by (induct n) (simp_all add: Let_def)
       
   106 
       
   107 
       
   108 lemma map_suc:
       
   109   "map (\<lambda>x. Suc (xs ! x)) [0..<length xs] = map Suc xs"
       
   110 proof -
       
   111   have "Suc \<circ> (\<lambda>x. xs ! x) = (\<lambda>x. Suc (xs ! x))" by (simp add: comp_def)
       
   112   then have "map (\<lambda>x. Suc (xs ! x)) [0..<length xs] = map (Suc \<circ> (\<lambda>x. xs ! x)) [0..<length xs]" by simp
       
   113   also have "... = map Suc (map (\<lambda>x. xs ! x) [0..<length xs])" by simp
       
   114   also have "... = map Suc xs" by (simp add: map_nth)
       
   115   finally show "map (\<lambda>x. Suc (xs ! x)) [0..<length xs] = map Suc xs" .
       
   116 qed
       
   117 
       
   118 lemma strt_lemma [simp]: 
       
   119   "length xs = vl \<Longrightarrow> rec_eval (rec_strt vl) xs = Strt xs"
       
   120 by (simp add: comp_def map_suc[symmetric])
       
   121 
       
   122 
       
   123 text {* The @{text "Scan"} function on page 90 of B book. *}
       
   124 fun Scan :: "nat \<Rightarrow> nat"
       
   125   where
       
   126   "Scan r = r mod 2"
       
   127 
       
   128 definition 
       
   129   "rec_scan = CN rec_rem [Id 1 0, constn 2]"
       
   130 
       
   131 lemma scan_lemma [simp]: 
       
   132   "rec_eval rec_scan [r] = r mod 2"
       
   133 by(simp add: rec_scan_def)
       
   134 
       
   135 text {* The @{text Newleft} and @{text Newright} functions on page 91 of B book. *}
       
   136 
       
   137 fun Newleft :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   138   where
       
   139   "Newleft p r a = (if a = 0 \<or> a = 1 then p 
       
   140                     else if a = 2 then p div 2
       
   141                     else if a = 3 then 2 * p + r mod 2
       
   142                     else p)"
       
   143 
       
   144 fun Newright :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   145   where
       
   146   "Newright p r a  = (if a = 0 then r - Scan r
       
   147                       else if a = 1 then r + 1 - Scan r
       
   148                       else if a = 2 then 2 * r + p mod 2
       
   149                       else if a = 3 then r div 2
       
   150                       else r)"
       
   151 
       
   152 definition
       
   153     "rec_newleft =
       
   154        (let cond1 = CN rec_disj [CN rec_eq [Id 3 2, Z], CN rec_eq [Id 3 2, constn 1]] in
       
   155         let cond2 = CN rec_eq [Id 3 2, constn 2] in
       
   156         let cond3 = CN rec_eq [Id 3 2, constn 3] in
       
   157         let case3 = CN rec_add [CN rec_mult [constn 2, Id 3 0], 
       
   158                                 CN rec_rem [Id 3 1, constn 2]] in
       
   159         CN rec_if [cond1, Id 3 0, 
       
   160           CN rec_if [cond2, CN rec_quo [Id 3 0, constn 2],
       
   161             CN rec_if [cond3, case3, Id 3 0]]])"
       
   162 
       
   163 definition
       
   164     "rec_newright =
       
   165        (let condn = \<lambda>n. CN rec_eq [Id 3 2, constn n] in
       
   166         let case0 = CN rec_minus [Id 3 1, CN rec_scan [Id 3 1]] in
       
   167         let case1 = CN rec_minus [CN rec_add [Id 3 1, constn 1], CN rec_scan [Id 3 1]] in
       
   168         let case2 = CN rec_add [CN rec_mult [constn 2, Id 3 1],                     
       
   169                                 CN rec_rem [Id 3 0, constn 2]] in
       
   170         let case3 = CN rec_quo [Id 2 1, constn 2] in
       
   171         CN rec_if [condn 0, case0, 
       
   172           CN rec_if [condn 1, case1,
       
   173             CN rec_if [condn 2, case2,
       
   174               CN rec_if [condn 3, case3, Id 3 1]]]])"
       
   175 
       
   176 lemma newleft_lemma [simp]:
       
   177   "rec_eval rec_newleft [p, r, a] = Newleft p r a"
       
   178 by (simp add: rec_newleft_def Let_def)
       
   179 
       
   180 lemma newright_lemma [simp]:
       
   181   "rec_eval rec_newright [p, r, a] = Newright p r a"
       
   182 by (simp add: rec_newright_def Let_def)
       
   183 
       
   184 text {*
       
   185   The @{text "Actn"} function given on page 92 of B book, which is used to 
       
   186   fetch Turing Machine intructions. In @{text "Actn m q r"}, @{text "m"} is 
       
   187   the Goedel coding of a Turing Machine, @{text "q"} is the current state of 
       
   188   Turing Machine, @{text "r"} is the right number of Turing Machine tape.
       
   189   *}
       
   190 fun Actn :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   191   where
       
   192   "Actn m q r = (if q \<noteq> 0 then Entry m (4 * (q - 1) + 2 * Scan r) else 4)"
       
   193 
       
   194 definition 
       
   195   "rec_actn = (let add1 = CN rec_mult [constn 4, CN rec_pred [Id 3 1]] in
       
   196                let add2 = CN rec_mult [constn 2, CN rec_scan [Id 3 2]] in
       
   197                let entry = CN rec_entry [Id 3 0, CN rec_add [add1, add2]]
       
   198                in CN rec_if [Id 3 1, entry, constn 4])"
       
   199 
       
   200 lemma actn_lemma [simp]:
       
   201   "rec_eval rec_actn [m, q, r] = Actn m q r"
       
   202 by (simp add: rec_actn_def)
       
   203 
       
   204 fun Newstat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   205   where
       
   206   "Newstat m q r = (if q \<noteq> 0 then Entry m (4 * (q - 1) + 2 * Scan r + 1) else 0)"
       
   207 
       
   208 definition rec_newstat :: "recf"
       
   209   where
       
   210   "rec_newstat = (let add1 = CN rec_mult [constn 4, CN rec_pred [Id 3 1]] in
       
   211                   let add2 = CN S [CN rec_mult [constn 2, CN rec_scan [Id 3 2]]] in
       
   212                   let entry = CN rec_entry [Id 3 0, CN rec_add [add1, add2]]
       
   213                   in CN rec_if [Id 3 1, entry, Z])"
       
   214 
       
   215 lemma newstat_lemma [simp]: 
       
   216   "rec_eval rec_newstat [m, q, r] = Newstat m q r"
       
   217 by (simp add: rec_newstat_def)
       
   218 
       
   219 
       
   220 fun Trpl :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   221   where
       
   222   "Trpl p q r = (Pi 0) ^ p * (Pi 1) ^ q * (Pi 2) ^ r"
       
   223 
       
   224 definition 
       
   225   "rec_trpl = CN rec_mult [CN rec_mult 
       
   226        [CN rec_power [constn (Pi 0), Id 3 0], 
       
   227         CN rec_power [constn (Pi 1), Id 3 1]],
       
   228         CN rec_power [constn (Pi 2), Id 3 2]]"
       
   229 
       
   230 lemma trpl_lemma [simp]: 
       
   231   "rec_eval rec_trpl [p, q, r] = Trpl p q r"
       
   232 by (simp add: rec_trpl_def)
       
   233 
       
   234 
       
   235 
       
   236 fun Left where
       
   237   "Left c = Lo c (Pi 0)"
       
   238 
       
   239 definition
       
   240   "rec_left = CN rec_lo [Id 1 0, constn (Pi 0)]"
       
   241 
       
   242 lemma left_lemma [simp]:
       
   243   "rec_eval rec_left [c] = Left c" 
       
   244 by(simp add: rec_left_def)
       
   245 
       
   246 fun Right where
       
   247   "Right c = Lo c (Pi 2)"
       
   248 
       
   249 definition 
       
   250   "rec_right = CN rec_lo [Id 1 0, constn (Pi 2)]"
       
   251 
       
   252 lemma right_lemma [simp]:
       
   253   "rec_eval rec_right [c] = Right c" 
       
   254 by(simp add: rec_right_def)
       
   255 
       
   256 fun Stat where
       
   257   "Stat c = Lo c (Pi 1)"
       
   258 
       
   259 definition 
       
   260   "rec_stat = CN rec_lo [Id 1 0, constn (Pi 1)]"
       
   261 
       
   262 lemma stat_lemma [simp]:
       
   263   "rec_eval rec_stat [c] = Stat c" 
       
   264 by(simp add: rec_stat_def)
       
   265 
       
   266 fun Inpt :: "nat \<Rightarrow> nat list \<Rightarrow> nat"
       
   267   where
       
   268   "Inpt m xs = Trpl 0 1 (Strt xs)"
       
   269 
       
   270 fun Newconf :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
   271   where
       
   272   "Newconf m c = Trpl (Newleft (Left c) (Right c) (Actn m (Stat c) (Right c)))
       
   273                       (Newstat m (Stat c) (Right c)) 
       
   274                       (Newright (Left c) (Right c) (Actn m (Stat c) (Right c)))"
       
   275 
       
   276 definition 
       
   277   "rec_newconf = (let act = CN rec_actn [Id 2 0, CN rec_stat [Id 2 1], CN rec_right [Id 2 1]] in
       
   278                   let left = CN rec_left [Id 2 1] in
       
   279                   let right = CN rec_right [Id 2 1] in
       
   280                   let stat = CN rec_stat [Id 2 1] in
       
   281                   let one = CN rec_newleft [left, right, act] in
       
   282                   let two = CN rec_newstat [Id 2 0, stat, right] in
       
   283                   let three = CN rec_newright [left, right, act]
       
   284                   in CN rec_trpl [one, two, three])" 
       
   285 
       
   286 lemma newconf_lemma [simp]: 
       
   287   "rec_eval rec_newconf [m, c] = Newconf m c"
       
   288 by (simp add: rec_newconf_def Let_def)
       
   289 
       
   290 text {*
       
   291   @{text "Conf k m r"} computes the TM configuration after @{text "k"} steps of execution
       
   292   of TM coded as @{text "m"} starting from the initial configuration where the left 
       
   293   number equals @{text "0"}, right number equals @{text "r"}. 
       
   294   *}
       
   295 fun Conf :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   296   where
       
   297   "Conf 0 m r  = Trpl 0 1 r"
       
   298 | "Conf (Suc k) m r = Newconf m (Conf k m r)"
       
   299 
       
   300 definition 
       
   301   "rec_conf = PR (CN rec_trpl [constn 0, constn 1, Id 2 1])
       
   302                  (CN rec_newconf [Id 4 2 , Id 4 1])"
       
   303 
       
   304 lemma conf_lemma [simp]: 
       
   305   "rec_eval rec_conf [k, m, r] = Conf k m r"
       
   306 by(induct k) (simp_all add: rec_conf_def)
       
   307 
       
   308 
       
   309 text {*
       
   310   @{text "Nstd c"} returns true if the configuration coded 
       
   311   by @{text "c"} is not a stardard final configuration.
       
   312   *}
       
   313 fun Nstd :: "nat \<Rightarrow> bool"
       
   314   where
       
   315   "Nstd c = (Stat c \<noteq> 0 \<or> 
       
   316              Left c \<noteq> 0 \<or> 
       
   317              Right c \<noteq> 2 ^ (Lg (Suc (Right c)) 2) - 1 \<or> 
       
   318              Right c = 0)"
       
   319 
       
   320 definition 
       
   321   "rec_nstd = (let disj1 = CN rec_noteq [rec_stat, constn 0] in
       
   322                let disj2 = CN rec_noteq [rec_left, constn 0] in
       
   323                let rhs = CN rec_pred [CN rec_power [constn 2, CN rec_lg [CN S [rec_right], constn 2]]] in
       
   324                let disj3 = CN rec_noteq [rec_right, rhs] in
       
   325                let disj4 = CN rec_eq [rec_right, constn 0] in
       
   326                CN rec_disj [CN rec_disj [CN rec_disj [disj1, disj2], disj3], disj4])"
       
   327 
       
   328 lemma nstd_lemma [simp]:
       
   329   "rec_eval rec_nstd [c] = (if Nstd c then 1 else 0)"
       
   330 by(simp add: rec_nstd_def)
       
   331 
       
   332 
       
   333 text{* 
       
   334   @{text "Nostop t m r"} means that afer @{text "t"} steps of 
       
   335   execution, the TM coded by @{text "m"} is not at a stardard 
       
   336   final configuration.
       
   337   *}
       
   338 fun Nostop :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
       
   339   where
       
   340   "Nostop t m r = Nstd (Conf t m r)"
       
   341 
       
   342 definition 
       
   343   "rec_nostop = CN rec_nstd [rec_conf]"
       
   344 
       
   345 lemma nostop_lemma [simp]:
       
   346   "rec_eval rec_nostop [t, m, r] = (if Nostop t m r then 1 else 0)" 
       
   347 by (simp add: rec_nostop_def)
       
   348 
       
   349 
       
   350 fun Value where
       
   351   "Value x = (Lg (Suc x) 2) - 1"
       
   352 
       
   353 definition 
       
   354   "rec_value = CN rec_pred [CN rec_lg [S, constn 2]]"
       
   355 
       
   356 lemma value_lemma [simp]:
       
   357   "rec_eval rec_value [x] = Value x"
       
   358 by (simp add: rec_value_def)
       
   359 
       
   360 text{*
       
   361   @{text "rec_halt"} is the recursive function calculating the steps a TM needs to execute before
       
   362   to reach a stardard final configuration. This recursive function is the only one
       
   363   using @{text "Mn"} combinator. So it is the only non-primitive recursive function 
       
   364   needs to be used in the construction of the universal function @{text "rec_uf"}.
       
   365   *}
       
   366 
       
   367 definition 
       
   368   "rec_halt = MN rec_nostop" 
       
   369 
       
   370 
       
   371 definition 
       
   372   "rec_uf = CN rec_value [CN rec_right [CN rec_conf [rec_halt, Id 2 0, Id 2 1]]]"
       
   373 
       
   374 end
       
   375 
       
   376 
       
   377 (*
       
   378 
       
   379 
       
   380 
       
   381 fun mtest where
       
   382   "mtest R 0 = if R 0 then 0 else 1"
       
   383 | "mtest R (Suc n) = (if R n then mtest R n else (Suc n))"
       
   384 
       
   385 
       
   386 lemma 
       
   387   "rec_eval (rec_maxr2 f) [x, y1, y2] = XXX"
       
   388 apply(simp only: rec_maxr2_def)
       
   389 apply(case_tac x)
       
   390 apply(clarify)
       
   391 apply(subst rec_eval.simps)
       
   392 apply(simp only: constn_lemma)
       
   393 defer
       
   394 apply(clarify)
       
   395 apply(subst rec_eval.simps)
       
   396 apply(simp only: rec_maxr2_def[symmetric])
       
   397 apply(subst rec_eval.simps)
       
   398 apply(simp only: map.simps nth)
       
   399 apply(subst rec_eval.simps)
       
   400 apply(simp only: map.simps nth)
       
   401 apply(subst rec_eval.simps)
       
   402 apply(simp only: map.simps nth)
       
   403 apply(subst rec_eval.simps)
       
   404 apply(simp only: map.simps nth)
       
   405 apply(subst rec_eval.simps)
       
   406 apply(simp only: map.simps nth)
       
   407 apply(subst rec_eval.simps)
       
   408 apply(simp only: map.simps nth)
       
   409 
       
   410 
       
   411 definition
       
   412   "rec_minr2 f = rec_sigma2 (rec_accum2 (CN rec_not [f]))"
       
   413 
       
   414 definition
       
   415   "rec_maxr2 f = rec_sigma2 (CN rec_sign [CN (rec_sigma2 f) [S]])"
       
   416 
       
   417 definition Minr :: "(nat \<Rightarrow> nat list \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> nat"
       
   418   where "Minr R x ys = Min ({z | z. z \<le> x \<and> R z ys} \<union> {Suc x})"
       
   419 
       
   420 definition Maxr :: "(nat \<Rightarrow> nat list \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> nat"
       
   421   where "Maxr R x ys = Max ({z | z. z \<le> x \<and> R z ys} \<union> {0})"
       
   422 
       
   423 lemma rec_minr2_le_Suc:
       
   424   "rec_eval (rec_minr2 f) [x, y1, y2] \<le> Suc x"
       
   425 apply(simp add: rec_minr2_def)
       
   426 apply(auto intro!: setsum_one_le setprod_one_le)
       
   427 done
       
   428 
       
   429 lemma rec_minr2_eq_Suc:
       
   430   assumes "\<forall>z \<le> x. rec_eval f [z, y1, y2] = 0"
       
   431   shows "rec_eval (rec_minr2 f) [x, y1, y2] = Suc x"
       
   432 using assms by (simp add: rec_minr2_def)
       
   433 
       
   434 lemma rec_minr2_le:
       
   435   assumes h1: "y \<le> x" 
       
   436   and     h2: "0 < rec_eval f [y, y1, y2]" 
       
   437   shows "rec_eval (rec_minr2 f) [x, y1, y2] \<le> y"
       
   438 apply(simp add: rec_minr2_def)
       
   439 apply(subst setsum_cut_off_le[OF h1])
       
   440 using h2 apply(auto)
       
   441 apply(auto intro!: setsum_one_less setprod_one_le)
       
   442 done
       
   443 
       
   444 (* ??? *)
       
   445 lemma setsum_eq_one_le2:
       
   446   fixes n::nat
       
   447   assumes "\<forall>i \<le> n. f i \<le> 1" 
       
   448   shows "((\<Sum>i \<le> n. f i) \<ge> Suc n) \<Longrightarrow> (\<forall>i \<le> n. f i = 1)"  
       
   449 using assms
       
   450 apply(induct n)
       
   451 apply(simp add: One_nat_def)
       
   452 apply(simp)
       
   453 apply(auto simp add: One_nat_def)
       
   454 apply(drule_tac x="Suc n" in spec)
       
   455 apply(auto)
       
   456 by (metis le_Suc_eq)
       
   457 
       
   458 
       
   459 lemma rec_min2_not:
       
   460   assumes "rec_eval (rec_minr2 f) [x, y1, y2] = Suc x"
       
   461   shows "\<forall>z \<le> x. rec_eval f [z, y1, y2] = 0"
       
   462 using assms
       
   463 apply(simp add: rec_minr2_def)
       
   464 apply(subgoal_tac "\<forall>i \<le> x. (\<Prod>z\<le>i. if rec_eval f [z, y1, y2] = 0 then 1 else 0) = (1::nat)")
       
   465 apply(simp)
       
   466 apply (metis atMost_iff le_refl zero_neq_one)
       
   467 apply(rule setsum_eq_one_le2)
       
   468 apply(auto)
       
   469 apply(rule setprod_one_le)
       
   470 apply(auto)
       
   471 done
       
   472 
       
   473 lemma disjCI2:
       
   474   assumes "~P ==> Q" shows "P|Q"
       
   475 apply (rule classical)
       
   476 apply (iprover intro: assms disjI1 disjI2 notI elim: notE)
       
   477 done
       
   478 
       
   479 lemma minr_lemma [simp]:
       
   480 shows "rec_eval (rec_minr2 f) [x, y1, y2] = (LEAST z.  (z \<le> x \<and> 0 < rec_eval f [z, y1, y2]) \<or> z = Suc x)"
       
   481 apply(induct x)
       
   482 apply(rule Least_equality[symmetric])
       
   483 apply(simp add: rec_minr2_def)
       
   484 apply(erule disjE)
       
   485 apply(rule rec_minr2_le)
       
   486 apply(auto)[2]
       
   487 apply(simp)
       
   488 apply(rule rec_minr2_le_Suc)
       
   489 apply(simp)
       
   490 
       
   491 apply(rule rec_minr2_le)
       
   492 
       
   493 
       
   494 apply(rule rec_minr2_le_Suc)
       
   495 apply(rule disjCI)
       
   496 apply(simp add: rec_minr2_def)
       
   497 
       
   498 apply(ru le setsum_one_less)
       
   499 apply(clarify)
       
   500 apply(rule setprod_one_le)
       
   501 apply(auto)[1]
       
   502 apply(simp)
       
   503 apply(rule setsum_one_le)
       
   504 apply(clarify)
       
   505 apply(rule setprod_one_le)
       
   506 apply(auto)[1]
       
   507 thm disj_CE
       
   508 apply(auto)
       
   509 
       
   510 lemma minr_lemma:
       
   511 shows "rec_eval (rec_minr2 f) [x, y1, y2] = Minr (\<lambda>x xs. (0 < rec_eval f (x #xs))) x [y1, y2]"
       
   512 apply(simp only: Minr_def)
       
   513 apply(rule sym)
       
   514 apply(rule Min_eqI)
       
   515 apply(auto)[1]
       
   516 apply(simp)
       
   517 apply(erule disjE)
       
   518 apply(simp)
       
   519 apply(rule rec_minr2_le_Suc)
       
   520 apply(rule rec_minr2_le)
       
   521 apply(auto)[2]
       
   522 apply(simp)
       
   523 apply(induct x)
       
   524 apply(simp add: rec_minr2_def)
       
   525 apply(
       
   526 apply(rule disjCI)
       
   527 apply(rule rec_minr2_eq_Suc)
       
   528 apply(simp)
       
   529 apply(auto)
       
   530 
       
   531 apply(rule setsum_one_le)
       
   532 apply(auto)[1]
       
   533 apply(rule setprod_one_le)
       
   534 apply(auto)[1]
       
   535 apply(subst setsum_cut_off_le)
       
   536 apply(auto)[2]
       
   537 apply(rule setsum_one_less)
       
   538 apply(auto)[1]
       
   539 apply(rule setprod_one_le)
       
   540 apply(auto)[1]
       
   541 apply(simp)
       
   542 thm setsum_eq_one_le
       
   543 apply(subgoal_tac "(\<forall>z\<le>x. (\<Prod>z\<le>z. if rec_eval f [z, y1, y2] = (0::nat) then 1 else 0) > (0::nat)) \<or>
       
   544                    (\<not> (\<forall>z\<le>x. (\<Prod>z\<le>z. if rec_eval f [z, y1, y2] = (0::nat) then 1 else 0) > (0::nat)))")
       
   545 prefer 2
       
   546 apply(auto)[1]
       
   547 apply(erule disjE)
       
   548 apply(rule disjI1)
       
   549 apply(rule setsum_eq_one_le)
       
   550 apply(simp)
       
   551 apply(rule disjI2)
       
   552 apply(simp)
       
   553 apply(clarify)
       
   554 apply(subgoal_tac "\<exists>l. l = (LEAST z. 0 < rec_eval f [z, y1, y2])")
       
   555 defer
       
   556 apply metis
       
   557 apply(erule exE)
       
   558 apply(subgoal_tac "l \<le> x")
       
   559 defer
       
   560 apply (metis not_leE not_less_Least order_trans)
       
   561 apply(subst setsum_least_eq)
       
   562 apply(rotate_tac 4)
       
   563 apply(assumption)
       
   564 apply(auto)[1]
       
   565 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y1, y2])")
       
   566 prefer 2
       
   567 apply(auto)[1]
       
   568 apply(rotate_tac 5)
       
   569 apply(drule not_less_Least)
       
   570 apply(auto)[1]
       
   571 apply(auto)
       
   572 apply(rule_tac x="(LEAST z. 0 < rec_eval f [z, y1, y2])" in exI)
       
   573 apply(simp)
       
   574 apply (metis LeastI_ex)
       
   575 apply(subst setsum_least_eq)
       
   576 apply(rotate_tac 3)
       
   577 apply(assumption)
       
   578 apply(simp)
       
   579 apply(auto)[1]
       
   580 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y1, y2])")
       
   581 prefer 2
       
   582 apply(auto)[1]
       
   583 apply (metis neq0_conv not_less_Least)
       
   584 apply(auto)[1]
       
   585 apply (metis (mono_tags) LeastI_ex)
       
   586 by (metis LeastI_ex)
       
   587 
       
   588 lemma minr_lemma:
       
   589 shows "rec_eval (rec_minr2 f) [x, y1, y2] = Minr (\<lambda>x xs. (0 < rec_eval f (x #xs))) x [y1, y2]"
       
   590 apply(simp only: Minr_def rec_minr2_def)
       
   591 apply(simp)
       
   592 apply(rule sym)
       
   593 apply(rule Min_eqI)
       
   594 apply(auto)[1]
       
   595 apply(simp)
       
   596 apply(erule disjE)
       
   597 apply(simp)
       
   598 apply(rule setsum_one_le)
       
   599 apply(auto)[1]
       
   600 apply(rule setprod_one_le)
       
   601 apply(auto)[1]
       
   602 apply(subst setsum_cut_off_le)
       
   603 apply(auto)[2]
       
   604 apply(rule setsum_one_less)
       
   605 apply(auto)[1]
       
   606 apply(rule setprod_one_le)
       
   607 apply(auto)[1]
       
   608 apply(simp)
       
   609 thm setsum_eq_one_le
       
   610 apply(subgoal_tac "(\<forall>z\<le>x. (\<Prod>z\<le>z. if rec_eval f [z, y1, y2] = (0::nat) then 1 else 0) > (0::nat)) \<or>
       
   611                    (\<not> (\<forall>z\<le>x. (\<Prod>z\<le>z. if rec_eval f [z, y1, y2] = (0::nat) then 1 else 0) > (0::nat)))")
       
   612 prefer 2
       
   613 apply(auto)[1]
       
   614 apply(erule disjE)
       
   615 apply(rule disjI1)
       
   616 apply(rule setsum_eq_one_le)
       
   617 apply(simp)
       
   618 apply(rule disjI2)
       
   619 apply(simp)
       
   620 apply(clarify)
       
   621 apply(subgoal_tac "\<exists>l. l = (LEAST z. 0 < rec_eval f [z, y1, y2])")
       
   622 defer
       
   623 apply metis
       
   624 apply(erule exE)
       
   625 apply(subgoal_tac "l \<le> x")
       
   626 defer
       
   627 apply (metis not_leE not_less_Least order_trans)
       
   628 apply(subst setsum_least_eq)
       
   629 apply(rotate_tac 4)
       
   630 apply(assumption)
       
   631 apply(auto)[1]
       
   632 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y1, y2])")
       
   633 prefer 2
       
   634 apply(auto)[1]
       
   635 apply(rotate_tac 5)
       
   636 apply(drule not_less_Least)
       
   637 apply(auto)[1]
       
   638 apply(auto)
       
   639 apply(rule_tac x="(LEAST z. 0 < rec_eval f [z, y1, y2])" in exI)
       
   640 apply(simp)
       
   641 apply (metis LeastI_ex)
       
   642 apply(subst setsum_least_eq)
       
   643 apply(rotate_tac 3)
       
   644 apply(assumption)
       
   645 apply(simp)
       
   646 apply(auto)[1]
       
   647 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y1, y2])")
       
   648 prefer 2
       
   649 apply(auto)[1]
       
   650 apply (metis neq0_conv not_less_Least)
       
   651 apply(auto)[1]
       
   652 apply (metis (mono_tags) LeastI_ex)
       
   653 by (metis LeastI_ex)
       
   654 
       
   655 lemma disjCI2:
       
   656   assumes "~P ==> Q" shows "P|Q"
       
   657 apply (rule classical)
       
   658 apply (iprover intro: assms disjI1 disjI2 notI elim: notE)
       
   659 done
       
   660 
       
   661 
       
   662 lemma minr_lemma [simp]:
       
   663 shows "rec_eval (rec_minr2 f) [x, y1, y2] = (LEAST z.  (z \<le> x \<and> 0 < rec_eval f [z, y1, y2]) \<or> z = Suc x)"
       
   664 (*apply(simp add: rec_minr2_def)*)
       
   665 apply(rule Least_equality[symmetric])
       
   666 prefer 2
       
   667 apply(erule disjE)
       
   668 apply(rule rec_minr2_le)
       
   669 apply(auto)[2]
       
   670 apply(clarify)
       
   671 apply(rule rec_minr2_le_Suc)
       
   672 apply(rule disjCI)
       
   673 apply(simp add: rec_minr2_def)
       
   674 
       
   675 apply(ru le setsum_one_less)
       
   676 apply(clarify)
       
   677 apply(rule setprod_one_le)
       
   678 apply(auto)[1]
       
   679 apply(simp)
       
   680 apply(rule setsum_one_le)
       
   681 apply(clarify)
       
   682 apply(rule setprod_one_le)
       
   683 apply(auto)[1]
       
   684 thm disj_CE
       
   685 apply(auto)
       
   686 apply(auto)
       
   687 prefer 2
       
   688 apply(rule le_tran
       
   689 
       
   690 apply(rule le_trans)
       
   691 apply(simp)
       
   692 defer
       
   693 apply(auto)
       
   694 apply(subst setsum_cut_off_le)
       
   695 
       
   696 
       
   697 lemma 
       
   698   "Minr R x ys = (LEAST z. (R z ys \<or> z = Suc x))" 
       
   699 apply(simp add: Minr_def)
       
   700 apply(rule Min_eqI)
       
   701 apply(auto)[1]
       
   702 apply(simp)
       
   703 apply(rule Least_le)
       
   704 apply(auto)[1]
       
   705 apply(rule LeastI2_wellorder)
       
   706 apply(auto)
       
   707 done
       
   708 
       
   709 definition (in ord)
       
   710   Great :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "GREAT " 10) where
       
   711   "Great P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> y \<le> x))"
       
   712 
       
   713 (*
       
   714 lemma Great_equality:
       
   715   assumes "P x"
       
   716     and "\<And>y. P y \<Longrightarrow> y \<le> x"
       
   717   shows "Great P = x"
       
   718 unfolding Great_def 
       
   719 apply(rule the_equality)
       
   720 apply(blast intro: assms)
       
   721 *)
       
   722 
       
   723 
       
   724 
       
   725 lemma 
       
   726   "Maxr R x ys = (GREAT z. (R z ys \<or> z = 0))" 
       
   727 apply(simp add: Maxr_def)
       
   728 apply(rule Max_eqI)
       
   729 apply(auto)[1]
       
   730 apply(simp)
       
   731 thm Least_le Greatest_le
       
   732 oops
       
   733 
       
   734 lemma
       
   735   "Maxr R x ys = x - Minr (\<lambda>z. R (x - z)) x ys"
       
   736 apply(simp add: Maxr_def Minr_def)
       
   737 apply(rule Max_eqI)
       
   738 apply(auto)[1]
       
   739 apply(simp)
       
   740 apply(erule disjE)
       
   741 apply(simp)
       
   742 apply(auto)[1]
       
   743 defer
       
   744 apply(simp)
       
   745 apply(auto)[1]
       
   746 thm Min_insert
       
   747 defer
       
   748 oops
       
   749 
       
   750 
       
   751 
       
   752 definition quo :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
   753   where
       
   754   "quo x y = (if y = 0 then 0 else x div y)"
       
   755 
       
   756 
       
   757 definition 
       
   758   "rec_quo = CN rec_mult [CN rec_sign [Id 2 1],  
       
   759       CN (rec_minr2 (CN rec_less [Id 3 1, CN rec_mult [CN S [Id 3 0], Id 3 2]])) 
       
   760                 [Id 2 0, Id 2 0, Id 2 1]]"
       
   761 
       
   762 lemma div_lemma [simp]:
       
   763   "rec_eval rec_quo [x, y] = quo x y"
       
   764 apply(simp add: rec_quo_def quo_def)
       
   765 apply(rule impI)
       
   766 apply(rule Min_eqI)
       
   767 apply(auto)[1]
       
   768 apply(simp)
       
   769 apply(erule disjE)
       
   770 apply(simp)
       
   771 apply(auto)[1]
       
   772 apply (metis div_le_dividend le_SucI)
       
   773 defer
       
   774 apply(simp)
       
   775 apply(auto)[1]
       
   776 apply (metis mult_Suc_right nat_mult_commute split_div_lemma)
       
   777 apply(auto)[1]
       
   778 
       
   779 apply (smt div_le_dividend fst_divmod_nat)
       
   780 apply(simp add: quo_def)
       
   781 apply(auto)[1]
       
   782 
       
   783 apply(auto)
       
   784 
       
   785 fun Minr :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   786   where "Minr R x y = (let setx = {z | z. z \<le> x \<and> R [z, y]} in 
       
   787                         if (setx = {}) then (Suc x) else (Min setx))"
       
   788 
       
   789 definition
       
   790   "rec_minr f = rec_sigma1 (rec_accum1 (CN rec_not [f]))"
       
   791 
       
   792 lemma minr_lemma [simp]:
       
   793 shows "rec_eval (rec_minr f) [x, y] = Minr (\<lambda>xs. (0 < rec_eval f xs)) x y"
       
   794 apply(simp only: rec_minr_def)
       
   795 apply(simp only: sigma1_lemma)
       
   796 apply(simp only: accum1_lemma)
       
   797 apply(subst rec_eval.simps)
       
   798 apply(simp only: map.simps nth)
       
   799 apply(simp only: Minr.simps Let_def)
       
   800 apply(auto simp del: not_lemma)
       
   801 apply(simp)
       
   802 apply(simp only: not_lemma sign_lemma)
       
   803 apply(rule sym)
       
   804 apply(rule Min_eqI)
       
   805 apply(auto)[1]
       
   806 apply(simp)
       
   807 apply(subst setsum_cut_off_le[where m="ya"])
       
   808 apply(simp)
       
   809 apply(simp)
       
   810 apply(metis Icc_subset_Ici_iff atLeast_def in_mono le_refl mem_Collect_eq)
       
   811 apply(rule setsum_one_less)
       
   812 apply(default)
       
   813 apply(rule impI)
       
   814 apply(rule setprod_one_le)
       
   815 apply(auto split: if_splits)[1]
       
   816 apply(simp)
       
   817 apply(rule conjI)
       
   818 apply(subst setsum_cut_off_le[where m="xa"])
       
   819 apply(simp)
       
   820 apply(simp)
       
   821 apply (metis Icc_subset_Ici_iff atLeast_def in_mono le_refl mem_Collect_eq)
       
   822 apply(rule le_trans)
       
   823 apply(rule setsum_one_less)
       
   824 apply(default)
       
   825 apply(rule impI)
       
   826 apply(rule setprod_one_le)
       
   827 apply(auto split: if_splits)[1]
       
   828 apply(simp)
       
   829 apply(subgoal_tac "\<exists>l. l = (LEAST z. 0 < rec_eval f [z, y])")
       
   830 defer
       
   831 apply metis
       
   832 apply(erule exE)
       
   833 apply(subgoal_tac "l \<le> x")
       
   834 defer
       
   835 apply (metis not_leE not_less_Least order_trans)
       
   836 apply(subst setsum_least_eq)
       
   837 apply(rotate_tac 3)
       
   838 apply(assumption)
       
   839 prefer 3
       
   840 apply (metis LeastI_ex)
       
   841 apply(auto)[1]
       
   842 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y])")
       
   843 prefer 2
       
   844 apply(auto)[1]
       
   845 apply(rotate_tac 5)
       
   846 apply(drule not_less_Least)
       
   847 apply(auto)[1]
       
   848 apply(auto)
       
   849 by (metis (mono_tags) LeastI_ex)
       
   850 
       
   851 
       
   852 fun Minr2 :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
       
   853   where "Minr2 R x y = (let setx = {z | z. z \<le> x \<and> R [z, y]} in 
       
   854                         Min (setx \<union> {Suc x}))"
       
   855 
       
   856 lemma Minr2_Minr: 
       
   857   "Minr2 R x y = Minr R x y"
       
   858 apply(auto)
       
   859 apply (metis (lifting, no_types) Min_singleton empty_Collect_eq)
       
   860 apply(rule min_absorb2)
       
   861 apply(subst Min_le_iff)
       
   862 apply(auto)  
       
   863 done
       
   864  *)