doc-src/TutorialI/Datatype/document/Nested.tex
changeset 9644 6b0b6b471855
parent 9541 d17c0b34d5c8
child 9689 751fde5307e4
equal deleted inserted replaced
9643:c94db1a96f4e 9644:6b0b6b471855
    11 \noindent
    11 \noindent
    12 Note that we need to quote \isa{term} on the left to avoid confusion with
    12 Note that we need to quote \isa{term} on the left to avoid confusion with
    13 the command \isacommand{term}.
    13 the command \isacommand{term}.
    14 Parameter \isa{'a} is the type of variables and \isa{'b} the type of
    14 Parameter \isa{'a} is the type of variables and \isa{'b} the type of
    15 function symbols.
    15 function symbols.
    16 A mathematical term like $f(x,g(y))$ becomes \isa{App\ f\ [Var\ x,\ App\ g\ [Var\ y]]}, where \isa{f}, \isa{g}, \isa{x}, \isa{y} are
    16 A mathematical term like $f(x,g(y))$ becomes \isa{App\ \mbox{f}\ [Var\ \mbox{x},\ App\ \mbox{g}\ [Var\ \mbox{y}]]}, where \isa{f}, \isa{g}, \isa{x}, \isa{y} are
    17 suitable values, e.g.\ numbers or strings.
    17 suitable values, e.g.\ numbers or strings.
    18 
    18 
    19 What complicates the definition of \isa{term} is the nested occurrence of
    19 What complicates the definition of \isa{term} is the nested occurrence of
    20 \isa{term} inside \isa{list} on the right-hand side. In principle,
    20 \isa{term} inside \isa{list} on the right-hand side. In principle,
    21 nested recursion can be eliminated in favour of mutual recursion by unfolding
    21 nested recursion can be eliminated in favour of mutual recursion by unfolding
    39 subst\ ::\ {"}('a{\isasymRightarrow}('a,'b)term)\ {\isasymRightarrow}\ ('a,'b)term\ \ \ \ \ \ {\isasymRightarrow}\ ('a,'b)term{"}\isanewline
    39 subst\ ::\ {"}('a{\isasymRightarrow}('a,'b)term)\ {\isasymRightarrow}\ ('a,'b)term\ \ \ \ \ \ {\isasymRightarrow}\ ('a,'b)term{"}\isanewline
    40 substs::\ {"}('a{\isasymRightarrow}('a,'b)term)\ {\isasymRightarrow}\ ('a,'b)term\ list\ {\isasymRightarrow}\ ('a,'b)term\ list{"}\isanewline
    40 substs::\ {"}('a{\isasymRightarrow}('a,'b)term)\ {\isasymRightarrow}\ ('a,'b)term\ list\ {\isasymRightarrow}\ ('a,'b)term\ list{"}\isanewline
    41 \isanewline
    41 \isanewline
    42 \isacommand{primrec}\isanewline
    42 \isacommand{primrec}\isanewline
    43 \ \ {"}subst\ s\ (Var\ x)\ =\ s\ x{"}\isanewline
    43 \ \ {"}subst\ s\ (Var\ x)\ =\ s\ x{"}\isanewline
       
    44 \ \ subst\_App:\isanewline
    44 \ \ {"}subst\ s\ (App\ f\ ts)\ =\ App\ f\ (substs\ s\ ts){"}\isanewline
    45 \ \ {"}subst\ s\ (App\ f\ ts)\ =\ App\ f\ (substs\ s\ ts){"}\isanewline
    45 \isanewline
    46 \isanewline
    46 \ \ {"}substs\ s\ []\ =\ []{"}\isanewline
    47 \ \ {"}substs\ s\ []\ =\ []{"}\isanewline
    47 \ \ {"}substs\ s\ (t\ \#\ ts)\ =\ subst\ s\ t\ \#\ substs\ s\ ts{"}%
    48 \ \ {"}substs\ s\ (t\ \#\ ts)\ =\ subst\ s\ t\ \#\ substs\ s\ ts{"}%
    48 \begin{isamarkuptext}%
    49 \begin{isamarkuptext}%
    49 \noindent
    50 \noindent
       
    51 You should ignore the label \isa{subst\_App} for the moment.
       
    52 
    50 Similarly, when proving a statement about terms inductively, we need
    53 Similarly, when proving a statement about terms inductively, we need
    51 to prove a related statement about term lists simultaneously. For example,
    54 to prove a related statement about term lists simultaneously. For example,
    52 the fact that the identity substitution does not change a term needs to be
    55 the fact that the identity substitution does not change a term needs to be
    53 strengthened and proved as follows:%
    56 strengthened and proved as follows:%
    54 \end{isamarkuptext}%
    57 \end{isamarkuptext}%
    56 \ \ \ \ \ \ \ \ substs\ Var\ ts\ =\ (ts::('a,'b)term\ list){"}\isanewline
    59 \ \ \ \ \ \ \ \ substs\ Var\ ts\ =\ (ts::('a,'b)term\ list){"}\isanewline
    57 \isacommand{by}(induct\_tac\ t\ \isakeyword{and}\ ts,\ auto)%
    60 \isacommand{by}(induct\_tac\ t\ \isakeyword{and}\ ts,\ auto)%
    58 \begin{isamarkuptext}%
    61 \begin{isamarkuptext}%
    59 \noindent
    62 \noindent
    60 Note that \isa{Var} is the identity substitution because by definition it
    63 Note that \isa{Var} is the identity substitution because by definition it
    61 leaves variables unchanged: \isa{subst\ Var\ (Var\ x)\ =\ Var\ x}. Note also
    64 leaves variables unchanged: \isa{subst\ Var\ (Var\ \mbox{x})\ =\ Var\ \mbox{x}}. Note also
    62 that the type annotations are necessary because otherwise there is nothing in
    65 that the type annotations are necessary because otherwise there is nothing in
    63 the goal to enforce that both halves of the goal talk about the same type
    66 the goal to enforce that both halves of the goal talk about the same type
    64 parameters \isa{('a,'b)}. As a result, induction would fail
    67 parameters \isa{('a,'b)}. As a result, induction would fail
    65 because the two halves of the goal would be unrelated.
    68 because the two halves of the goal would be unrelated.
    66 
    69 
    72 \end{ttbox}
    75 \end{ttbox}
    73 Correct this statement (you will find that it does not type-check),
    76 Correct this statement (you will find that it does not type-check),
    74 strengthen it, and prove it. (Note: \ttindexbold{o} is function composition;
    77 strengthen it, and prove it. (Note: \ttindexbold{o} is function composition;
    75 its definition is found in theorem \isa{o_def}).
    78 its definition is found in theorem \isa{o_def}).
    76 \end{exercise}
    79 \end{exercise}
       
    80 \begin{exercise}\label{ex:trev-trev}
       
    81   Define a function \isa{trev} of type \isa{(\mbox{'a},\ \mbox{'b})\ term\ {\isasymRightarrow}\ (\mbox{'a},\ \mbox{'b})\ term} that
       
    82   recursively reverses the order of arguments of all function symbols in a
       
    83   term. Prove that \isa{trev(trev t) = t}.
       
    84 \end{exercise}
       
    85 
       
    86 The experienced functional programmer may feel that our above definition of
       
    87 \isa{subst} is unnecessarily complicated in that \isa{substs} is completely
       
    88 unnecessary. The \isa{App}-case can be defined directly as
       
    89 \begin{quote}
       
    90 
       
    91 \begin{isabelle}%
       
    92 subst\ \mbox{s}\ (App\ \mbox{f}\ \mbox{ts})\ =\ App\ \mbox{f}\ (map\ (subst\ \mbox{s})\ \mbox{ts})
       
    93 \end{isabelle}%
       
    94 
       
    95 \end{quote}
       
    96 where \isa{map} is the standard list function such that
       
    97 \isa{map f [x1,...,xn] = [f x1,...,f xn]}. This is true, but Isabelle insists
       
    98 on the above fixed format. Fortunately, we can easily \emph{prove} that the
       
    99 suggested equation holds:%
       
   100 \end{isamarkuptext}%
       
   101 \isacommand{lemma}\ [simp]:\ {"}subst\ s\ (App\ f\ ts)\ =\ App\ f\ (map\ (subst\ s)\ ts){"}\isanewline
       
   102 \isacommand{by}(induct\_tac\ ts,\ auto)%
       
   103 \begin{isamarkuptext}%
       
   104 What is more, we can now disable the old defining equation as a
       
   105 simplification rule:%
       
   106 \end{isamarkuptext}%
       
   107 \isacommand{lemmas}\ [simp\ del]\ =\ subst\_App%
       
   108 \begin{isamarkuptext}%
       
   109 The advantage is that now we have replaced \isa{substs} by \isa{map},
       
   110 we can profit from the large number of pre-proved lemmas about \isa{map}.
       
   111 We illustrate this with an example, reversing terms:%
       
   112 \end{isamarkuptext}%
       
   113 \isacommand{consts}\ trev\ \ ::\ {"}('a,'b)term\ =>\ ('a,'b)term{"}\isanewline
       
   114 \ \ \ \ \ \ \ trevs\ ::\ {"}('a,'b)term\ list\ =>\ ('a,'b)term\ list{"}\isanewline
       
   115 \isacommand{primrec}\ \ \ {"}trev\ (Var\ x)\ =\ Var\ x{"}\isanewline
       
   116 trev\_App:\ {"}trev\ (App\ f\ ts)\ =\ App\ f\ (trevs\ ts){"}\isanewline
       
   117 \isanewline
       
   118 \ \ \ \ \ \ \ \ \ \ {"}trevs\ []\ =\ []{"}\isanewline
       
   119 \ \ \ \ \ \ \ \ \ \ {"}trevs\ (t\#ts)\ =\ trevs\ ts\ @\ [trev\ t]{"}%
       
   120 \begin{isamarkuptext}%
       
   121 \noindent
       
   122 Following the above methodology, we re-express \isa{trev\_App}:%
       
   123 \end{isamarkuptext}%
       
   124 \isacommand{lemma}\ [simp]:\ {"}trev\ (App\ f\ ts)\ =\ App\ f\ (rev(map\ trev\ ts)){"}\isanewline
       
   125 \isacommand{by}(induct\_tac\ ts,\ auto)\isanewline
       
   126 \isacommand{lemmas}\ [simp\ del]\ =\ trev\_App%
       
   127 \begin{isamarkuptext}%
       
   128 \noindent
       
   129 Now it becomes quite easy to prove \isa{trev\ (trev\ \mbox{t})\ =\ \mbox{t}}, except that we
       
   130 still have to come up with the second half of the conjunction:%
       
   131 \end{isamarkuptext}%
       
   132 \isacommand{lemma}\ {"}trev(trev\ t)\ =\ (t::('a,'b)term)\ \&\isanewline
       
   133 \ \ \ \ \ \ \ \ map\ trev\ (map\ trev\ ts)\ =\ (ts::('a,'b)term\ list){"}\isanewline
       
   134 \isacommand{by}(induct\_tac\ t\ \isakeyword{and}\ ts,\ auto\ simp\ add:rev\_map)%
       
   135 \begin{isamarkuptext}%
       
   136 \noindent
       
   137 Getting rid of this second conjunct requires deriving a new induction schema
       
   138 for \isa{term}, which is beyond what we have learned so far. Please stay
       
   139 tuned, we will solve this final problem in \S\ref{sec:der-ind-schemas}.
    77 
   140 
    78 Of course, you may also combine mutual and nested recursion. For example,
   141 Of course, you may also combine mutual and nested recursion. For example,
    79 constructor \isa{Sum} in \S\ref{sec:datatype-mut-rec} could take a list of
   142 constructor \isa{Sum} in \S\ref{sec:datatype-mut-rec} could take a list of
    80 expressions as its argument: \isa{Sum "'a aexp list"}.%
   143 expressions as its argument: \isa{Sum "'a aexp list"}.%
    81 \end{isamarkuptext}%
   144 \end{isamarkuptext}%