cws/main_cw03.tex
changeset 396 3ffe978a5664
parent 390 175a950470a9
child 415 fced9a61c881
equal deleted inserted replaced
395:017f621f5835 396:3ffe978a5664
   117 \begin{document}
   117 \begin{document}
   118 
   118 
   119 % BF IDE
   119 % BF IDE
   120 % https://www.microsoft.com/en-us/p/brainf-ck/9nblgggzhvq5
   120 % https://www.microsoft.com/en-us/p/brainf-ck/9nblgggzhvq5
   121   
   121   
   122 \section*{Main Part 3 (Scala, 7 Marks)}
   122 \section*{Main Part 3 (Scala, 6 Marks)}
   123 
   123 
   124 %\mbox{}\hfill\textit{``[Google’s MapReduce] abstraction is inspired by the}\\
   124 %\mbox{}\hfill\textit{``[Google’s MapReduce] abstraction is inspired by the}\\
   125 %\mbox{}\hfill\textit{map and reduce primitives present in Lisp and many}\\
   125 %\mbox{}\hfill\textit{map and reduce primitives present in Lisp and many}\\
   126 %\mbox{}\hfill\textit{other functional language.''}\smallskip\\
   126 %\mbox{}\hfill\textit{other functional language.''}\smallskip\\
   127 %\mbox{}\hfill\textit{ --- Dean and Ghemawat, who designed this concept at Google}
   127 %\mbox{}\hfill\textit{ --- Dean and Ghemawat, who designed this concept at Google}
   148 This Scala assignment comes with a reference implementation in form of
   148 This Scala assignment comes with a reference implementation in form of
   149 a \texttt{jar}-file. This allows you to run any test cases on your own
   149 a \texttt{jar}-file. This allows you to run any test cases on your own
   150 computer. For example you can call Scala on the command line with the
   150 computer. For example you can call Scala on the command line with the
   151 option \texttt{-cp re.jar} and then query any function from the
   151 option \texttt{-cp re.jar} and then query any function from the
   152 \texttt{re.scala} template file. As usual you have to prefix the calls
   152 \texttt{re.scala} template file. As usual you have to prefix the calls
   153 with \texttt{CW8c} or import this object.  Since some tasks
   153 with \texttt{M3} or import this object.  Since some tasks
   154 are time sensitive, you can check the reference implementation as
   154 are time sensitive, you can check the reference implementation as
   155 follows: if you want to know, for example, how long it takes to match
   155 follows: if you want to know, for example, how long it takes to match
   156 strings of $a$'s using the regular expression $(a^*)^*\cdot b$ you can
   156 strings of $a$'s using the regular expression $(a^*)^*\cdot b$ you can
   157 query as follows:
   157 query as follows:
   158 
   158 
   159 
   159 
   160 \begin{lstlisting}[xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small]
   160 \begin{lstlisting}[xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small]
   161 $ scala -cp re.jar
   161 $ scala -cp re.jar
   162 scala> import CW8c._  
   162 scala> import M3._  
   163 scala> for (i <- 0 to 5000000 by 500000) {
   163 scala> for (i <- 0 to 5000000 by 500000) {
   164   | println(f"$i: ${time_needed(2, matcher(EVIL, "a" * i))}%.5f secs.")
   164   | println(f"$i: ${time_needed(2, matcher(EVIL, "a" * i))}%.5f secs.")
   165   | }
   165   | }
   166 0: 0.00002 secs.
   166 0: 0.00002 secs.
   167 500000: 0.10608 secs.
   167 500000: 0.10608 secs.
   228   \begin{tabular}{rcl@{\hspace{10mm}}l}
   228   \begin{tabular}{rcl@{\hspace{10mm}}l}
   229     & & code: & shorthand:\smallskip \\ 
   229     & & code: & shorthand:\smallskip \\ 
   230   $\ZERO$ & $\mapsto$ & \texttt{ZERO}\\
   230   $\ZERO$ & $\mapsto$ & \texttt{ZERO}\\
   231   $\ONE$  & $\mapsto$ & \texttt{ONE}\\
   231   $\ONE$  & $\mapsto$ & \texttt{ONE}\\
   232   $c$     & $\mapsto$ & \texttt{CHAR(c)}\\
   232   $c$     & $\mapsto$ & \texttt{CHAR(c)}\\
       
   233   $\sum rs$ & $\mapsto$ & \texttt{ALTs(rs)}\\  
   233   $r_1 + r_2$ & $\mapsto$ & \texttt{ALT(r1, r2)} & \texttt{r1 | r2}\\
   234   $r_1 + r_2$ & $\mapsto$ & \texttt{ALT(r1, r2)} & \texttt{r1 | r2}\\
   234   $r_1 \cdot r_2$ & $\mapsto$ & \texttt{SEQ(r1, r2)} & \texttt{r1 $\sim$ r2}\\
   235   $r_1 \cdot r_2$ & $\mapsto$ & \texttt{SEQ(r1, r2)} & \texttt{r1 $\sim$ r2}\\
   235   $r^*$ & $\mapsto$ &  \texttt{STAR(r)} & \texttt{r.\%}
   236   $r^*$ & $\mapsto$ &  \texttt{STAR(r)} & \texttt{r.\%}
   236 \end{tabular}    
   237 \end{tabular}    
   237 \end{center}  
   238 \end{center}  
   238 
   239 
       
   240 \noindent
       
   241 The alternative regular expressions comes in two versions: one is
       
   242 binary (+ / \texttt{ALT}) and the other is n-ary ($\sum$ /
       
   243 \texttt{ALTs}). The latter takes a list of regular expressions as
       
   244 arguments.  In what follows we shall use $rs$ to stand for lists of
       
   245 regular expressions.  The binary alternative can be seen as an abbreviation,
       
   246 that is $r_1 + r_2 \dn \sum\,[r_1, r_2]$. As a result we can ignore the
       
   247 binary version and only implement the n-ary alternative.
   239 
   248 
   240 \begin{itemize}
   249 \begin{itemize}
   241 \item[(1)] Implement a function, called \textit{nullable}, by
   250 \item[(1)] Implement a function, called \textit{nullable}, by
   242   recursion over regular expressions. This function tests whether a
   251   recursion over regular expressions. This function tests whether a
   243   regular expression can match the empty string. This means given a
   252   regular expression can match the empty string. This means given a
   248 \begin{center}
   257 \begin{center}
   249 \begin{tabular}{lcl}
   258 \begin{tabular}{lcl}
   250 $\textit{nullable}(\ZERO)$ & $\dn$ & $\textit{false}$\\
   259 $\textit{nullable}(\ZERO)$ & $\dn$ & $\textit{false}$\\
   251 $\textit{nullable}(\ONE)$  & $\dn$ & $\textit{true}$\\
   260 $\textit{nullable}(\ONE)$  & $\dn$ & $\textit{true}$\\
   252 $\textit{nullable}(c)$     & $\dn$ & $\textit{false}$\\
   261 $\textit{nullable}(c)$     & $\dn$ & $\textit{false}$\\
   253 $\textit{nullable}(r_1 + r_2)$ & $\dn$ & $\textit{nullable}(r_1) \vee \textit{nullable}(r_2)$\\
   262 $\textit{nullable}(\sum rs)$ & $\dn$ & $\exists r \in rs.\;\textit{nullable}(r)$\\
   254 $\textit{nullable}(r_1 \cdot r_2)$ & $\dn$ & $\textit{nullable}(r_1) \wedge \textit{nullable}(r_2)$\\
   263 $\textit{nullable}(r_1 \cdot r_2)$ & $\dn$ & $\textit{nullable}(r_1) \wedge \textit{nullable}(r_2)$\\
   255 $\textit{nullable}(r^*)$ & $\dn$ & $\textit{true}$\\
   264 $\textit{nullable}(r^*)$ & $\dn$ & $\textit{true}$\\
   256 \end{tabular}
   265 \end{tabular}
   257 \end{center}~\hfill[1 Mark]
   266 \end{center}~\hfill[0.5 Marks]
   258 
   267 
   259 \item[(2)] Implement a function, called \textit{der}, by recursion over
   268 \item[(2)] Implement a function, called \textit{der}, by recursion over
   260   regular expressions. It takes a character and a regular expression
   269   regular expressions. It takes a character and a regular expression
   261   as arguments and calculates the derivative of a regular expression according
   270   as arguments and calculates the derivative of a regular expression according
   262   to the rules:
   271   to the rules:
   264 \begin{center}
   273 \begin{center}
   265 \begin{tabular}{lcl}
   274 \begin{tabular}{lcl}
   266 $\textit{der}\;c\;(\ZERO)$ & $\dn$ & $\ZERO$\\
   275 $\textit{der}\;c\;(\ZERO)$ & $\dn$ & $\ZERO$\\
   267 $\textit{der}\;c\;(\ONE)$  & $\dn$ & $\ZERO$\\
   276 $\textit{der}\;c\;(\ONE)$  & $\dn$ & $\ZERO$\\
   268 $\textit{der}\;c\;(d)$     & $\dn$ & $\textit{if}\; c = d\;\textit{then} \;\ONE \; \textit{else} \;\ZERO$\\
   277 $\textit{der}\;c\;(d)$     & $\dn$ & $\textit{if}\; c = d\;\textit{then} \;\ONE \; \textit{else} \;\ZERO$\\
   269 $\textit{der}\;c\;(r_1 + r_2)$ & $\dn$ & $(\textit{der}\;c\;r_1) + (\textit{der}\;c\;r_2)$\\
   278 $\textit{der}\;c\;(\sum\;[r_1,..,r_n])$ & $\dn$ & $\sum\;[\textit{der}\;c\;r_1,..,\textit{der}\;c\;r_n]$\\
   270 $\textit{der}\;c\;(r_1 \cdot r_2)$ & $\dn$ & $\textit{if}\;\textit{nullable}(r_1)$\\
   279 $\textit{der}\;c\;(r_1 \cdot r_2)$ & $\dn$ & $\textit{if}\;\textit{nullable}(r_1)$\\
   271       & & $\textit{then}\;((\textit{der}\;c\;r_1)\cdot r_2) + (\textit{der}\;c\;r_2)$\\
   280       & & $\textit{then}\;((\textit{der}\;c\;r_1)\cdot r_2) + (\textit{der}\;c\;r_2)$\\
   272       & & $\textit{else}\;(\textit{der}\;c\;r_1)\cdot r_2$\\
   281       & & $\textit{else}\;(\textit{der}\;c\;r_1)\cdot r_2$\\
   273 $\textit{der}\;c\;(r^*)$ & $\dn$ & $(\textit{der}\;c\;r)\cdot (r^*)$\\
   282 $\textit{der}\;c\;(r^*)$ & $\dn$ & $(\textit{der}\;c\;r)\cdot (r^*)$\\
   274 \end{tabular}
   283 \end{tabular}
   310 \end{center}
   319 \end{center}
   311 
   320 
   312 Note, the last derivative can match the empty string, that is it is \textit{nullable}.\\
   321 Note, the last derivative can match the empty string, that is it is \textit{nullable}.\\
   313 \mbox{}\hfill\mbox{[1 Mark]}
   322 \mbox{}\hfill\mbox{[1 Mark]}
   314 
   323 
   315 \item[(3)] Implement the function \textit{simp}, which recursively
   324 \item[(3)] We next want to simplify regular expressions: essentially
       
   325   we want to remove $\ZERO$ in regular expressions like $r + \ZERO$
       
   326   and $\ZERO + r$.  However, our n-ary alternative takes a list of
       
   327   regular expressions as argument, we therefore need a more general
       
   328   ``flatten'' function, called \texttt{flts}. This function should
       
   329   analyse a list of regular expressions, say $rs$, as follows:
       
   330 
       
   331   \begin{center}
       
   332     \begin{tabular}{lllll}
       
   333       1) &$rs = []$                & $\dn$ & $[]$ & (empty list)\\
       
   334       2) &$rs = \ZERO :: rest$     & $\dn$ & $\textrm{flatten}\;rest$\\
       
   335       3) &$rs = (\sum rs_1) :: rest$ & $\dn$ & $rs_1 ::: \textrm{flatten}\;rest$\\
       
   336       4) &$rs = r :: rest$         & $\dn$ & $r :: \textrm{flatten}\;rest$ & (otherwise)\\
       
   337     \end{tabular}  
       
   338   \end{center}  
       
   339 
       
   340   The first clause just states that empty lists cannot be further
       
   341   flattened. The second removes all $\ZERO$s from the list.
       
   342   The third is when the first regular expression is an \texttt{ALTs}, then
       
   343   the content of this alternative should be spilled out and appended
       
   344   with the flattened rest of the list. The last case is for all other
       
   345   cases where the head of the list is not $\ZERO$ and not an \texttt{ALTs},
       
   346   then we just keep the head of the list and flatten the rest.
       
   347   \mbox{}\hfill\mbox{[1 Mark]}
       
   348 
       
   349 \item[(4)] Implement the function \textit{simp}, which recursively
   316   traverses a regular expression, and on the way up simplifies every
   350   traverses a regular expression, and on the way up simplifies every
   317   regular expression on the left (see below) to the regular expression
   351   regular expression on the left (see below) to the regular expression
   318   on the right, except it does not simplify inside ${}^*$-regular
   352   on the right, except it does not simplify inside ${}^*$-regular
   319   expressions.
   353   expressions.
   320 
   354 
   322 \begin{tabular}{l@{\hspace{4mm}}c@{\hspace{4mm}}ll}
   356 \begin{tabular}{l@{\hspace{4mm}}c@{\hspace{4mm}}ll}
   323 $r \cdot \ZERO$ & $\mapsto$ & $\ZERO$\\ 
   357 $r \cdot \ZERO$ & $\mapsto$ & $\ZERO$\\ 
   324 $\ZERO \cdot r$ & $\mapsto$ & $\ZERO$\\ 
   358 $\ZERO \cdot r$ & $\mapsto$ & $\ZERO$\\ 
   325 $r \cdot \ONE$ & $\mapsto$ & $r$\\ 
   359 $r \cdot \ONE$ & $\mapsto$ & $r$\\ 
   326 $\ONE \cdot r$ & $\mapsto$ & $r$\\ 
   360 $\ONE \cdot r$ & $\mapsto$ & $r$\\ 
   327 $r + \ZERO$ & $\mapsto$ & $r$\\ 
   361 $\sum\;[r_1,..,r_n]$ & $\mapsto$ & $\sum\;(\texttt{(flts + distinct)}[simp(r_1),..,simp(r_n)])$\\  
   328 $\ZERO + r$ & $\mapsto$ & $r$\\ 
       
   329 $r + r$ & $\mapsto$ & $r$\\ 
       
   330 \end{tabular}
   362 \end{tabular}
   331   \end{center}
   363 \end{center}
       
   364 
       
   365   The last case is as follows: first apply $simp$ to all regular expressions
       
   366   $r_1,.. ,r_n$; then flatten the resulting list using \texttt{flts};
       
   367   finally remove all duplicates in this list (this can be done in Scala
       
   368   using the function \texttt{\_.distinct}).
   332 
   369 
   333   For example the regular expression
   370   For example the regular expression
   334   \[(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)\]
   371   \[(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)\]
   335 
   372 
   336   simplifies to just $r_1$. \textbf{Hint:} Regular expressions can be
   373   simplifies to just $r_1$. \textbf{Hint:} Regular expressions can be
   337   seen as trees and there are several methods for traversing
   374   seen as trees and there are several methods for traversing
   338   trees. One of them corresponds to the inside-out traversal, which is also
   375   trees. One of them corresponds to the inside-out traversal, which is
   339   sometimes called post-order tra\-versal: you traverse inside the
   376   also sometimes called post-order tra\-versal: you traverse inside
   340   tree and on the way up you apply simplification rules.
   377   the tree and on the way up you apply simplification rules.
   341   \textbf{Another Hint:}
   378   \textbf{Another Hint:} Remember numerical expressions from school
   342   Remember numerical expressions from school times---there you had expressions
   379   times---there you had expressions like
   343   like $u + \ldots + (1 \cdot x) - \ldots (z + (y \cdot 0)) \ldots$
   380   $u + \ldots + (1 \cdot x) - \ldots (z + (y \cdot 0)) \ldots$ and
   344   and simplification rules that looked very similar to rules
   381   simplification rules that looked very similar to rules above. You
   345   above. You would simplify such numerical expressions by replacing
   382   would simplify such numerical expressions by replacing for example
   346   for example the $y \cdot 0$ by $0$, or $1\cdot x$ by $x$, and then
   383   the $y \cdot 0$ by $0$, or $1\cdot x$ by $x$, and then look whether
   347   look whether more rules are applicable. If you organise the
   384   more rules are applicable. If you regard regular expressions as
   348   simplification in an inside-out fashion, it is always clear which
   385   trees and if you organise the simplification in an inside-out
   349   simplification should be applied next.\hfill[1 Mark]
   386   fashion, it is always clear which simplification should be applied
   350 
   387   next.\mbox{}\hfill\mbox{[1 Mark]}
   351 \item[(4)] Implement two functions: The first, called \textit{ders},
   388 
       
   389 \item[(5)] Implement two functions: The first, called \textit{ders},
   352   takes a list of characters and a regular expression as arguments, and
   390   takes a list of characters and a regular expression as arguments, and
   353   builds the derivative w.r.t.~the list as follows:
   391   builds the derivative w.r.t.~the list as follows:
   354 
   392 
   355 \begin{center}
   393 \begin{center}
   356 \begin{tabular}{lcl}
   394 \begin{tabular}{lcl}
   369 derivative regular expression can match the empty string (using
   407 derivative regular expression can match the empty string (using
   370 \textit{nullable}).  For example the \textit{matcher} will produce
   408 \textit{nullable}).  For example the \textit{matcher} will produce
   371 true for the regular expression $(a\cdot b)\cdot c$ and the string
   409 true for the regular expression $(a\cdot b)\cdot c$ and the string
   372 $abc$, but false if you give it the string $ab$. \hfill[1 Mark]
   410 $abc$, but false if you give it the string $ab$. \hfill[1 Mark]
   373 
   411 
   374 \item[(5)] Implement a function, called \textit{size}, by recursion
   412 \item[(6)] Implement a function, called \textit{size}, by recursion
   375   over regular expressions. If a regular expression is seen as a tree,
   413   over regular expressions. If a regular expression is seen as a tree,
   376   then \textit{size} should return the number of nodes in such a
   414   then \textit{size} should return the number of nodes in such a
   377   tree. Therefore this function is defined as follows:
   415   tree. Therefore this function is defined as follows:
   378 
   416 
   379 \begin{center}
   417 \begin{center}
   380 \begin{tabular}{lcl}
   418 \begin{tabular}{lcl}
   381 $\textit{size}(\ZERO)$ & $\dn$ & $1$\\
   419 $\textit{size}(\ZERO)$ & $\dn$ & $1$\\
   382 $\textit{size}(\ONE)$  & $\dn$ & $1$\\
   420 $\textit{size}(\ONE)$  & $\dn$ & $1$\\
   383 $\textit{size}(c)$     & $\dn$ & $1$\\
   421 $\textit{size}(c)$     & $\dn$ & $1$\\
   384 $\textit{size}(r_1 + r_2)$ & $\dn$ & $1 + \textit{size}(r_1) + \textit{size}(r_2)$\\
   422 $\textit{size}(\sum\,[r_1,..,r_n]$ & $\dn$ & $1 + \textit{size}(r_1) + ... + \textit{size}(r_n)$\\
   385 $\textit{size}(r_1 \cdot r_2)$ & $\dn$ & $1 + \textit{size}(r_1) + \textit{size}(r_2)$\\
   423 $\textit{size}(r_1 \cdot r_2)$ & $\dn$ & $1 + \textit{size}(r_1) + \textit{size}(r_2)$\\
   386 $\textit{size}(r^*)$ & $\dn$ & $1 + \textit{size}(r)$\\
   424 $\textit{size}(r^*)$ & $\dn$ & $1 + \textit{size}(r)$\\
   387 \end{tabular}
   425 \end{tabular}
   388 \end{center}
   426 \end{center}
   389 
   427 
   390 You can use \textit{size} in order to test how much the ``evil'' regular
   428 You can use \textit{size} in order to test how much the ``evil'' regular
   391 expression $(a^*)^* \cdot b$ grows when taking successive derivatives
   429 expression $(a^*)^* \cdot b$ grows when taking successive derivatives
   392 according the letter $a$ without simplification and then compare it to
   430 according the letter $a$ without simplification and then compare it to
   393 taking the derivative, but simplify the result.  The sizes
   431 taking the derivative, but simplify the result.  The sizes
   394 are given in \texttt{re.scala}. \hfill[1 Mark]
   432 are given in \texttt{re.scala}. \hfill[0.5 Marks]
   395 
   433 
   396 \item[(6)] You do not have to implement anything specific under this
   434 \item[(7)] You do not have to implement anything specific under this
   397   task.  The purpose here is that you will be marked for some ``power''
   435   task.  The purpose here is that you will be marked for some ``power''
   398   test cases. For example can your matcher decide within 30 seconds
   436   test cases. For example can your matcher decide within 30 seconds
   399   whether the regular expression $(a^*)^*\cdot b$ matches strings of the
   437   whether the regular expression $(a^*)^*\cdot b$ matches strings of the
   400   form $aaa\ldots{}aaaa$, for say 1 Million $a$'s. And does simplification
   438   form $aaa\ldots{}aaaa$, for say 1 Million $a$'s. And does simplification
   401   simplify the regular expression
   439   simplify the regular expression
   404   \texttt{SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE)}
   442   \texttt{SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE)}
   405   \]  
   443   \]  
   406 
   444 
   407   \noindent correctly to just \texttt{ONE}, where \texttt{SEQ} is nested
   445   \noindent correctly to just \texttt{ONE}, where \texttt{SEQ} is nested
   408   50 or more times?\\
   446   50 or more times?\\
   409   \mbox{}\hfill[2 Marks]
   447   \mbox{}\hfill[1 Mark]
   410 \end{itemize}
   448 \end{itemize}
   411 
   449 
   412 \subsection*{Background}
   450 \subsection*{Background}
   413 
   451 
   414 Although easily implementable in Scala, the idea behind the derivative
   452 Although easily implementable in Scala (ok maybe the \texttt{simp} functions and
   415 function might not so easy to be seen. To understand its purpose
   453 \texttt{ALTs} needs a bit more thinking), the idea behind the
   416 better, assume a regular expression $r$ can match strings of the form
   454 derivative function might not so easy to be seen. To understand its
   417 $c\!::\!cs$ (that means strings which start with a character $c$ and have
   455 purpose better, assume a regular expression $r$ can match strings of
   418 some rest, or tail, $cs$). If you take the derivative of $r$ with
   456 the form $c\!::\!cs$ (that means strings which start with a character
   419 respect to the character $c$, then you obtain a regular expression
   457 $c$ and have some rest, or tail, $cs$). If you take the derivative of
   420 that can match all the strings $cs$.  In other words, the regular
   458 $r$ with respect to the character $c$, then you obtain a regular
   421 expression $\textit{der}\;c\;r$ can match the same strings $c\!::\!cs$
   459 expression that can match all the strings $cs$.  In other words, the
   422 that can be matched by $r$, except that the $c$ is chopped off.
   460 regular expression $\textit{der}\;c\;r$ can match the same strings
       
   461 $c\!::\!cs$ that can be matched by $r$, except that the $c$ is chopped
       
   462 off.
   423 
   463 
   424 Assume now $r$ can match the string $abc$. If you take the derivative
   464 Assume now $r$ can match the string $abc$. If you take the derivative
   425 according to $a$ then you obtain a regular expression that can match
   465 according to $a$ then you obtain a regular expression that can match
   426 $bc$ (it is $abc$ where the $a$ has been chopped off). If you now
   466 $bc$ (it is $abc$ where the $a$ has been chopped off). If you now
   427 build the derivative $\textit{der}\;b\;(\textit{der}\;a\;r)$ you
   467 build the derivative $\textit{der}\;b\;(\textit{der}\;a\;r)$ you
   449 
   489 
   450 If you want to see how badly the regular expression matchers do in
   490 If you want to see how badly the regular expression matchers do in
   451 Java\footnote{Version 8 and below; Version 9 and above does not seem to be as
   491 Java\footnote{Version 8 and below; Version 9 and above does not seem to be as
   452   catastrophic, but still much worse than the regular expression
   492   catastrophic, but still much worse than the regular expression
   453   matcher based on derivatives.}, JavaScript and Python with the
   493   matcher based on derivatives.}, JavaScript and Python with the
   454 `evil' regular expression $(a^*)^*\cdot b$, then have a look at the
   494 ``evil'' regular expression $(a^*)^*\cdot b$, then have a look at the
   455 graphs below (you can try it out for yourself: have a look at the files
   495 graphs below (you can try it out for yourself: have a look at the files
   456 \texttt{catastrophic9.java}, \texttt{catastrophic.js},
   496 \texttt{catastrophic9.java}, \texttt{catastrophic.js},
   457 \texttt{catastrophic.py} etc on KEATS). Compare this with the matcher you
   497 \texttt{catastrophic.py} etc on KEATS). Compare this with the matcher you
   458 have implemented. How long can the string of $a$'s be in your matcher
   498 have implemented. How long can a string of $a$'s be in your matcher
   459 and still stay within the 30 seconds time limit?
   499 and still stay within the 30 seconds time limit? It should be muuuch better
       
   500 than your off-the-shelf matcher in your bog-standard language.
   460 
   501 
   461 \begin{center}
   502 \begin{center}
   462 \begin{tabular}{@{}cc@{}}
   503 \begin{tabular}{@{}cc@{}}
   463 \multicolumn{2}{c}{Graph: $(a^*)^*\cdot b$ and strings 
   504 \multicolumn{2}{c}{Graph: $(a^*)^*\cdot b$ and strings 
   464            $\underbrace{a\ldots a}_{n}$}\bigskip\\
   505            $\underbrace{a\ldots a}_{n}$}\bigskip\\
   475     ymax=45,
   516     ymax=45,
   476     ytick={0,5,...,40},
   517     ytick={0,5,...,40},
   477     scaled ticks=false,
   518     scaled ticks=false,
   478     axis lines=left,
   519     axis lines=left,
   479     width=6cm,
   520     width=6cm,
   480     height=5.5cm, 
   521     height=5.0cm, 
   481     legend entries={Python, Java 8, JavaScript, Swift, Dart},  
   522     legend entries={Python, Java 8, JavaScript, Swift, Dart},  
   482     legend pos=north west,
   523     legend pos=north west,
   483     legend cell align=left]
   524     legend cell align=left]
   484 \addplot[blue,mark=*, mark options={fill=white}] table {re-python2.data};
   525 \addplot[blue,mark=*, mark options={fill=white}] table {re-python2.data};
   485 \addplot[cyan,mark=*, mark options={fill=white}] table {re-java.data};
   526 \addplot[cyan,mark=*, mark options={fill=white}] table {re-java.data};
   501     ymax=45,
   542     ymax=45,
   502     ytick={0,5,...,40},
   543     ytick={0,5,...,40},
   503     scaled ticks=false,
   544     scaled ticks=false,
   504     axis lines=left,
   545     axis lines=left,
   505     width=6cm,
   546     width=6cm,
   506     height=5.5cm, 
   547     height=5.0cm, 
   507     legend entries={Java 9},  
   548     legend entries={Java 9},  
   508     legend pos=north west]
   549     legend pos=north west]
   509 \addplot[cyan,mark=*, mark options={fill=white}] table {re-java9.data};
   550 \addplot[cyan,mark=*, mark options={fill=white}] table {re-java9.data};
   510 \end{axis}
   551 \end{axis}
   511 \end{tikzpicture}
   552 \end{tikzpicture}