doc-src/TutorialI/Datatype/document/ABexpr.tex
author nipkow
Wed, 19 Apr 2000 12:59:38 +0200
changeset 8749 2665170f104a
child 8771 026f37a86ea7
permissions -rw-r--r--
Adding generated files
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}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    16
\isacommand{datatype}~'a~aexp~=~IF~~~{"}'a~bexp{"}~{"}'a~aexp{"}~{"}'a~aexp{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    17
~~~~~~~~~~~~~~~~~|~Sum~~{"}'a~aexp{"}~{"}'a~aexp{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    18
~~~~~~~~~~~~~~~~~|~Diff~{"}'a~aexp{"}~{"}'a~aexp{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    19
~~~~~~~~~~~~~~~~~|~Var~'a\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    20
~~~~~~~~~~~~~~~~~|~Num~nat\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    21
\isakeyword{and}~~~~~~'a~bexp~=~Less~{"}'a~aexp{"}~{"}'a~aexp{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    22
~~~~~~~~~~~~~~~~~|~And~~{"}'a~bexp{"}~{"}'a~bexp{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    23
~~~~~~~~~~~~~~~~~|~Neg~~{"}'a~bexp{"}%
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}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    32
\isacommand{consts}~~evala~::~{"}('a~{\isasymRightarrow}~nat)~{\isasymRightarrow}~'a~aexp~{\isasymRightarrow}~nat{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    33
~~~~~~~~evalb~::~{"}('a~{\isasymRightarrow}~nat)~{\isasymRightarrow}~'a~bexp~{\isasymRightarrow}~bool{"}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    34
\begin{isamarkuptext}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    35
\noindent
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    36
that take an environment (a mapping from variables \isa{'a} to values
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    37
\isa{nat}) and an expression and return its arithmetic/boolean
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
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    43
~~{"}evala~env~(IF~b~a1~a2)~=\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    44
~~~~~(if~evalb~env~b~then~evala~env~a1~else~evala~env~a2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    45
~~{"}evala~env~(Sum~a1~a2)~=~evala~env~a1~+~evala~env~a2{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    46
~~{"}evala~env~(Diff~a1~a2)~=~evala~env~a1~-~evala~env~a2{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    47
~~{"}evala~env~(Var~v)~=~env~v{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    48
~~{"}evala~env~(Num~n)~=~n{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    49
\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    50
~~{"}evalb~env~(Less~a1~a2)~=~(evala~env~a1~<~evala~env~a2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    51
~~{"}evalb~env~(And~b1~b2)~=~(evalb~env~b1~{\isasymand}~evalb~env~b2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    52
~~{"}evalb~env~(Neg~b)~=~({\isasymnot}~evalb~env~b){"}%
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}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    57
\isacommand{consts}~substa~::~{"}('a~{\isasymRightarrow}~'b~aexp)~{\isasymRightarrow}~'a~aexp~{\isasymRightarrow}~'b~aexp{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    58
~~~~~~~substb~::~{"}('a~{\isasymRightarrow}~'b~aexp)~{\isasymRightarrow}~'a~bexp~{\isasymRightarrow}~'b~bexp{"}%
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
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    67
~~{"}substa~s~(IF~b~a1~a2)~=\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    68
~~~~~IF~(substb~s~b)~(substa~s~a1)~(substa~s~a2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    69
~~{"}substa~s~(Sum~a1~a2)~=~Sum~(substa~s~a1)~(substa~s~a2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    70
~~{"}substa~s~(Diff~a1~a2)~=~Diff~(substa~s~a1)~(substa~s~a2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    71
~~{"}substa~s~(Var~v)~=~s~v{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    72
~~{"}substa~s~(Num~n)~=~Num~n{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    73
\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    74
~~{"}substb~s~(Less~a1~a2)~=~Less~(substa~s~a1)~(substa~s~a2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    75
~~{"}substb~s~(And~b1~b2)~=~And~(substb~s~b1)~(substb~s~b2){"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    76
~~{"}substb~s~(Neg~b)~=~Neg~(substb~s~b){"}%
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}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    87
\isacommand{lemma}~{"}evala~env~(substa~s~a)~=~evala~({\isasymlambda}x.~evala~env~(s~x))~a~{\isasymand}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    88
~~~~~~~~evalb~env~(substb~s~b)~=~evalb~({\isasymlambda}x.~evala~env~(s~x))~b{"}\isanewline
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    89
\isacommand{apply}(induct\_tac~a~\isakeyword{and}~b)%
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}%
2665170f104a Adding generated files
nipkow
parents:
diff changeset
    94
\isacommand{apply}~auto\isacommand{.}%
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}
2665170f104a Adding generated files
nipkow
parents:
diff changeset
   105
  Define a function \isa{norma} of type \isa{'a aexp \isasymFun\ 'a aexp} that
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}%