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}% |