Tests/Rec_Def.thy
changeset 213 30d81499766b
parent 212 203d50aebb1c
child 215 12f278bd67aa
equal deleted inserted replaced
212:203d50aebb1c 213:30d81499766b
     1 header {* Definition of Recursive Functions *}
     1 header {* Definition of Recursive Functions *}
     2 
     2 
     3 theory Rec_Def
     3 theory Rec_Def
     4 imports Main "~~/src/HOL/Library/Monad_Syntax"
     4 imports Main "~~/src/HOL/Library/Monad_Syntax"
     5 begin
     5 begin
     6 
       
     7 type_synonym heap = "nat \<Rightarrow> nat"
       
     8 type_synonym exception = nat
       
     9 
       
    10 datatype 'a Heap = Heap "heap \<Rightarrow> (('a + exception) * heap)"
       
    11 
       
    12 definition return
       
    13 where "return x = Heap (Pair (Inl x))"
       
    14 
       
    15 fun exec
       
    16 where "exec (Heap f) = f" 
       
    17 
       
    18 definition bind ("_ >>= _")
       
    19 where "bind f g = Heap (\<lambda>h. case (exec f h) of 
       
    20                            (Inl x, h') \<Rightarrow> exec (g x) h'
       
    21                          | (Inr exn, h') \<Rightarrow> (Inr exn, h')
       
    22                        )"
       
    23 
     6 
    24 datatype recf = 
     7 datatype recf = 
    25   Zero 
     8   Zero 
    26 | Succ 
     9 | Succ 
    27 | Id nat nat              --"Projection"
    10 | Id nat nat              --"Projection"
    28 | Cn nat recf "recf list" --"Composition"
    11 | Cn nat recf "recf list" --"Composition"
    29 | Pr nat recf recf        --"Primitive recursion"
    12 | Pr nat recf recf        --"Primitive recursion"
    30 | Mn nat recf             --"Minimisation"
    13 | Mn nat recf             --"Minimisation"
    31 
    14 
    32 partial_function (tailrec) 
    15 partial_function (option) 
    33   findzero :: "(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat"
    16   eval :: "recf \<Rightarrow> nat option \<Rightarrow> (nat list) option => nat list \<Rightarrow> nat option"
    34 where
    17 where
    35   "findzero f n = (if f n = 0 then n else findzero f (Suc n))"
    18  "eval f i gs ns = (case (i, gs, f, ns) of
       
    19                   (None, None, Zero, [n]) \<Rightarrow> Some 0
       
    20                 | (None, None, Succ, [n]) \<Rightarrow> Some (n + 1)
       
    21                 | (None, None, Id i j, ns) \<Rightarrow> if (j < i) then Some (ns ! j) else None               
       
    22                 | (None, None, Pr n f g, 0 # ns) \<Rightarrow> eval f None None ns
       
    23                 | (None, None, Pr n f g, Suc k # ns) \<Rightarrow>
       
    24                     do { r \<leftarrow> eval (Pr n f g) None None (k # ns); eval g None None (r # k # ns) }            
       
    25                 | (None, None, Mn n f, ns) \<Rightarrow> eval f (Some 0) None ns
       
    26                 | (Some n, None, f, ns) \<Rightarrow> 
       
    27                     do { r \<leftarrow> eval f None None (n # ns); 
       
    28                          if r = 0 then Some n else eval f (Some (Suc n)) None ns }
       
    29                 | (None, None, Cn n f [], ns) \<Rightarrow> eval f None None []
       
    30                 | (None, None, Cn n f (g#gs), ns) \<Rightarrow> 
       
    31                     do { r \<leftarrow> eval g None None ns; eval (Cn n f gs) None (Some [r]) ns }
       
    32                 | (None, Some rs, Cn n f [], ns) \<Rightarrow> eval f None None rs  
       
    33                 | (None, Some rs, Cn n f (g#gs), ns) \<Rightarrow> 
       
    34                     do { r \<leftarrow> eval g None None ns; eval (Cn n f gs) None (Some (r#rs)) ns }  
       
    35                 | (_, _) \<Rightarrow> None)"
    36 
    36 
    37 print_theorems
    37 abbreviation
       
    38   "eval0 f ns \<equiv> eval f None None ns"
    38 
    39 
    39 declare findzero.simps[simp del] 
    40 lemma "eval0 Zero [n] = Some 0"
    40 
    41 apply(subst eval.simps)
    41 lemma "findzero (\<lambda>n. if n = 3 then 0 else 1) 0 = 3"
    42 apply(simp)
    42 apply(simp add: findzero.simps)
       
    43 done
    43 done
    44 
    44 
    45 lemma "findzero (\<lambda>n. if n = 3 then 0 else 1) 0 \<noteq> 2"
    45 lemma "eval0 Succ [n] = Some (n + 1)"
    46 apply(simp add: findzero.simps)
    46 apply(subst eval.simps)
       
    47 apply(simp)
       
    48 done
       
    49 
       
    50 lemma "eval0 (Id i j) ns = (if (j < i) then Some (ns ! j) else None)" 
       
    51 apply(subst eval.simps)
       
    52 apply(simp)
       
    53 done
       
    54 
       
    55 lemma "eval0 (Pr n f g) (0 # ns) = eval0 f ns"
       
    56 apply(subst eval.simps)
       
    57 apply(simp)
       
    58 done
       
    59 
       
    60 lemma "eval0 (Pr n f g) (Suc k # ns) = 
       
    61   do { r \<leftarrow> eval0 (Pr n f g) (k # ns); eval0 g (r # k # ns) }" 
       
    62 apply(subst eval.simps)
       
    63 apply(simp)
    47 done
    64 done
    48 
    65 
    49 
    66 
    50 fun
       
    51   least :: "(nat \<Rightarrow> bool) \<Rightarrow> nat"
       
    52 where
       
    53   "least P = (SOME n. (P n \<and> (\<forall>m. m < n \<longrightarrow> \<not> P m)))"
       
    54 
    67 
    55 lemma [partial_function_mono]:
       
    56   "mono_option (\<lambda>eval. if \<forall>g\<in>set list. case eval (g, ba) of None \<Rightarrow> False | Some a \<Rightarrow> True
       
    57      then eval (recf, map (\<lambda>g. the (eval (g, ba))) list) else None)"
       
    58 apply(rule monotoneI)
       
    59 unfolding flat_ord_def
       
    60 apply(auto)
       
    61 oops
       
    62 
    68 
    63 partial_function (option) 
       
    64   eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat option"
       
    65 where
       
    66  "eval f ns = (case (f, ns) of
       
    67                   (Zero, [n]) \<Rightarrow> Some 0
       
    68                 | (Succ, [n]) \<Rightarrow> Some (n + 1)
       
    69                 | (Id i j, ns) \<Rightarrow> if (j < i) then Some (ns ! j) else None               
       
    70                 | (Pr n f g, 0 # ns) \<Rightarrow> eval f ns
       
    71                 | (Pr n f g, Suc k # ns) \<Rightarrow>
       
    72                     do { r \<leftarrow> eval (Pr n f g) (k # ns); eval g (r # k # ns) }            
       
    73                 | (Cn n f gs, ns) \<Rightarrow>  if (\<forall>g \<in> set gs. case (eval g ns) of None => False | _ => True)
       
    74                                       then eval f (map (\<lambda>g. the (eval g ns)) gs) else None
       
    75                 | (_, _) \<Rightarrow> None)"
       
    76 
       
    77 (*
       
    78                 | (Cn n f gs, ns) \<Rightarrow>  if (\<forall>g \<in> set gs. case (eval g ns) of None => False | _ => True)
       
    79                                       then eval f (map (\<lambda>g. the (eval g ns)) gs) else None
       
    80 *)
       
    81 (*      
       
    82                 | (Mn n f, ns) \<Rightarrow> Some (least (\<lambda>r. eval f (r # ns) = Some 0)) 
       
    83 *)
       
    84 end
    69 end