src/HOL/Corec_Examples/Paper_Examples.thy
author wenzelm
Fri, 21 Apr 2017 16:48:58 +0200
changeset 65538 a39ef48fbee0
parent 63468 cadd40a6cdec
child 66453 cc19f7ca2ed6
permissions -rw-r--r--
tuned imports;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     1
(*  Title:      HOL/Corec_Examples/Paper_Examples.thy
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     2
    Author:     Andreas Lochbihler, ETH Zuerich
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     3
    Author:     Andrei Popescu, TU Muenchen
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     4
    Copyright   2016
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     5
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
     6
Small examples from the paper "Friends with Benefits".
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     7
*)
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
     8
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
     9
section \<open>Small Examples from the Paper ``Friends with Benefits''\<close>
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    10
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    11
theory Paper_Examples
65538
a39ef48fbee0 tuned imports;
wenzelm
parents: 63468
diff changeset
    12
imports "~~/src/HOL/Library/BNF_Corec" "~~/src/HOL/Library/FSet" Complex_Main
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    13
begin
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    14
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    15
section \<open>Examples from the introduction\<close>
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    16
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    17
codatatype 'a stream = SCons (shd: 'a) (stl: "'a stream") (infixr "\<lhd>" 65)
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    18
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    19
corec "natsFrom" :: "nat \<Rightarrow> nat stream" where
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    20
  "natsFrom n = n \<lhd> natsFrom (n + 1)"
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    21
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    22
corec (friend) add1 :: "nat stream \<Rightarrow> nat stream"
63468
blanchet
parents: 63408
diff changeset
    23
where "add1 ns = (shd ns + 1) \<lhd> add1 (stl ns)"
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    24
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    25
corec natsFrom' :: "nat \<Rightarrow> nat stream" where
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    26
  "natsFrom' n = n \<lhd> add1 (natsFrom' n)"
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    27
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    28
section \<open>Examples from section 3\<close>
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    29
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    30
text \<open>We curry the example functions in this section because infix syntax works only for curried functions.\<close>
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    31
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    32
corec (friend) Plus :: "nat stream \<Rightarrow> nat stream \<Rightarrow> nat stream" (infix "\<oplus>" 67) where
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    33
  "x\<^sub>1 \<oplus> x\<^sub>2 = (shd x\<^sub>1 + shd x\<^sub>2) \<lhd> (stl x\<^sub>1 \<oplus> stl x\<^sub>2)"
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    34
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    35
section \<open>Examples from section 4\<close>
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    36
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    37
codatatype 'a llist = LNil | LCons 'a "'a llist"
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    38
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    39
corec collatz :: "nat \<Rightarrow> nat llist" where
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    40
  "collatz n = (if n \<le> 1 then LNil
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    41
     else if even n then collatz (n div 2)
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    42
     else LCons n (collatz (3 * n + 1)))"
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
    43
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    44
datatype 'a nelist = NEList (hd:'a) (tl:"'a list")
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    45
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    46
primrec (transfer) snoc :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a nelist" (infix "\<rhd>" 64) where
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    47
 "[] \<rhd> a = NEList a []"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    48
