doc-src/Exercises/0304/a2/a2.thy
author obua
Sun, 09 May 2004 23:04:36 +0200
changeset 14722 8e739a6eaf11
parent 14499 f08ea8e964d8
permissions -rw-r--r--
replaced apply-style proof for instance Multiset :: plus_ac0 by recommended Isar proof style
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14499
streckem
parents:
diff changeset
     1
streckem
parents:
diff changeset
     2
(*<*) theory a2 = Main: (*>*)
streckem
parents:
diff changeset
     3
streckem
parents:
diff changeset
     4
subsection {* Folding Lists and Trees *}
streckem
parents:
diff changeset
     5
streckem
parents:
diff changeset
     6
subsubsection {* Some more list functions *}
streckem
parents:
diff changeset
     7
streckem
parents:
diff changeset
     8
text{* Recall the summation function *}
streckem
parents:
diff changeset
     9
streckem
parents:
diff changeset
    10
(*<*) consts (*>*)
streckem
parents:
diff changeset
    11
  sum :: "nat list \<Rightarrow> nat"
streckem
parents:
diff changeset
    12
primrec
streckem
parents:
diff changeset
    13
  "sum [] = 0"
streckem
parents:
diff changeset
    14
  "sum (x # xs) = x + sum xs"
streckem
parents:
diff changeset
    15
streckem
parents:
diff changeset
    16
streckem
parents:
diff changeset
    17
text{* In the Isabelle library, you will find in theory
streckem
parents:
diff changeset
    18
\texttt{List.thy} the functions @{text foldr} and @{text foldl}, which
streckem
parents:
diff changeset
    19
allow you to define some list functions, among them @{text sum} and
streckem
parents:
diff changeset
    20
@{text length}. Show the following: *}
streckem
parents:
diff changeset
    21
streckem
parents:
diff changeset
    22
streckem
parents:
diff changeset
    23
lemma sum_foldr: "sum xs = foldr (op +) xs 0"
streckem
parents:
diff changeset
    24
(*<*) oops (*>*)
streckem
parents:
diff changeset
    25
streckem
parents:
diff changeset
    26
lemma length_foldr: "length xs = foldr (\<lambda> x res. 1 + res) xs 0"
streckem
parents:
diff changeset
    27
(*<*) oops (*>*)
streckem
parents:
diff changeset
    28
streckem
parents:
diff changeset
    29
text {* Repeated application of @{text foldr} and @{text map} has the
streckem
parents:
diff changeset
    30
disadvantage that a list is traversed several times. A single traversal is sufficient, as
streckem
parents:
diff changeset
    31
illustrated by the following example: *}
streckem
parents:
diff changeset
    32
streckem
parents:
diff changeset
    33
lemma "sum (map (\<lambda> x. x + 3) xs) = foldr h xs b"
streckem
parents:
diff changeset
    34
(*<*) oops (*>*)
streckem
parents:
diff changeset
    35
streckem
parents:
diff changeset
    36
text {* Find terms @{text h} and @{text b} which solve this
streckem
parents:
diff changeset
    37
equation. Generalize this result, i.e. show for appropriate @{text h}
streckem
parents:
diff changeset
    38
and @{text b}: *}
streckem
parents:
diff changeset
    39
streckem
parents:
diff changeset
    40
streckem
parents:
diff changeset
    41
lemma "foldr g (map f xs) a = foldr h xs b"
streckem
parents:
diff changeset
    42
(*<*) oops (*>*)
streckem
parents:
diff changeset
    43
streckem
parents:
diff changeset
    44
text {* Hint: Isabelle can help you find the solution if you use the
streckem
parents:
diff changeset
    45
equalities arising during a proof attempt. *}
streckem
parents:
diff changeset
    46
streckem
parents:
diff changeset
    47
text {* The following function @{text rev_acc} reverses a list in linear time: *}
streckem
parents:
diff changeset
    48
streckem
parents:
diff changeset
    49
streckem
parents:
diff changeset
    50
consts
streckem
parents:
diff changeset
    51
  rev_acc :: "['a list, 'a list] \<Rightarrow> 'a list"
streckem
parents:
diff changeset
    52
primrec
streckem
parents:
diff changeset
    53
  "rev_acc [] ys = ys"
streckem
parents:
diff changeset
    54
  "rev_acc (x#xs) ys = (rev_acc xs (x#ys))"
streckem
parents:
diff changeset
    55
streckem
parents:
diff changeset
    56
text{* Show that @{text rev_acc} can be defined by means of @{text foldl}. *}
streckem
parents:
diff changeset
    57
streckem
parents:
diff changeset
    58
lemma rev_acc_foldl: "rev_acc xs a = foldl (\<lambda> ys x. x # ys) a xs"
streckem
parents:
diff changeset
    59
(*<*) oops (*>*)
streckem
parents:
diff changeset
    60
streckem
parents:
diff changeset
    61
text {* On the first exercise sheet, we have shown: *}
streckem
parents:
diff changeset
    62
streckem
parents:
diff changeset
    63
lemma sum_append [simp]: "sum (xs @ ys) = sum xs + sum ys"
streckem
parents:
diff changeset
    64
  by (induct xs) auto
