author | paulson |
Wed, 18 May 2005 10:23:47 +0200 | |
changeset 15997 | c71031d7988c |
parent 15481 | fc075ae929e4 |
child 16069 | 3f2a9f400168 |
permissions | -rw-r--r-- |
10217 | 1 |
% |
2 |
\begin{isabellebody}% |
|
3 |
\def\isabellecontext{AB}% |
|
11866 | 4 |
\isamarkupfalse% |
10225 | 5 |
% |
10878 | 6 |
\isamarkupsection{Case Study: A Context Free Grammar% |
10395 | 7 |
} |
11866 | 8 |
\isamarkuptrue% |
10236 | 9 |
% |
10 |
\begin{isamarkuptext}% |
|
10242 | 11 |
\label{sec:CFG} |
11494 | 12 |
\index{grammars!defining inductively|(}% |
10236 | 13 |
Grammars are nothing but shorthands for inductive definitions of nonterminals |
14 |
which represent sets of strings. For example, the production |
|
15 |
$A \to B c$ is short for |
|
16 |
\[ w \in B \Longrightarrow wc \in A \] |
|
10878 | 17 |
This section demonstrates this idea with an example |
18 |
due to Hopcroft and Ullman, a grammar for generating all words with an |
|
19 |
equal number of $a$'s and~$b$'s: |
|
10236 | 20 |
\begin{eqnarray} |
21 |
S &\to& \epsilon \mid b A \mid a B \nonumber\\ |
|
22 |
A &\to& a S \mid b A A \nonumber\\ |
|
23 |
B &\to& b S \mid a B B \nonumber |
|
24 |
\end{eqnarray} |
|
10878 | 25 |
At the end we say a few words about the relationship between |
26 |
the original proof \cite[p.\ts81]{HopcroftUllman} and our formal version. |
|
10236 | 27 |
|
10299 | 28 |
We start by fixing the alphabet, which consists only of \isa{a}'s |
10878 | 29 |
and~\isa{b}'s:% |
10236 | 30 |
\end{isamarkuptext}% |
11866 | 31 |
\isamarkuptrue% |
32 |
\isacommand{datatype}\ alfa\ {\isacharequal}\ a\ {\isacharbar}\ b\isamarkupfalse% |
|
33 |
% |
|
10236 | 34 |
\begin{isamarkuptext}% |
35 |
\noindent |
|
10299 | 36 |
For convenience we include the following easy lemmas as simplification rules:% |
10236 | 37 |
\end{isamarkuptext}% |
11866 | 38 |
\isamarkuptrue% |
10236 | 39 |
\isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}x\ {\isasymnoteq}\ a{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}x\ {\isacharequal}\ b{\isacharparenright}\ {\isasymand}\ {\isacharparenleft}x\ {\isasymnoteq}\ b{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}x\ {\isacharequal}\ a{\isacharparenright}{\isachardoublequote}\isanewline |
11866 | 40 |
\isamarkupfalse% |
15481 | 41 |
\isamarkupfalse% |
11866 | 42 |
% |
10236 | 43 |
\begin{isamarkuptext}% |
44 |
\noindent |
|
45 |
Words over this alphabet are of type \isa{alfa\ list}, and |
|
10878 | 46 |
the three nonterminals are declared as sets of such words:% |
10236 | 47 |
\end{isamarkuptext}% |
11866 | 48 |
\isamarkuptrue% |
10217 | 49 |
\isacommand{consts}\ S\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}alfa\ list\ set{\isachardoublequote}\isanewline |
50 |
\ \ \ \ \ \ \ A\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}alfa\ list\ set{\isachardoublequote}\isanewline |
|
11866 | 51 |
\ \ \ \ \ \ \ B\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}alfa\ list\ set{\isachardoublequote}\isamarkupfalse% |
52 |
% |
|
10236 | 53 |
\begin{isamarkuptext}% |
54 |
\noindent |
|
10878 | 55 |
The productions above are recast as a \emph{mutual} inductive |
10242 | 56 |
definition\index{inductive definition!simultaneous} |
10878 | 57 |
of \isa{S}, \isa{A} and~\isa{B}:% |
10236 | 58 |
\end{isamarkuptext}% |
11866 | 59 |
\isamarkuptrue% |
10217 | 60 |
\isacommand{inductive}\ S\ A\ B\isanewline |
61 |
\isakeyword{intros}\isanewline |
|
10236 | 62 |
\ \ {\isachardoublequote}{\isacharbrackleft}{\isacharbrackright}\ {\isasymin}\ S{\isachardoublequote}\isanewline |
63 |
\ \ {\isachardoublequote}w\ {\isasymin}\ A\ {\isasymLongrightarrow}\ b{\isacharhash}w\ {\isasymin}\ S{\isachardoublequote}\isanewline |
|
64 |
\ \ {\isachardoublequote}w\ {\isasymin}\ B\ {\isasymLongrightarrow}\ a{\isacharhash}w\ {\isasymin}\ S{\isachardoublequote}\isanewline |
|
10217 | 65 |
\isanewline |
10236 | 66 |
\ \ {\isachardoublequote}w\ {\isasymin}\ S\ \ \ \ \ \ \ \ {\isasymLongrightarrow}\ a{\isacharhash}w\ \ \ {\isasymin}\ A{\isachardoublequote}\isanewline |
67 |
\ \ {\isachardoublequote}{\isasymlbrakk}\ v{\isasymin}A{\isacharsemicolon}\ w{\isasymin}A\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ b{\isacharhash}v{\isacharat}w\ {\isasymin}\ A{\isachardoublequote}\isanewline |
|
10217 | 68 |
\isanewline |
10236 | 69 |
\ \ {\isachardoublequote}w\ {\isasymin}\ S\ \ \ \ \ \ \ \ \ \ \ \ {\isasymLongrightarrow}\ b{\isacharhash}w\ \ \ {\isasymin}\ B{\isachardoublequote}\isanewline |
11866 | 70 |
\ \ {\isachardoublequote}{\isasymlbrakk}\ v\ {\isasymin}\ B{\isacharsemicolon}\ w\ {\isasymin}\ B\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ a{\isacharhash}v{\isacharat}w\ {\isasymin}\ B{\isachardoublequote}\isamarkupfalse% |
71 |
% |
|
10236 | 72 |
\begin{isamarkuptext}% |
73 |
\noindent |
|
10878 | 74 |
First we show that all words in \isa{S} contain the same number of \isa{a}'s and \isa{b}'s. Since the definition of \isa{S} is by mutual |
75 |
induction, so is the proof: we show at the same time that all words in |
|
10236 | 76 |
\isa{A} contain one more \isa{a} than \isa{b} and all words in \isa{B} contains one more \isa{b} than \isa{a}.% |
77 |
\end{isamarkuptext}% |
|
11866 | 78 |
\isamarkuptrue% |
10236 | 79 |
\isacommand{lemma}\ correctness{\isacharcolon}\isanewline |
80 |
\ \ {\isachardoublequote}{\isacharparenleft}w\ {\isasymin}\ S\ {\isasymlongrightarrow}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}a{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}b{\isacharbrackright}{\isacharparenright}\ \ \ \ \ {\isasymand}\isanewline |
|
10237 | 81 |
\ \ \ {\isacharparenleft}w\ {\isasymin}\ A\ {\isasymlongrightarrow}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}a{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}b{\isacharbrackright}\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}\ {\isasymand}\isanewline |
11866 | 82 |
\ \ \ {\isacharparenleft}w\ {\isasymin}\ B\ {\isasymlongrightarrow}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}b{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}a{\isacharbrackright}\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequote}\isamarkupfalse% |
83 |
\isamarkuptrue% |
|
15481 | 84 |
\isamarkupfalse% |
11866 | 85 |
% |
10236 | 86 |
\begin{isamarkuptext}% |
87 |
\noindent |
|
88 |
This may seem surprising at first, and is indeed an indication of the power |
|
89 |
of inductive definitions. But it is also quite straightforward. For example, |
|
90 |
consider the production $A \to b A A$: if $v,w \in A$ and the elements of $A$ |
|
10878 | 91 |
contain one more $a$ than~$b$'s, then $bvw$ must again contain one more $a$ |
92 |
than~$b$'s. |
|
10236 | 93 |
|
94 |
As usual, the correctness of syntactic descriptions is easy, but completeness |
|
95 |
is hard: does \isa{S} contain \emph{all} words with an equal number of |
|
96 |
\isa{a}'s and \isa{b}'s? It turns out that this proof requires the |
|
10878 | 97 |
following lemma: every string with two more \isa{a}'s than \isa{b}'s can be cut somewhere such that each half has one more \isa{a} than |
10236 | 98 |
\isa{b}. This is best seen by imagining counting the difference between the |
10283 | 99 |
number of \isa{a}'s and \isa{b}'s starting at the left end of the |
100 |
word. We start with 0 and end (at the right end) with 2. Since each move to the |
|
10236 | 101 |
right increases or decreases the difference by 1, we must have passed through |
102 |
1 on our way from 0 to 2. Formally, we appeal to the following discrete |
|
103 |
intermediate value theorem \isa{nat{\isadigit{0}}{\isacharunderscore}intermed{\isacharunderscore}int{\isacharunderscore}val} |
|
104 |
\begin{isabelle}% |
|
14379 | 105 |
\ \ \ \ \ {\isasymlbrakk}{\isasymforall}i{\isacharless}n{\isachardot}\ {\isasymbar}f\ {\isacharparenleft}i\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}\ {\isacharminus}\ f\ i{\isasymbar}\ {\isasymle}\ {\isadigit{1}}{\isacharsemicolon}\ f\ {\isadigit{0}}\ {\isasymle}\ k{\isacharsemicolon}\ k\ {\isasymle}\ f\ n{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isasymexists}i{\isasymle}n{\isachardot}\ f\ i\ {\isacharequal}\ k% |
10236 | 106 |
\end{isabelle} |
107 |
where \isa{f} is of type \isa{nat\ {\isasymRightarrow}\ int}, \isa{int} are the integers, |
|
11308 | 108 |
\isa{{\isasymbar}{\isachardot}{\isasymbar}} is the absolute value function\footnote{See |
109 |
Table~\ref{tab:ascii} in the Appendix for the correct \textsc{ascii} |
|
11708 | 110 |
syntax.}, and \isa{{\isadigit{1}}} is the integer 1 (see \S\ref{sec:numbers}). |
10236 | 111 |
|
11147 | 112 |
First we show that our specific function, the difference between the |
10236 | 113 |
numbers of \isa{a}'s and \isa{b}'s, does indeed only change by 1 in every |
114 |
move to the right. At this point we also start generalizing from \isa{a}'s |
|
115 |
and \isa{b}'s to an arbitrary property \isa{P}. Otherwise we would have |
|
116 |
to prove the desired lemma twice, once as stated above and once with the |
|
117 |
roles of \isa{a}'s and \isa{b}'s interchanged.% |
|
118 |
\end{isamarkuptext}% |
|
11866 | 119 |
\isamarkuptrue% |
10236 | 120 |
\isacommand{lemma}\ step{\isadigit{1}}{\isacharcolon}\ {\isachardoublequote}{\isasymforall}i\ {\isacharless}\ size\ w{\isachardot}\isanewline |
10608 | 121 |
\ \ {\isasymbar}{\isacharparenleft}int{\isacharparenleft}size{\isacharbrackleft}x{\isasymin}take\ {\isacharparenleft}i{\isacharplus}{\isadigit{1}}{\isacharparenright}\ w{\isachardot}\ P\ x{\isacharbrackright}{\isacharparenright}{\isacharminus}int{\isacharparenleft}size{\isacharbrackleft}x{\isasymin}take\ {\isacharparenleft}i{\isacharplus}{\isadigit{1}}{\isacharparenright}\ w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharparenright}{\isacharparenright}\isanewline |
11870
181bd2050cf4
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11866
diff
changeset
|
122 |
\ \ \ {\isacharminus}\ {\isacharparenleft}int{\isacharparenleft}size{\isacharbrackleft}x{\isasymin}take\ i\ w{\isachardot}\ P\ x{\isacharbrackright}{\isacharparenright}{\isacharminus}int{\isacharparenleft}size{\isacharbrackleft}x{\isasymin}take\ i\ w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharparenright}{\isacharparenright}{\isasymbar}\ {\isasymle}\ {\isadigit{1}}{\isachardoublequote}\isamarkupfalse% |
11866 | 123 |
\isamarkuptrue% |
15481 | 124 |
\isamarkupfalse% |
11866 | 125 |
\isamarkupfalse% |
15481 | 126 |
\isamarkupfalse% |
11866 | 127 |
% |
10236 | 128 |
\begin{isamarkuptext}% |
11494 | 129 |
Finally we come to the above-mentioned lemma about cutting in half a word with two more elements of one sort than of the other sort:% |
10236 | 130 |
\end{isamarkuptext}% |
11866 | 131 |
\isamarkuptrue% |
10236 | 132 |
\isacommand{lemma}\ part{\isadigit{1}}{\isacharcolon}\isanewline |
133 |
\ {\isachardoublequote}size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharplus}{\isadigit{2}}\ {\isasymLongrightarrow}\isanewline |
|
11866 | 134 |
\ \ {\isasymexists}i{\isasymle}size\ w{\isachardot}\ size{\isacharbrackleft}x{\isasymin}take\ i\ w{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}take\ i\ w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharplus}{\isadigit{1}}{\isachardoublequote}\isamarkupfalse% |
135 |
\isamarkuptrue% |
|
136 |
\isamarkupfalse% |
|
15481 | 137 |
\isamarkupfalse% |
11866 | 138 |
% |
10236 | 139 |
\begin{isamarkuptext}% |
140 |
\noindent |
|
141 |
||
142 |
Lemma \isa{part{\isadigit{1}}} tells us only about the prefix \isa{take\ i\ w}. |
|
10878 | 143 |
An easy lemma deals with the suffix \isa{drop\ i\ w}:% |
10236 | 144 |
\end{isamarkuptext}% |
11866 | 145 |
\isamarkuptrue% |
10236 | 146 |
\isacommand{lemma}\ part{\isadigit{2}}{\isacharcolon}\isanewline |
147 |
\ \ {\isachardoublequote}{\isasymlbrakk}size{\isacharbrackleft}x{\isasymin}take\ i\ w\ {\isacharat}\ drop\ i\ w{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharequal}\isanewline |
|
148 |
\ \ \ \ size{\isacharbrackleft}x{\isasymin}take\ i\ w\ {\isacharat}\ drop\ i\ w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharplus}{\isadigit{2}}{\isacharsemicolon}\isanewline |
|
149 |
\ \ \ \ size{\isacharbrackleft}x{\isasymin}take\ i\ w{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}take\ i\ w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharplus}{\isadigit{1}}{\isasymrbrakk}\isanewline |
|
150 |
\ \ \ {\isasymLongrightarrow}\ size{\isacharbrackleft}x{\isasymin}drop\ i\ w{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}drop\ i\ w{\isachardot}\ {\isasymnot}P\ x{\isacharbrackright}{\isacharplus}{\isadigit{1}}{\isachardoublequote}\isanewline |
|
11866 | 151 |
\isamarkupfalse% |
15481 | 152 |
\isamarkupfalse% |
11866 | 153 |
% |
10236 | 154 |
\begin{isamarkuptext}% |
155 |
\noindent |
|
11257 | 156 |
In the proof we have disabled the normally useful lemma |
10878 | 157 |
\begin{isabelle} |
158 |
\isa{take\ n\ xs\ {\isacharat}\ drop\ n\ xs\ {\isacharequal}\ xs} |
|
159 |
\rulename{append_take_drop_id} |
|
160 |
\end{isabelle} |
|
11257 | 161 |
to allow the simplifier to apply the following lemma instead: |
162 |
\begin{isabelle}% |
|
163 |
\ \ \ \ \ {\isacharbrackleft}x{\isasymin}xs{\isacharat}ys{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}x{\isasymin}xs{\isachardot}\ P\ x{\isacharbrackright}\ {\isacharat}\ {\isacharbrackleft}x{\isasymin}ys{\isachardot}\ P\ x{\isacharbrackright}% |
|
164 |
\end{isabelle} |
|
10236 | 165 |
|
166 |
To dispose of trivial cases automatically, the rules of the inductive |
|
167 |
definition are declared simplification rules:% |
|
168 |
\end{isamarkuptext}% |
|
11866 | 169 |
\isamarkuptrue% |
170 |
\isacommand{declare}\ S{\isacharunderscore}A{\isacharunderscore}B{\isachardot}intros{\isacharbrackleft}simp{\isacharbrackright}\isamarkupfalse% |
|
171 |
% |
|
10236 | 172 |
\begin{isamarkuptext}% |
173 |
\noindent |
|
174 |
This could have been done earlier but was not necessary so far. |
|
175 |
||
176 |
The completeness theorem tells us that if a word has the same number of |
|
10878 | 177 |
\isa{a}'s and \isa{b}'s, then it is in \isa{S}, and similarly |
178 |
for \isa{A} and \isa{B}:% |
|
10236 | 179 |
\end{isamarkuptext}% |
11866 | 180 |
\isamarkuptrue% |
10236 | 181 |
\isacommand{theorem}\ completeness{\isacharcolon}\isanewline |
182 |
\ \ {\isachardoublequote}{\isacharparenleft}size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}a{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}b{\isacharbrackright}\ \ \ \ \ {\isasymlongrightarrow}\ w\ {\isasymin}\ S{\isacharparenright}\ {\isasymand}\isanewline |
|
10237 | 183 |
\ \ \ {\isacharparenleft}size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}a{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}b{\isacharbrackright}\ {\isacharplus}\ {\isadigit{1}}\ {\isasymlongrightarrow}\ w\ {\isasymin}\ A{\isacharparenright}\ {\isasymand}\isanewline |
11866 | 184 |
\ \ \ {\isacharparenleft}size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}b{\isacharbrackright}\ {\isacharequal}\ size{\isacharbrackleft}x{\isasymin}w{\isachardot}\ x{\isacharequal}a{\isacharbrackright}\ {\isacharplus}\ {\isadigit{1}}\ {\isasymlongrightarrow}\ w\ {\isasymin}\ B{\isacharparenright}{\isachardoublequote}\isamarkupfalse% |
185 |
\isamarkuptrue% |
|
15481 | 186 |
\isamarkupfalse% |
187 |
\isamarkupfalse% |
|
188 |
\isamarkuptrue% |
|
189 |
\isamarkupfalse% |
|
190 |
\isamarkupfalse% |
|
11866 | 191 |
\isamarkupfalse% |
192 |
\isamarkuptrue% |
|
15481 | 193 |
\isamarkupfalse% |
194 |
\isamarkupfalse% |
|
195 |
\isamarkupfalse% |
|
11866 | 196 |
\isamarkupfalse% |
15481 | 197 |
\isamarkuptrue% |
198 |
\isamarkupfalse% |
|
199 |
\isamarkupfalse% |
|
11866 | 200 |
\isamarkuptrue% |
15481 | 201 |
\isamarkupfalse% |
202 |
\isamarkuptrue% |
|
203 |
\isamarkupfalse% |
|
204 |
\isamarkuptrue% |
|
205 |
\isamarkupfalse% |
|
206 |
\isamarkupfalse% |
|
11866 | 207 |
\isamarkuptrue% |
15481 | 208 |
\isamarkupfalse% |
11866 | 209 |
\isamarkupfalse% |
210 |
\isamarkupfalse% |
|
15481 | 211 |
\isamarkupfalse% |
11866 | 212 |
\isamarkupfalse% |
213 |
\isamarkupfalse% |
|
214 |
\isamarkupfalse% |
|
215 |
\isamarkupfalse% |
|
15481 | 216 |
\isamarkupfalse% |
11866 | 217 |
% |
10236 | 218 |
\begin{isamarkuptext}% |
10878 | 219 |
We conclude this section with a comparison of our proof with |
11494 | 220 |
Hopcroft\index{Hopcroft, J. E.} and Ullman's\index{Ullman, J. D.} |
221 |
\cite[p.\ts81]{HopcroftUllman}. |
|
222 |
For a start, the textbook |
|
11257 | 223 |
grammar, for no good reason, excludes the empty word, thus complicating |
224 |
matters just a little bit: they have 8 instead of our 7 productions. |
|
10236 | 225 |
|
11158 | 226 |
More importantly, the proof itself is different: rather than |
227 |
separating the two directions, they perform one induction on the |
|
228 |
length of a word. This deprives them of the beauty of rule induction, |
|
229 |
and in the easy direction (correctness) their reasoning is more |
|
230 |
detailed than our \isa{auto}. For the hard part (completeness), they |
|
231 |
consider just one of the cases that our \isa{simp{\isacharunderscore}all} disposes of |
|
232 |
automatically. Then they conclude the proof by saying about the |
|
233 |
remaining cases: ``We do this in a manner similar to our method of |
|
234 |
proof for part (1); this part is left to the reader''. But this is |
|
235 |
precisely the part that requires the intermediate value theorem and |
|
236 |
thus is not at all similar to the other cases (which are automatic in |
|
237 |
Isabelle). The authors are at least cavalier about this point and may |
|
238 |
even have overlooked the slight difficulty lurking in the omitted |
|
11494 | 239 |
cases. Such errors are found in many pen-and-paper proofs when they |
240 |
are scrutinized formally.% |
|
241 |
\index{grammars!defining inductively|)}% |
|
10236 | 242 |
\end{isamarkuptext}% |
11866 | 243 |
\isamarkuptrue% |
244 |
\isamarkupfalse% |
|
10217 | 245 |
\end{isabellebody}% |
246 |
%%% Local Variables: |
|
247 |
%%% mode: latex |
|
248 |
%%% TeX-master: "root" |
|
249 |
%%% End: |