doc-src/TutorialI/Datatype/Fundata.thy
author nipkow
Tue, 05 Sep 2000 09:03:17 +0200
changeset 9834 109b11c4e77e
parent 9792 bbefb6ce5cb2
child 9933 9feb1e0c4cb3
permissions -rw-r--r--
*** empty log message ***
nipkow@8745
     1
(*<*)
nipkow@8745
     2
theory Fundata = Main:
nipkow@8745
     3
(*>*)
nipkow@8745
     4
datatype ('a,'i)bigtree = Tip | Branch 'a "'i \\<Rightarrow> ('a,'i)bigtree"
nipkow@8745
     5
nipkow@9792
     6
text{*\noindent
nipkow@9792
     7
Parameter @{typ"'a"} is the type of values stored in
nipkow@9792
     8
the @{term"Branch"}es of the tree, whereas @{typ"'i"} is the index
nipkow@9792
     9
type over which the tree branches. If @{typ"'i"} is instantiated to
nipkow@9792
    10
@{typ"bool"}, the result is a binary tree; if it is instantiated to
nipkow@9792
    11
@{typ"nat"}, we have an infinitely branching tree because each node
nipkow@8745
    12
has as many subtrees as there are natural numbers. How can we possibly
nipkow@9541
    13
write down such a tree? Using functional notation! For example, the term
nipkow@9541
    14
@{term[display]"Branch 0 (%i. Branch i (%n. Tip))"}
nipkow@9541
    15
of type @{typ"(nat,nat)bigtree"} is the tree whose
nipkow@8771
    16
root is labeled with 0 and whose $i$th subtree is labeled with $i$ and
nipkow@9792
    17
has merely @{term"Tip"}s as further subtrees.
nipkow@8745
    18
nipkow@9792
    19
Function @{term"map_bt"} applies a function to all labels in a @{text"bigtree"}:
nipkow@8745
    20
*}
nipkow@8745
    21
nipkow@8745
    22
consts map_bt :: "('a \\<Rightarrow> 'b) \\<Rightarrow> ('a,'i)bigtree \\<Rightarrow> ('b,'i)bigtree"
nipkow@8745
    23
primrec
nipkow@8745
    24
"map_bt f Tip          = Tip"
nipkow@8745
    25
"map_bt f (Branch a F) = Branch (f a) (\\<lambda>i. map_bt f (F i))"
nipkow@8745
    26
nipkow@8745
    27
text{*\noindent This is a valid \isacommand{primrec} definition because the
nipkow@9792
    28
recursive calls of @{term"map_bt"} involve only subtrees obtained from
nipkow@9792
    29
@{term"F"}, i.e.\ the left-hand side. Thus termination is assured.  The
nipkow@9541
    30
seasoned functional programmer might have written @{term"map_bt f o F"}
nipkow@9541
    31
instead of @{term"%i. map_bt f (F i)"}, but the former is not accepted by
nipkow@8745
    32
Isabelle because the termination proof is not as obvious since
nipkow@9792
    33
@{term"map_bt"} is only partially applied.
nipkow@8745
    34
nipkow@8745
    35
The following lemma has a canonical proof  *}
nipkow@8745
    36
nipkow@8771
    37
lemma "map_bt (g o f) T = map_bt g (map_bt f T)";
nipkow@9689
    38
by(induct_tac "T", simp_all)
nipkow@8745
    39
nipkow@8745
    40
text{*\noindent
nipkow@8745
    41
but it is worth taking a look at the proof state after the induction step
nipkow@8745
    42
to understand what the presence of the function type entails:
nipkow@9723
    43
\begin{isabelle}
nipkow@8745
    44
~1.~map\_bt~g~(map\_bt~f~Tip)~=~map\_bt~(g~{\isasymcirc}~f)~Tip\isanewline
nipkow@8745
    45
~2.~{\isasymAnd}a~F.\isanewline
nipkow@8745
    46
~~~~~~{\isasymforall}x.~map\_bt~g~(map\_bt~f~(F~x))~=~map\_bt~(g~{\isasymcirc}~f)~(F~x)~{\isasymLongrightarrow}\isanewline
nipkow@8745
    47
~~~~~~map\_bt~g~(map\_bt~f~(Branch~a~F))~=~map\_bt~(g~{\isasymcirc}~f)~(Branch~a~F)%
nipkow@9723
    48
\end{isabelle}
nipkow@8745
    49
*}
nipkow@8745
    50
(*<*)
nipkow@8745
    51
end
nipkow@8745
    52
(*>*)