streckem
parents:
diff changeset
    65
streckem
parents:
diff changeset
    66
text {* Prove a similar distributivity property for @{text foldr},
streckem
parents:
diff changeset
    67
i.e. something like @{text "foldr f (xs @ ys) a = f (foldr f xs a)
streckem
parents:
diff changeset
    68
(foldr f ys a)"}. However, you will have to strengthen the premisses
streckem
parents:
diff changeset
    69
by taking into account algebraic properties of @{text f} and @{text
streckem
parents:
diff changeset
    70
a}. *}
streckem
parents:
diff changeset
    71
streckem
parents:
diff changeset
    72
streckem
parents:
diff changeset
    73
lemma foldr_append: "foldr f (xs @ ys) a = f (foldr f xs a) (foldr f ys a)"
streckem
parents:
diff changeset
    74
(*<*) oops (*>*)
streckem
parents:
diff changeset
    75
streckem
parents:
diff changeset
    76
text {* Now, define the function @{text prod}, which computes the product of all list elements: *}
streckem
parents:
diff changeset
    77
(*<*) consts (*>*)
streckem
parents:
diff changeset
    78
  prod :: "nat list \<Rightarrow> nat"
streckem
parents:
diff changeset
    79
streckem
parents:
diff changeset
    80
text {* direcly with the aid of  a fold and prove the following: *}
streckem
parents:
diff changeset
    81
lemma "prod (xs @ ys) = prod xs * prod ys"
streckem
parents:
diff changeset
    82
(*<*) oops (*>*)
streckem
parents:
diff changeset
    83
streckem
parents:
diff changeset
    84
streckem
parents:
diff changeset
    85
subsubsection {* Functions on Trees *}
streckem
parents:
diff changeset
    86
streckem
parents:
diff changeset
    87
text {* Consider the following type of binary trees: *}
streckem
parents:
diff changeset
    88
datatype 'a tree = Tip | Node "'a tree" 'a "'a tree"
streckem
parents:
diff changeset
    89
streckem
parents:
diff changeset
    90
text {* Define functions which convert a tree into a list by traversing it in pre- resp. postorder: *}
streckem
parents:
diff changeset
    91
(*<*) consts (*>*)
streckem
parents:
diff changeset
    92
  preorder :: "'a tree \<Rightarrow> 'a list"
streckem
parents:
diff changeset
    93
  postorder :: "'a tree \<Rightarrow> 'a list"
streckem
parents:
diff changeset
    94
streckem
parents:
diff changeset
    95
text {* You have certainly realized that computation of postorder traversal can be efficiently realized with an accumulator, in analogy to  @{text rev_acc}: *} 
streckem
parents:
diff changeset
    96
streckem
parents:
diff changeset
    97
consts
streckem
parents:
diff changeset
    98
  postorder_acc :: "['a tree, 'a list] \<Rightarrow> 'a list"
streckem
parents:
diff changeset
    99
streckem
parents:
diff changeset
   100
text {* Define this function and show: *}
streckem
parents:
diff changeset
   101
lemma "postorder_acc t xs = (postorder t) @ xs"
streckem
parents:
diff changeset
   102
(*<*) oops (*>*)
streckem
parents:
diff changeset
   103
streckem
parents:
diff changeset
   104
streckem
parents:
diff changeset
   105
text {* @{text postorder_acc} is the instance of a function
streckem
parents:
diff changeset
   106
@{text foldl_tree}, which is similar to @{text foldl}. *}
streckem
parents:
diff changeset
   107
streckem
parents:
diff changeset
   108
consts
streckem
parents:
diff changeset
   109
  foldl_tree :: "('b => 'a => 'b) \<Rightarrow> 'b \<Rightarrow> 'a tree \<Rightarrow> 'b"
streckem
parents:
diff changeset
   110
streckem
parents:
diff changeset
   111
text {* Show the following: *}
streckem
parents:
diff changeset
   112
streckem
parents:
diff changeset
   113
lemma "\<forall> a. postorder_acc t a = foldl_tree (\<lambda> xs x. Cons x xs) a t"
streckem
parents:
diff changeset
   114
(*<*) oops (*>*)
streckem
parents:
diff changeset
   115
streckem
parents:
diff changeset
   116
text {* Define a function @{text tree_sum} that computes the sum of
streckem
parents:
diff changeset
   117
the elements of a tree of natural numbers: *}
streckem
parents:
diff changeset
   118
streckem
parents:
diff changeset
   119
consts
streckem
parents:
diff changeset
   120
  tree_sum :: "nat tree \<Rightarrow> nat"
streckem
parents:
diff changeset
   121
streckem
parents:
diff changeset
   122
text {* and show that this function satisfies *}
streckem
parents:
diff changeset
   123
streckem
parents:
diff changeset
   124
lemma "tree_sum t = sum (preorder t)"
streckem
parents:
diff changeset
   125
(*<*) oops (*>*)
streckem
parents:
diff changeset
   126
streckem
parents:
diff changeset
   127
streckem
parents:
diff changeset
   128
(*<*) end (*>*)
streckem
parents:
diff changeset
   129