doc-src/TutorialI/Datatype/document/ABexpr.tex
author wenzelm
Thu, 17 Aug 2000 10:33:37 +0200
changeset 9619 6125cc9efc18
parent 9541 d17c0b34d5c8
child 9644 6b0b6b471855
permissions -rw-r--r--
fixed deps;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     1
\begin{isabelle}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     2
%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     3
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     4
Sometimes it is necessary to define two datatypes that depend on each
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     5
other. This is called \textbf{mutual recursion}. As an example consider a
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     6
language of arithmetic and boolean expressions where
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     7
\begin{itemize}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     8
\item arithmetic expressions contain boolean expressions because there are
2665170f104a Adding generated files
nipkow
parents:
diff changeset
     9
  conditional arithmetic expressions like ``if $m<n$ then $n-m$ else $m-n$'',
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    10
  and
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    11
\item boolean expressions contain arithmetic expressions because of
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    12
  comparisons like ``$m<n$''.
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    13
\end{itemize}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    14
In Isabelle this becomes%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    15
\end{isamarkuptext}%
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    16
\isacommand{datatype}\ 'a\ aexp\ =\ IF\ \ \ {"}'a\ bexp{"}\ {"}'a\ aexp{"}\ {"}'a\ aexp{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    17
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ Sum\ \ {"}'a\ aexp{"}\ {"}'a\ aexp{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    18
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ Diff\ {"}'a\ aexp{"}\ {"}'a\ aexp{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    19
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ Var\ 'a\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    20
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ Num\ nat\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    21
\isakeyword{and}\ \ \ \ \ \ 'a\ bexp\ =\ Less\ {"}'a\ aexp{"}\ {"}'a\ aexp{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    22
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ And\ \ {"}'a\ bexp{"}\ {"}'a\ bexp{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    23
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ Neg\ \ {"}'a\ bexp{"}%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    24
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    25
\noindent
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    26
Type \isa{aexp} is similar to \isa{expr} in \S\ref{sec:ExprCompiler},
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    27
except that we have fixed the values to be of type \isa{nat} and that we
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    28
have fixed the two binary operations \isa{Sum} and \isa{Diff}. Boolean
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    29
expressions can be arithmetic comparisons, conjunctions and negations.
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    30
The semantics is fixed via two evaluation functions%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    31
\end{isamarkuptext}%
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    32
\isacommand{consts}\ \ evala\ ::\ {"}'a\ aexp\ {\isasymRightarrow}\ ('a\ {\isasymRightarrow}\ nat)\ {\isasymRightarrow}\ nat{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    33
\ \ \ \ \ \ \ \ evalb\ ::\ {"}'a\ bexp\ {\isasymRightarrow}\ ('a\ {\isasymRightarrow}\ nat)\ {\isasymRightarrow}\ bool{"}%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    34
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    35
\noindent
8771
026f37a86ea7 *** empty log message ***
nipkow
parents: 8749
diff changeset
    36
that take an expression and an environment (a mapping from variables \isa{'a} to values
026f37a86ea7 *** empty log message ***
nipkow
parents: 8749
diff changeset
    37
\isa{nat}) and return its arithmetic/boolean
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    38
value. Since the datatypes are mutually recursive, so are functions that
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    39
operate on them. Hence they need to be defined in a single \isacommand{primrec}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    40
section:%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    41
\end{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    42
\isacommand{primrec}\isanewline
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    43
\ \ {"}evala\ (IF\ b\ a1\ a2)\ env\ =\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    44
\ \ \ \ \ (if\ evalb\ b\ env\ then\ evala\ a1\ env\ else\ evala\ a2\ env){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    45
\ \ {"}evala\ (Sum\ a1\ a2)\ env\ =\ evala\ a1\ env\ +\ evala\ a2\ env{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    46
\ \ {"}evala\ (Diff\ a1\ a2)\ env\ =\ evala\ a1\ env\ -\ evala\ a2\ env{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    47
\ \ {"}evala\ (Var\ v)\ env\ =\ env\ v{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    48
\ \ {"}evala\ (Num\ n)\ env\ =\ n{"}\isanewline
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    49
\isanewline
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    50
\ \ {"}evalb\ (Less\ a1\ a2)\ env\ =\ (evala\ a1\ env\ <\ evala\ a2\ env){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    51
\ \ {"}evalb\ (And\ b1\ b2)\ env\ =\ (evalb\ b1\ env\ {\isasymand}\ evalb\ b2\ env){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    52
\ \ {"}evalb\ (Neg\ b)\ env\ =\ ({\isasymnot}\ evalb\ b\ env){"}%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    53
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    54
\noindent
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    55
In the same fashion we also define two functions that perform substitution:%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    56
\end{isamarkuptext}%
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    57
\isacommand{consts}\ substa\ ::\ {"}('a\ {\isasymRightarrow}\ 'b\ aexp)\ {\isasymRightarrow}\ 'a\ aexp\ {\isasymRightarrow}\ 'b\ aexp{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    58
\ \ \ \ \ \ \ substb\ ::\ {"}('a\ {\isasymRightarrow}\ 'b\ aexp)\ {\isasymRightarrow}\ 'a\ bexp\ {\isasymRightarrow}\ 'b\ bexp{"}%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    59
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    60
\noindent
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    61
The first argument is a function mapping variables to expressions, the
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    62
substitution. It is applied to all variables in the second argument. As a
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    63
result, the type of variables in the expression may change from \isa{'a}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    64
to \isa{'b}. Note that there are only arithmetic and no boolean variables.%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    65
\end{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    66
\isacommand{primrec}\isanewline
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    67
\ \ {"}substa\ s\ (IF\ b\ a1\ a2)\ =\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    68
\ \ \ \ \ IF\ (substb\ s\ b)\ (substa\ s\ a1)\ (substa\ s\ a2){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    69
\ \ {"}substa\ s\ (Sum\ a1\ a2)\ =\ Sum\ (substa\ s\ a1)\ (substa\ s\ a2){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    70
\ \ {"}substa\ s\ (Diff\ a1\ a2)\ =\ Diff\ (substa\ s\ a1)\ (substa\ s\ a2){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    71
\ \ {"}substa\ s\ (Var\ v)\ =\ s\ v{"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    72
\ \ {"}substa\ s\ (Num\ n)\ =\ Num\ n{"}\isanewline
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    73
\isanewline
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    74
\ \ {"}substb\ s\ (Less\ a1\ a2)\ =\ Less\ (substa\ s\ a1)\ (substa\ s\ a2){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    75
\ \ {"}substb\ s\ (And\ b1\ b2)\ =\ And\ (substb\ s\ b1)\ (substb\ s\ b2){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    76
\ \ {"}substb\ s\ (Neg\ b)\ =\ Neg\ (substb\ s\ b){"}%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    77
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    78
Now we can prove a fundamental theorem about the interaction between
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    79
evaluation and substitution: applying a substitution $s$ to an expression $a$
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    80
and evaluating the result in an environment $env$ yields the same result as
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    81
evaluation $a$ in the environment that maps every variable $x$ to the value
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    82
of $s(x)$ under $env$. If you try to prove this separately for arithmetic or
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    83
boolean expressions (by induction), you find that you always need the other
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    84
theorem in the induction step. Therefore you need to state and prove both
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    85
theorems simultaneously:%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    86
\end{isamarkuptext}%
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    87
\isacommand{lemma}\ {"}evala\ (substa\ s\ a)\ env\ =\ evala\ a\ ({\isasymlambda}x.\ evala\ (s\ x)\ env)\ {\isasymand}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    88
\ \ \ \ \ \ \ \ evalb\ (substb\ s\ b)\ env\ =\ evalb\ b\ ({\isasymlambda}x.\ evala\ (s\ x)\ env){"}\isanewline
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    89
\isacommand{apply}(induct\_tac\ a\ \isakeyword{and}\ b)%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    90
\begin{isamarkuptxt}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    91
\noindent
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    92
The resulting 8 goals (one for each constructor) are proved in one fell swoop:%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    93
\end{isamarkuptxt}%
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    94
\isacommand{by}\ auto%
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    95
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    96
In general, given $n$ mutually recursive datatypes $\tau@1$, \dots, $\tau@n$,
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    97
an inductive proof expects a goal of the form
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    98
\[ P@1(x@1)\ \land \dots \land P@n(x@n) \]
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    99
where each variable $x@i$ is of type $\tau@i$. Induction is started by
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   100
\begin{ttbox}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   101
apply(induct_tac \(x@1\) \texttt{and} \(\dots\) \texttt{and} \(x@n\));
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   102
\end{ttbox}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   103
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   104
\begin{exercise}
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
   105
  Define a function \isa{norma} of type \isa{'a\ aexp\ {\isasymRightarrow}\ 'a\ aexp} that
8749
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   106
  replaces \isa{IF}s with complex boolean conditions by nested
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   107
  \isa{IF}s where each condition is a \isa{Less} --- \isa{And} and
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   108
  \isa{Neg} should be eliminated completely. Prove that \isa{norma}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   109
  preserves the value of an expression and that the result of \isa{norma}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   110
  is really normal, i.e.\ no more \isa{And}s and \isa{Neg}s occur in
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   111
  it.  ({\em Hint:} proceed as in \S\ref{sec:boolex}).
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   112
\end{exercise}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   113
\end{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   114
\end{isabelle}%
9145
9f7b8de5bfaf updated;
wenzelm
parents: 8771
diff changeset
   115
%%% Local Variables:
9f7b8de5bfaf updated;
wenzelm
parents: 8771
diff changeset
   116
%%% mode: latex
9f7b8de5bfaf updated;
wenzelm
parents: 8771
diff changeset
   117
%%% TeX-master: "root"
9f7b8de5bfaf updated;
wenzelm
parents: 8771
diff changeset
   118
%%% End: