doc-src/TutorialI/Datatype/Nested.thy
author wenzelm
Fri, 15 Sep 2000 20:18:08 +0200
changeset 9994 b06f6d2eef5f
parent 9933 9feb1e0c4cb3
child 10171 59d6633835fa
permissions -rw-r--r--
XSYMBOL_INSTALLFONTS is back;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     1
(*<*)
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
     2
theory Nested = ABexpr:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     3
(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     4
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     5
text{*
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     6
So far, all datatypes had the property that on the right-hand side of their
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     7
definition they occurred only at the top-level, i.e.\ directly below a
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     8
constructor. This is not the case any longer for the following model of terms
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     9
where function symbols can be applied to a list of arguments:
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    10
*}
9933
9feb1e0c4cb3 *** empty log message ***
nipkow
parents: 9834
diff changeset
    11
(*<*)hide const Var(*>*)
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    12
datatype ('a,'b)"term" = Var 'a | App 'b "('a,'b)term list";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    13
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    14
text{*\noindent
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    15
Note that we need to quote @{text"term"} on the left to avoid confusion with
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    16
the command \isacommand{term}.
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    17
Parameter @{typ"'a"} is the type of variables and @{typ"'b"} the type of
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    18
function symbols.
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    19
A mathematical term like $f(x,g(y))$ becomes @{term"App f [Var x, App g
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    20
  [Var y]]"}, where @{term"f"}, @{term"g"}, @{term"x"}, @{term"y"} are
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    21
suitable values, e.g.\ numbers or strings.
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    22
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    23
What complicates the definition of @{text"term"} is the nested occurrence of
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    24
@{text"term"} inside @{text"list"} on the right-hand side. In principle,
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    25
nested recursion can be eliminated in favour of mutual recursion by unfolding
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    26
the offending datatypes, here @{text"list"}. The result for @{text"term"}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    27
would be something like
8751
9ed0548177fb *** empty log message ***
nipkow
parents: 8745
diff changeset
    28
\medskip
9ed0548177fb *** empty log message ***
nipkow
parents: 8745
diff changeset
    29
9ed0548177fb *** empty log message ***
nipkow
parents: 8745
diff changeset
    30
\input{Datatype/document/unfoldnested.tex}
9ed0548177fb *** empty log message ***
nipkow
parents: 8745
diff changeset
    31
\medskip
9ed0548177fb *** empty log message ***
nipkow
parents: 8745
diff changeset
    32
9ed0548177fb *** empty log message ***
nipkow
parents: 8745
diff changeset
    33
\noindent
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    34
Although we do not recommend this unfolding to the user, it shows how to
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    35
simulate nested recursion by mutual recursion.
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    36
Now we return to the initial definition of @{text"term"} using
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    37
nested recursion.
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    38
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    39
Let us define a substitution function on terms. Because terms involve term
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    40
lists, we need to define two substitution functions simultaneously:
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    41
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    42
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    43
consts
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    44
subst :: "('a\\<Rightarrow>('a,'b)term) \\<Rightarrow> ('a,'b)term      \\<Rightarrow> ('a,'b)term"
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    45
substs:: "('a\\<Rightarrow>('a,'b)term) \\<Rightarrow> ('a,'b)term list \\<Rightarrow> ('a,'b)term list";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    46
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    47
primrec
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    48
  "subst s (Var x) = s x"
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    49
  subst_App:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    50
  "subst s (App f ts) = App f (substs s ts)"
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    51
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    52
  "substs s [] = []"
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    53
  "substs s (t # ts) = subst s t # substs s ts";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    54
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    55
text{*\noindent
9933
9feb1e0c4cb3 *** empty log message ***
nipkow
parents: 9834
diff changeset
    56
(Please ignore the label @{thm[source]subst_App} for the moment.)
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    57
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    58
Similarly, when proving a statement about terms inductively, we need
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    59
to prove a related statement about term lists simultaneously. For example,
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    60
the fact that the identity substitution does not change a term needs to be
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    61
strengthened and proved as follows:
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    62
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    63
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    64
lemma "subst  Var t  = (t ::('a,'b)term)  \\<and>
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    65
        substs Var ts = (ts::('a,'b)term list)";
9689
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
    66
by(induct_tac t and ts, simp_all);
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    67
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    68
text{*\noindent
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    69
Note that @{term"Var"} is the identity substitution because by definition it
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    70
leaves variables unchanged: @{prop"subst Var (Var x) = Var x"}. Note also
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    71
that the type annotations are necessary because otherwise there is nothing in
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    72
the goal to enforce that both halves of the goal talk about the same type
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    73
parameters @{text"('a,'b)"}. As a result, induction would fail
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    74
because the two halves of the goal would be unrelated.
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    75
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    76
\begin{exercise}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    77
The fact that substitution distributes over composition can be expressed
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    78
roughly as follows:
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    79
@{text[display]"subst (f o g) t = subst f (subst g t)"}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    80
Correct this statement (you will find that it does not type-check),
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    81
strengthen it, and prove it. (Note: \isaindexbold{o} is function composition;
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    82
its definition is found in theorem @{thm[source]o_def}).
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    83
\end{exercise}
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    84
\begin{exercise}\label{ex:trev-trev}
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    85
  Define a function @{text"trev"} of type @{typ"('a,'b)term => ('a,'b)term"}
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    86
that recursively reverses the order of arguments of all function symbols in a
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    87
  term. Prove that @{prop"trev(trev t) = t"}.
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    88
\end{exercise}
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    89
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    90
The experienced functional programmer may feel that our above definition of
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    91
@{term"subst"} is unnecessarily complicated in that @{term"substs"} is
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    92
completely unnecessary. The @{term"App"}-case can be defined directly as
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    93
@{term[display]"subst s (App f ts) = App f (map (subst s) ts)"}
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    94
where @{term"map"} is the standard list function such that
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    95
@{text"map f [x1,...,xn] = [f x1,...,f xn]"}. This is true, but Isabelle
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    96
insists on the above fixed format. Fortunately, we can easily \emph{prove}
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
    97
that the suggested equation holds:
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    98
*}
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
    99
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   100
lemma [simp]: "subst s (App f ts) = App f (map (subst s) ts)"
9689
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   101
by(induct_tac ts, simp_all)
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   102
9689
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   103
text{*\noindent
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   104
What is more, we can now disable the old defining equation as a
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   105
simplification rule:
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   106
*}
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   107
9933
9feb1e0c4cb3 *** empty log message ***
nipkow
parents: 9834
diff changeset
   108
declare subst_App [simp del]
9644
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   109
6b0b6b471855 *** empty log message ***
nipkow
parents: 9541
diff changeset
   110
text{*\noindent
9689
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   111
The advantage is that now we have replaced @{term"substs"} by
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   112
@{term"map"}, we can profit from the large number of pre-proved lemmas
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   113
about @{term"map"}.  Unfortunately inductive proofs about type
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
   114
@{text"term"} are still awkward because they expect a conjunction. One
9689
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   115
could derive a new induction principle as well (see
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   116
\S\ref{sec:derive-ind}), but turns out to be simpler to define
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   117
functions by \isacommand{recdef} instead of \isacommand{primrec}.
751fde5307e4 *** empty log message ***
nipkow
parents: 9644
diff changeset
   118
The details are explained in \S\ref{sec:advanced-recdef} below.
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   119
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   120
Of course, you may also combine mutual and nested recursion. For example,
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
   121
constructor @{text"Sum"} in \S\ref{sec:datatype-mut-rec} could take a list of
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9689
diff changeset
   122
expressions as its argument: @{text"Sum"}~@{typ[quotes]"'a aexp list"}.
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   123
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   124
(*<*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   125
end
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   126
(*>*)