|"(b # bs) \<rhd> a = NEList b (bs @ [a])"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    49
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    50
corec (friend) inter :: "nat stream nelist \<Rightarrow> nat stream" where
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    51
"inter xss = shd (hd xss) \<lhd> inter (tl xss \<rhd> stl (hd xss))"
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    52
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    53
corec (friend) inter' :: "nat stream nelist \<Rightarrow> nat stream" where
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    54
"inter' xss = (case hd xss of x \<lhd> xs \<Rightarrow> x \<lhd> inter' (tl xss \<rhd> xs))"
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    55
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    56
corec zero :: "nat stream" where "zero = 0 \<lhd> zero"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    57
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    58
section \<open>Examples from Blanchette et al. (ICFP 2015)\<close>
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    59
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    60
corec oneTwos :: "nat stream" where "oneTwos = 1 \<lhd> 2 \<lhd> oneTwos"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    61
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    62
corec everyOther :: "'a stream \<Rightarrow> 'a stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    63
where "everyOther xs = shd xs \<lhd> everyOther (stl (stl xs))"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    64
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    65
corec fibA :: "nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    66
where "fibA = 0 \<lhd> (1 \<lhd> fibA \<oplus> fibA)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    67
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    68
corec fibB :: "nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    69
where "fibB = (0 \<lhd> 1 \<lhd> fibB) \<oplus> (0 \<lhd> fibB)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    70
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    71
corec (friend) times :: "nat stream \<Rightarrow> nat stream \<Rightarrow> nat stream" (infix "\<otimes>" 69)
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    72
where "xs \<otimes> ys = (shd xs * shd ys) \<lhd> xs \<otimes> stl ys \<oplus> stl xs \<otimes> ys"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    73
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    74
corec (friend) exp :: "nat stream \<Rightarrow> nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    75
where "exp xs = 2 ^ shd xs \<lhd> (stl xs \<otimes> exp xs)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    76
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    77
corec facA :: "nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    78
where "facA = (1 \<lhd> facA) \<otimes> (1 \<lhd> facA)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    79
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    80
corec facB :: "nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    81
where "facB = exp (0 \<lhd> facB)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    82
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    83
corec (friend) sfsup :: "nat stream fset \<Rightarrow> nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    84
where "sfsup X = Sup (fset (fimage shd X)) \<lhd> sfsup (fimage stl X)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    85
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    86
codatatype tree = Node (val: nat) (sub: "tree list")
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    87
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    88
corec (friend) tplus :: "tree \<Rightarrow> tree \<Rightarrow> tree"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    89
where "tplus t u = Node (val t + val u) (map (\<lambda>(t', u'). tplus t' u') (zip (sub t) (sub u)))"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    90
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    91
corec (friend) ttimes :: "tree \<Rightarrow> tree \<Rightarrow> tree"
63408
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    92
where "ttimes t u = Node (val t * val u)
74c609115df0 updated example
blanchet
parents: 63406
diff changeset
    93
  (map (\<lambda>(t, u). tplus (ttimes t u) (ttimes t u)) (zip (sub t) (sub u)))"
63406
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    94
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    95
corecursive primes :: "nat \<Rightarrow> nat \<Rightarrow> nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    96
where "primes m n =
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    97
  (if (m = 0 \<and> n > 1) \<or> coprime m n then n \<lhd> primes (m * n) (n + 1) else primes m (n + 1))"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    98
apply (relation "measure (\<lambda>(m, n). if n = 0 then 1 else if coprime m n then 0 else m - n mod m)")
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
    99
apply (auto simp: mod_Suc intro: Suc_lessI )
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   100
apply (metis One_nat_def coprime_Suc_nat gcd.commute gcd_red_nat)
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   101
by (metis diff_less_mono2 lessI mod_less_divisor)
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   102
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   103
corec facC :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   104
where "facC n a i = (if i = 0 then a \<lhd> facC (n + 1) 1 (n + 1) else facC n (a * i) (i - 1))"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   105
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   106
corec catalan :: "nat \<Rightarrow> nat stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   107
where "catalan n = (if n > 0 then catalan (n - 1) \<oplus> (0 \<lhd> catalan (n + 1)) else 1 \<lhd> catalan 1)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   108
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   109
corec (friend) heart :: "nat stream \<Rightarrow> nat stream \<Rightarrow> nat stream" (infix "\<heartsuit>" 65)
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   110
where "xs \<heartsuit> ys = SCons (shd xs * shd ys) ((((xs \<heartsuit> stl ys) \<oplus> (stl xs \<otimes> ys)) \<heartsuit> ys) \<otimes> ys)"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   111
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   112
corec (friend) g :: "'a stream \<Rightarrow> 'a stream"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   113
where "g xs = shd xs \<lhd> g (g (stl xs))"
32866eff1843 updated examples
blanchet
parents: 62734
diff changeset
   114
62734
38fefd98c929 another 'corec' example
blanchet
parents:
diff changeset
   115
end