4 |
4 |
5 \begin{document} |
5 \begin{document} |
6 |
6 |
7 \section*{Coursework 8 (Scala, Regular Expressions} |
7 \section*{Coursework 8 (Scala, Regular Expressions} |
8 |
8 |
9 This coursework is worth 10\%. It is about regular expressions and |
9 This coursework is worth 10\%. It is about regular expressions, |
10 pattern matching. The first part is due on 30 November at 11pm; the |
10 pattern matching and polymorphism. The first part is due on 30 |
11 second, more advanced part, is due on 7 December at 11pm. You are |
11 November at 11pm; the second, more advanced part, is due on 7 December |
12 asked to implement a regular expression matcher. Make sure the files |
12 at 11pm. You are asked to implement a regular expression matcher. Make |
13 you submit can be processed by just calling \texttt{scala |
13 sure the files you submit can be processed by just calling |
14 <<filename.scala>>}.\bigskip |
14 \texttt{scala <<filename.scala>>}.\bigskip |
15 |
15 |
16 \noindent |
16 \noindent |
17 \textbf{Important:} Do not use any mutable data structures in your |
17 \textbf{Important:} Do not use any mutable data structures in your |
18 submission! They are not needed. This excludes the use of |
18 submission! They are not needed. This excludes the use of |
19 \texttt{ListBuffer}s, for example. Do not use \texttt{return} in your |
19 \texttt{ListBuffer}s, for example. Do not use \texttt{return} in your |
63 \item[$\bullet$] \url{http://stackstatus.net/post/147710624694/outage-postmortem-july-20-2016} |
63 \item[$\bullet$] \url{http://stackstatus.net/post/147710624694/outage-postmortem-july-20-2016} |
64 \item[$\bullet$] \url{https://vimeo.com/112065252} |
64 \item[$\bullet$] \url{https://vimeo.com/112065252} |
65 \item[$\bullet$] \url{http://davidvgalbraith.com/how-i-fixed-atom/} |
65 \item[$\bullet$] \url{http://davidvgalbraith.com/how-i-fixed-atom/} |
66 \end{itemize}} |
66 \end{itemize}} |
67 |
67 |
68 \subsection*{Tasks (file re.scala)} |
68 \subsubsection*{Tasks (file re.scala)} |
69 |
69 |
70 \begin{itemize} |
70 \begin{itemize} |
71 \item[(1a)] Implement a function, called \textit{nullable}, by recursion over |
71 \item[(1a)] Implement a function, called \textit{nullable}, by recursion over |
72 regular expressions. This function tests whether a regular expression can match |
72 regular expressions. This function tests whether a regular expression can match |
73 the empty string. |
73 the empty string. |
157 \end{center} |
157 \end{center} |
158 |
158 |
159 For example the regular expression |
159 For example the regular expression |
160 \[(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)\] |
160 \[(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)\] |
161 |
161 |
162 simplifies to just $r_1$. |
162 simplifies to just $r_1$. \textbf{Hints:} Regular expressions can be |
163 \hfill[1 Mark] |
163 seen as trees and there are several methods for traversing |
|
164 trees. One of them corresponds to the inside-out traversal. Also |
|
165 remember numerical expressions from school: there you had exprssions |
|
166 like $u + \ldots + (1 \cdot x) * \ldots (z + (y \cdot 0)) \ldots$ |
|
167 and simplification rules that looked very similar to rules |
|
168 above. You would simplify such numerical expressions by replacing |
|
169 for example the $y \cdot 0$ by $0$, or $1\cdot x$ by $x$, and then |
|
170 look if more rules are applicable. If you organise this |
|
171 simplification in an inside-out fashion, it is always clear which |
|
172 rule should applied next.\\\mbox{}\hfill[1 Mark] |
164 |
173 |
165 \item[(1d)] Implement two functions: The first, called \textit{ders}, |
174 \item[(1d)] Implement two functions: The first, called \textit{ders}, |
166 takes a list of characters and a regular expression as arguments, and |
175 takes a list of characters and a regular expression as arguments, and |
167 builds the derivative w.r.t.~the list as follows: |
176 builds the derivative w.r.t.~the list as follows: |
168 |
177 |
213 You need to copy all the code from \texttt{re.scala} into |
222 You need to copy all the code from \texttt{re.scala} into |
214 \texttt{re2.scala} in order to complete Part 2. Parts (2a) and (2b) |
223 \texttt{re2.scala} in order to complete Part 2. Parts (2a) and (2b) |
215 give you another method and datapoints for testing the \textit{der} |
224 give you another method and datapoints for testing the \textit{der} |
216 and \textit{simp} functions from Part~1. |
225 and \textit{simp} functions from Part~1. |
217 |
226 |
218 \subsection*{Tasks (file re2.scala)} |
227 \subsubsection*{Tasks (file re2.scala)} |
219 |
228 |
220 \begin{itemize} |
229 \begin{itemize} |
221 \item[(2a)] Write a \textbf{polymorphic} function, called |
230 \item[(2a)] Write a \textbf{polymorphic} function, called |
222 \textit{iterT}, that is \textbf{tail-recursive}(!) and takes an |
231 \textit{iterT}, that is \textbf{tail-recursive}(!) and takes an |
223 integer $n$, a function $f$ and an $x$ as arguments. This function |
232 integer $n$, a function $f$ and an $x$ as arguments. This function |
238 \end{tabular} |
247 \end{tabular} |
239 \end{center} |
248 \end{center} |
240 |
249 |
241 Make sure you write a \textbf{tail-recursive} version of |
250 Make sure you write a \textbf{tail-recursive} version of |
242 \textit{iterT}. If you add the annotation \texttt{@tailrec} (see |
251 \textit{iterT}. If you add the annotation \texttt{@tailrec} (see |
243 below) you should not get an error message. |
252 below) your code should not produce an error message. |
244 |
253 |
245 \begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-1mm] |
254 \begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-1mm] |
246 import scala.annotation.tailrec |
255 import scala.annotation.tailrec |
247 |
256 |
248 @tailrec |
257 @tailrec |
251 |
260 |
252 You can assume that \textit{iterT} will only be called for positive |
261 You can assume that \textit{iterT} will only be called for positive |
253 integers $0 \le n$. Given the type variable \texttt{A}, the type of |
262 integers $0 \le n$. Given the type variable \texttt{A}, the type of |
254 $f$ is \texttt{A => A} and the type of $x$ is \texttt{A}. This means |
263 $f$ is \texttt{A => A} and the type of $x$ is \texttt{A}. This means |
255 \textit{iterT} can be used, for example, for functions from integers |
264 \textit{iterT} can be used, for example, for functions from integers |
256 to integers, or strings to strings. \\ \mbox{}\hfill[2 Marks] |
265 to integers, or strings to strings, or regular expressions to |
|
266 regular expressions. \\ \mbox{}\hfill[2 Marks] |
257 |
267 |
258 \item[(2b)] Implement a function, called \textit{size}, by recursion |
268 \item[(2b)] Implement a function, called \textit{size}, by recursion |
259 over regular expressions. If a regular expression is seen as a tree, |
269 over regular expressions. If a regular expression is seen as a tree, |
260 then \textit{size} should return the number of nodes in such a |
270 then \textit{size} should return the number of nodes in such a |
261 tree. Therefore this function is defined as follows: |
271 tree. Therefore this function is defined as follows: |
271 \end{tabular} |
281 \end{tabular} |
272 \end{center} |
282 \end{center} |
273 |
283 |
274 You can use \textit{size} and \textit{iterT} in order to test how much |
284 You can use \textit{size} and \textit{iterT} in order to test how much |
275 the 'evil' regular expression $(a^*)^* \cdot b$ grows when taking |
285 the 'evil' regular expression $(a^*)^* \cdot b$ grows when taking |
276 successive derivatives according the letter $a$ and compare it to |
286 successive derivatives according the letter $a$ and then compare it to |
277 taking the derivative, but simlifying the derivative after each step. |
287 taking the derivative, but simlifying the derivative after each step. |
278 For example, the calls |
288 For example, the calls |
279 |
289 |
280 \begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-1mm] |
290 \begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-1mm] |
281 size(iterT(20, (r: Rexp) => der('a', r), EVIL)) |
291 size(iterT(20, (r: Rexp) => der('a', r), EVIL)) |
282 size(iterT(20, (r: Rexp) => simp(der('a', r)), EVIL)) |
292 size(iterT(20, (r: Rexp) => simp(der('a', r)), EVIL)) |
283 \end{lstlisting} |
293 \end{lstlisting} |
284 |
294 |
285 produce without simplification a regular expression of size of |
295 produce without simplification a regular expression of size of |
286 7340068 for the derivative after 20 iterations, while the latter is |
296 7340068 after 20 iterations, while the one with |
|
297 simplification gives |
287 just 8.\\ \mbox{}\hfill[1 Mark] |
298 just 8.\\ \mbox{}\hfill[1 Mark] |
288 |
299 |
289 |
300 |
290 \item[(2c)] Write a \textbf{polymorphic} function, called |
301 \item[(2c)] Write a \textbf{polymorphic} function, called |
291 \textit{fixpT}, that takes |
302 \textit{fixpT}, that takes |