# HG changeset patch # User blanchet # Date 1467839967 -7200 # Node ID 32866eff1843cd0f10d0128f922969efaf46ad3d # Parent 9202173231471945d9b443e464c8346fe2cd16ad updated examples diff -r 920217323147 -r 32866eff1843 src/HOL/Corec_Examples/Paper_Examples.thy --- a/src/HOL/Corec_Examples/Paper_Examples.thy Wed Jul 06 22:52:10 2016 +0200 +++ b/src/HOL/Corec_Examples/Paper_Examples.thy Wed Jul 06 23:19:27 2016 +0200 @@ -3,51 +3,114 @@ Author: Andrei Popescu, TU Muenchen Copyright 2016 -Small examples from the paper. +Small examples from the paper "Friends with Benefits". *) -section \Small Examples from the Paper\ +section \Small Examples from the Paper ``Friends with Benefits''\ theory Paper_Examples -imports "~~/src/HOL/Library/BNF_Corec" +imports "~~/src/HOL/Library/BNF_Corec" "~~/src/HOL/Library/FSet" "Complex_Main" begin -subsection \Examples from the introduction\ +section \Examples from the introduction\ -codatatype 'a stream = SCons (hd: 'a) (tl: "'a stream") (infixr "\" 65) +codatatype 'a stream = SCons (shd: 'a) (stl: "'a stream") (infixr "\" 65) -corec "from" :: "nat \ nat stream" where - "from n = n \ from (n + 1)" +corec "natsFrom" :: "nat \ nat stream" where + "natsFrom n = n \ natsFrom (n + 1)" -corec (friend) addOne :: "nat stream \ nat stream" where - "addOne n = (hd n + 1) \ addOne (tl n)" +corec (friend) addOne :: "nat stream \ nat stream" +where "addOne n = (shd n + 1) \ addOne (stl n)" -corec from' :: "nat \ nat stream" where - "from' n = n \ addOne (from' n)" +corec natsFrom' :: "nat \ nat stream" where + "natsFrom' n = n \ addOne (natsFrom' n)" -subsection \Examples from Section 5\ +section \Examples from section 3\ -text \ -We curry the example functions in this section because infix syntax works only for curried -functions. -\ +text \We curry the example functions in this section because infix syntax works only for curried functions.\ corec (friend) Plus :: "nat stream \ nat stream \ nat stream" (infix "\" 67) where - "x\<^sub>1 \ x\<^sub>2 = (hd x\<^sub>1 + hd x\<^sub>2) \ (tl x\<^sub>1 \ tl x\<^sub>2)" - -corec zeros :: "nat stream" where "zeros = 0 \ zeros" + "x\<^sub>1 \ x\<^sub>2 = (shd x\<^sub>1 + shd x\<^sub>2) \ (stl x\<^sub>1 \ stl x\<^sub>2)" -corec (friend) Plus' :: "nat stream \ nat stream \ nat stream" (infix "\''" 67) where - "x\<^sub>1 \' x\<^sub>2 = hd x\<^sub>1 \ (tl (tl zeros) \' x\<^sub>2)" -corec (friend) heart :: "nat stream \ nat stream \ nat stream" (infix "\" 67) where - "x\<^sub>1 \ x\<^sub>2 = (hd x\<^sub>1 * hd x\<^sub>2) \ (x\<^sub>2 \ ((x\<^sub>1 \ ((x\<^sub>1 \ tl x\<^sub>2) \ (tl x\<^sub>1 \ x\<^sub>2)))))" - -corec spade :: "nat stream \ nat stream \ nat stream" (infix "\" 67) where - "x\<^sub>1 \ x\<^sub>2 = (hd x\<^sub>1 \ (x\<^sub>1 \ x\<^sub>2)) \ (hd x\<^sub>1 \ ((x\<^sub>1 \ tl x\<^sub>2) \ (tl x\<^sub>1 \ x\<^sub>2)))" +section \Examples from section 4\ corec collatz :: "nat \ nat stream" where "collatz n = (if even n \ n > 0 then collatz (n div 2) else n \ collatz (3 * n + 1))" +datatype 'a nelist = NEList (hd:'a) (tl:"'a list") + +primrec (transfer) postpend :: "'a list \ 'a \ 'a nelist" (infix "\" 64) where + "[] \ a = NEList a []" +|"(b # bs) \ a = NEList b (bs @ [a])" + +corec (friend) inter :: "nat stream nelist \ nat stream" where +"inter x = shd (hd x) \ inter (tl x \ stl (hd x))" + +corec (friend) inter2 :: "nat stream nelist \ nat stream" where +"inter2 x = (case hd x of n \ y \ n \ inter2 (tl x \ y))" + +corec zero :: "nat stream" where "zero = 0 \ zero" + +corec (friend) inter3 :: "nat stream nelist \ nat stream" where +"inter3 x = shd (stl zero) \ inter3 ([hd x] \ stl (hd x))" + + +section \Examples from Blanchette et al. (ICFP 2015)\ + +corec oneTwos :: "nat stream" where "oneTwos = 1 \ 2 \ oneTwos" + +corec everyOther :: "'a stream \ 'a stream" +where "everyOther xs = shd xs \ everyOther (stl (stl xs))" + +corec fibA :: "nat stream" +where "fibA = 0 \ (1 \ fibA \ fibA)" + +corec fibB :: "nat stream" +where "fibB = (0 \ 1 \ fibB) \ (0 \ fibB)" + +corec (friend) times :: "nat stream \ nat stream \ nat stream" (infix "\" 69) +where "xs \ ys = (shd xs * shd ys) \ xs \ stl ys \ stl xs \ ys" + +corec (friend) exp :: "nat stream \ nat stream" +where "exp xs = 2 ^ shd xs \ (stl xs \ exp xs)" + +corec facA :: "nat stream" +where "facA = (1 \ facA) \ (1 \ facA)" + +corec facB :: "nat stream" +where "facB = exp (0 \ facB)" + +corec (friend) sfsup :: "nat stream fset \ nat stream" +where "sfsup X = Sup (fset (fimage shd X)) \ sfsup (fimage stl X)" + +codatatype tree = Node (val: nat) (sub: "tree list") + +corec (friend) tplus :: "tree \ tree \ tree" +where "tplus t u = Node (val t + val u) (map (\(t', u'). tplus t' u') (zip (sub t) (sub u)))" + +corec (friend) ttimes :: "tree \ tree \ tree" +where "ttimes t u = Node (val t * val u) (map (\(t , u ). tplus (ttimes t u ) (ttimes t u)) (zip (sub t) (sub u)))" + +corecursive primes :: "nat \ nat \ nat stream" +where "primes m n = + (if (m = 0 \ n > 1) \ coprime m n then n \ primes (m * n) (n + 1) else primes m (n + 1))" +apply (relation "measure (\(m, n). if n = 0 then 1 else if coprime m n then 0 else m - n mod m)") +apply (auto simp: mod_Suc intro: Suc_lessI ) +apply (metis One_nat_def coprime_Suc_nat gcd.commute gcd_red_nat) +by (metis diff_less_mono2 lessI mod_less_divisor) + +corec facC :: "nat \ nat \ nat \ nat stream" +where "facC n a i = (if i = 0 then a \ facC (n + 1) 1 (n + 1) else facC n (a * i) (i - 1))" + +corec catalan :: "nat \ nat stream" +where "catalan n = (if n > 0 then catalan (n - 1) \ (0 \ catalan (n + 1)) else 1 \ catalan 1)" + +corec (friend) heart :: "nat stream \ nat stream \ nat stream" (infix "\" 65) +where "xs \ ys = SCons (shd xs * shd ys) ((((xs \ stl ys) \ (stl xs \ ys)) \ ys) \ ys)" + +corec (friend) g :: "'a stream \ 'a stream" +where "g xs = shd xs \ g (g (stl xs))" + end