handouts/ho02.tex
changeset 488 598741d39d21
parent 481 acd8780bfc8b
child 492 39b7ff2cf1bc
equal deleted inserted replaced
487:a697421eaa04 488:598741d39d21
    50 \end{tikzpicture}
    50 \end{tikzpicture}
    51 &
    51 &
    52 \begin{tikzpicture}
    52 \begin{tikzpicture}
    53   \begin{axis}[
    53   \begin{axis}[
    54     xlabel={$n$},
    54     xlabel={$n$},
    55     x label style={at={(1.05,0.0)}},
    55     x label style={at={(1.1,0.0)}},
       
    56     %%xtick={0,1000000,...,5000000}, 
    56     ylabel={time in secs},
    57     ylabel={time in secs},
    57     enlargelimits=false,
    58     enlargelimits=false,
    58     ymax=35,
    59     ymax=35,
    59     ytick={0,5,...,30},
    60     ytick={0,5,...,30},
    60     axis lines=left,
    61     axis lines=left,
    61     scaled ticks=false,
    62     %scaled ticks=false,
    62     width=6.5cm,
    63     width=6.5cm,
    63     height=5cm,
    64     height=5cm,
    64     legend entries={Scala V3},  
    65     legend entries={Our matcher},  
    65     legend pos=north east,
    66     legend pos=north east,
    66     legend cell align=left]
    67     legend cell align=left]
    67 %\addplot[green,mark=square*,mark options={fill=white}] table {re2a.data};    
    68 %\addplot[green,mark=square*,mark options={fill=white}] table {re2a.data};    
    68 \addplot[black,mark=square*,mark options={fill=white}] table {re3a.data};
    69 \addplot[black,mark=square*,mark options={fill=white}] table {re3a.data};
    69 \end{axis}
    70 \end{axis}
    70 \end{tikzpicture}
    71 \end{tikzpicture}
    71 \end{tabular}
    72 \end{tabular}
    72 \end{center}
    73 \end{center}\bigskip
    73 
    74 
    74 \begin{center}
    75 \begin{center}
    75 Graphs: $a^{?\{n\}} \cdot a^{\{n\}}$ and strings $\underbrace{a\ldots a}_{n}$\\
    76 Graphs: $a^{?\{n\}} \cdot a^{\{n\}}$ and strings $\underbrace{a\ldots a}_{n}$\\
    76 \begin{tabular}{@{}cc@{}}
    77 \begin{tabular}{@{}cc@{}}
    77 \begin{tikzpicture}
    78 \begin{tikzpicture}
   108     ytick={0,5,...,30},
   109     ytick={0,5,...,30},
   109     scaled ticks=false,
   110     scaled ticks=false,
   110     axis lines=left,
   111     axis lines=left,
   111     width=6.5cm,
   112     width=6.5cm,
   112     height=5cm,
   113     height=5cm,
   113     legend entries={Scala V3},  
   114     legend entries={Our matcher},  
   114     legend pos=north east,
   115     legend pos=north east,
   115     legend cell align=left]
   116     legend cell align=left]
   116 %\addplot[green,mark=square*,mark options={fill=white}] table {re2.data};
   117 %\addplot[green,mark=square*,mark options={fill=white}] table {re2.data};
   117 \addplot[black,mark=square*,mark options={fill=white}] table {re3.data};
   118 \addplot[black,mark=square*,mark options={fill=white}] table {re3.data};
   118 \end{axis}
   119 \end{axis}
   119 \end{tikzpicture}
   120 \end{tikzpicture}
   120 \end{tabular}
   121 \end{tabular}
   121 \end{center}
   122 \end{center}
   122 \medskip
   123 \bigskip
   123 
   124 
   124 \noindent
   125 \noindent
   125 We will use these regular expressions and strings as running
   126 In what follows we will use these regular expressions and strings as
   126 examples. There will be several versions (V1, V2, V3,\ldots) of the
   127 running examples. There will be several versions (V1, V2, V3,\ldots)
   127 algorithm.\footnote{The corresponding files are \texttt{re1.scala},
   128 of our matcher.\footnote{The corresponding files are
   128   \texttt{re2.scala} and so on. As usual, you can find the code on
   129   \texttt{re1.scala}, \texttt{re2.scala} and so on. As usual, you can
   129   KEATS.}\bigskip
   130   find the code on KEATS.}\bigskip
   130 
   131 
   131 \noindent
   132 \noindent
   132 Having specified in the previous lecture what
   133 Having specified in the previous lecture what
   133 problem our regular expression matcher is supposed to solve,
   134 problem our regular expression matcher is supposed to solve,
   134 namely for any given regular expression $r$ and string $s$
   135 namely for any given regular expression $r$ and string $s$
   136 
   137 
   137 \[
   138 \[
   138 s \in L(r)
   139 s \in L(r)
   139 \]
   140 \]
   140 
   141 
   141 \noindent we can look at an algorithm to solve this problem. Clearly
   142 \noindent we can look for an algorithm to solve this problem. Clearly
   142 we cannot use the function $L$ directly for this, because in general
   143 we cannot use the function $L$ directly for this, because in general
   143 the set of strings $L$ returns is infinite (recall what $L(a^*)$ is).
   144 the set of strings $L$ returns is infinite (recall what $L(a^*)$ is).
   144 In such cases there is no way we can implement an exhaustive test for
   145 In such cases there is no way we can implement an exhaustive test for
   145 whether a string is member of this set or not. In contrast our
   146 whether a string is member of this set or not. In contrast our
   146 matching algorithm will operate on the regular expression $r$ and
   147 matching algorithm will operate on the regular expression $r$ and
   235 (r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)
   236 (r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)
   236 \label{big}
   237 \label{big}
   237 \end{equation}
   238 \end{equation}
   238 
   239 
   239 \noindent If we can find an equivalent regular expression that is
   240 \noindent If we can find an equivalent regular expression that is
   240 simpler (smaller for example), then this might potentially make our
   241 simpler (that usually means smaller), then this might potentially make
   241 matching algorithm run faster. We can look for such a simpler regular
   242 our matching algorithm run faster. We can look for such a simpler
   242 expression $r'$ because whether a string $s$ is in $L(r)$ or in
   243 regular expression $r'$ because whether a string $s$ is in $L(r)$ or
   243 $L(r')$ with $r\equiv r'$ will always give the same answer. In the
   244 in $L(r')$ with $r\equiv r'$ will always give the same answer. Yes?
   244 example above you will see that the regular expression is equivalent
   245 
   245 to just $r_1$. You can verify this by iteratively applying the
   246 In the example above you will see that the regular expression is
   246 simplification rules from above:
   247 equivalent to just $r_1$. You can verify this by iteratively applying
       
   248 the simplification rules from above:
   247 
   249 
   248 \begin{center}
   250 \begin{center}
   249 \begin{tabular}{ll}
   251 \begin{tabular}{ll}
   250  & $(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot 
   252  & $(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot 
   251 (\underline{r_4 \cdot \ZERO})$\smallskip\\
   253 (\underline{r_4 \cdot \ZERO})$\smallskip\\
   262 rule is applied. Our matching algorithm in the next section
   264 rule is applied. Our matching algorithm in the next section
   263 will often generate such ``useless'' $\ONE$s and
   265 will often generate such ``useless'' $\ONE$s and
   264 $\ZERO$s, therefore simplifying them away will make the
   266 $\ZERO$s, therefore simplifying them away will make the
   265 algorithm quite a bit faster.
   267 algorithm quite a bit faster.
   266 
   268 
   267 Finally here are three equivalences between regulare expressions which are
   269 Finally here are three equivalences between regular expressions which are
   268 not so obvious:
   270 not so obvious:
   269 
   271 
   270 \begin{center}
   272 \begin{center}
   271 \begin{tabular}{rcl}
   273 \begin{tabular}{rcl}
   272 $r^*$  & $\equiv$ & $1 + r\cdot r^*$\\
   274 $r^*$  & $\equiv$ & $1 + r\cdot r^*$\\
   274 $(r_1 \cdot r_2)^*$ & $\equiv$ & $1 + r_1\cdot (r_2 \cdot r_1)^* \cdot r_2$\\
   276 $(r_1 \cdot r_2)^*$ & $\equiv$ & $1 + r_1\cdot (r_2 \cdot r_1)^* \cdot r_2$\\
   275 \end{tabular}
   277 \end{tabular}
   276 \end{center}
   278 \end{center}
   277 
   279 
   278 \noindent
   280 \noindent
   279 You can try to establish them. As an aside, there has been a lot of research
   281 We will not use them in our algorithm, but feel free to make sure they
   280 in questions like: Can one always decide when two regular expressions are
   282 hold. As an aside, there has been a lot of research about questions
   281 equivalent or not? What does an algorithm look like to decide this?
   283 like: Can one always decide when two regular expressions are
       
   284 equivalent or not? What does an algorithm look like to decide this
       
   285 efficiently?
   282 
   286 
   283 \subsection*{The Matching Algorithm}
   287 \subsection*{The Matching Algorithm}
   284 
   288 
   285 The algorithm we will define below consists of two parts. One
   289 The algorithm we will define below consists of two parts. One
   286 is the function $\textit{nullable}$ which takes a regular expression as
   290 is the function $\textit{nullable}$ which takes a regular expression as
   313 
   317 
   314 The other function of our matching algorithm calculates a
   318 The other function of our matching algorithm calculates a
   315 \emph{derivative} of a regular expression. This is a function
   319 \emph{derivative} of a regular expression. This is a function
   316 which will take a regular expression, say $r$, and a
   320 which will take a regular expression, say $r$, and a
   317 character, say $c$, as arguments and returns a new regular
   321 character, say $c$, as arguments and returns a new regular
   318 expression. Be careful that the intuition behind this function
   322 expression. Be mindful that the intuition behind this function
   319 is not so easy to grasp on first reading. Essentially this
   323 is not so easy to grasp on first reading. Essentially this
   320 function solves the following problem: if $r$ can match a
   324 function solves the following problem: if $r$ can match a
   321 string of the form $c\!::\!s$, what does the regular
   325 string of the form $c\!::\!s$, what does a regular
   322 expression look like that can match just $s$? The definition
   326 expression look like that can match just $s$? The definition
   323 of this function is as follows:
   327 of this function is as follows:
   324 
   328 
   325 \begin{center}
   329 \begin{center}
   326 \begin{tabular}{l@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
   330 \begin{tabular}{l@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
   370 $c\!::\!s$, then the first part must be ``matched'' by a
   374 $c\!::\!s$, then the first part must be ``matched'' by a
   371 single copy of $r$. Therefore we call recursively $\textit{der}\,c\,r$
   375 single copy of $r$. Therefore we call recursively $\textit{der}\,c\,r$
   372 and ``append'' $r^*$ in order to match the rest of $s$. Still
   376 and ``append'' $r^*$ in order to match the rest of $s$. Still
   373 makes sense?
   377 makes sense?
   374 
   378 
   375 If all this did not make sense yet, here is another way to rationalise
   379 If all this did not make sense yet, here is another way to explain the
   376 the definition of $\textit{der}$ by considering the following operation
   380 definition of $\textit{der}$ by considering the following operation on
   377 on sets:
   381 sets:
   378 
   382 
   379 \begin{equation}\label{Der}
   383 \begin{equation}\label{Der}
   380 \textit{Der}\,c\,A\;\dn\;\{s\,|\,c\!::\!s \in A\}
   384 \textit{Der}\,c\,A\;\dn\;\{s\,|\,c\!::\!s \in A\}
   381 \end{equation}
   385 \end{equation}
   382 
   386 
   452   $\textit{ders}\, (c\!::\!s)\, r$ & $\dn$ & $\textit{ders}\,s\,(\textit{der}\,c\,r)$ & \\
   456   $\textit{ders}\, (c\!::\!s)\, r$ & $\dn$ & $\textit{ders}\,s\,(\textit{der}\,c\,r)$ & \\
   453   \end{tabular}
   457   \end{tabular}
   454 \end{center}
   458 \end{center}
   455 
   459 
   456 \noindent This function iterates $\textit{der}$ taking one character at
   460 \noindent This function iterates $\textit{der}$ taking one character at
   457 the time from the original string until it is exhausted.
   461 the time from the original string until the string is exhausted.
   458 Having $\textit{der}s$ in place, we can finally define our matching
   462 Having $\textit{der}s$ in place, we can finally define our matching
   459 algorithm:
   463 algorithm:
   460 
   464 
   461 \[
   465 \[
   462 \textit{matches}\,s\,r \dn \textit{nullable}(\textit{ders}\,s\,r)
   466 \textit{matches}\,s\,r \dn \textit{nullable}(\textit{ders}\,s\,r)
   491 
   495 
   492 \begin{figure}[p]
   496 \begin{figure}[p]
   493   \lstinputlisting[numbers=left,linebackgroundcolor=
   497   \lstinputlisting[numbers=left,linebackgroundcolor=
   494                   {\ifodd\value{lstnumber}\color{capri!3}\fi}]
   498                   {\ifodd\value{lstnumber}\color{capri!3}\fi}]
   495                   {../progs/app5.scala}
   499                   {../progs/app5.scala}
   496 \caption{Scala implementation of the \textit{nullable} and 
   500 \caption{A Scala implementation of the \textit{nullable} and 
   497   derivative functions. These functions are easy to
   501   derivative functions. These functions are easy to
   498   implement in functional languages, because their built-in pattern 
   502   implement in functional languages. This is because pattern 
   499   matching and recursion allow us to mimic the mathematical
   503   matching and recursion allow us to mimic the mathematical
   500   definitions very closely.\label{scala1}}
   504   definitions very closely. Nearly all functional
       
   505   programming languages support pattern matching and
       
   506   recursion out of the box.\label{scala1}}
   501 \end{figure}
   507 \end{figure}
   502 
   508 
   503 
   509 
   504 %Remember our second example involving the regular expression
   510 %Remember our second example involving the regular expression
   505 %$(a^*)^* \cdot b$ which could not match strings of $n$ \texttt{a}s. 
   511 %$(a^*)^* \cdot b$ which could not match strings of $n$ \texttt{a}s. 
   536 %strings up to the length of 6500. After that we receive a
   542 %strings up to the length of 6500. After that we receive a
   537 %StackOverflow exception, but still\ldots
   543 %StackOverflow exception, but still\ldots
   538 
   544 
   539 For running the algorithm with our first example, the evil
   545 For running the algorithm with our first example, the evil
   540 regular expression $a^?{}^{\{n\}}a^{\{n\}}$, we need to implement
   546 regular expression $a^?{}^{\{n\}}a^{\{n\}}$, we need to implement
   541 the optional regular expression and the exactly $n$-times
   547 the optional regular expression and the `exactly $n$-times
   542 regular expression. This can be done with the translations
   548 regular expression'. This can be done with the translations
   543 
   549 
   544 \lstinputlisting[numbers=none]{../progs/app51.scala}
   550 \lstinputlisting[numbers=none]{../progs/app51.scala}
   545 
   551 
   546 \noindent Running the matcher with this example, we find it is
   552 \noindent Running the matcher with this example, we find it is
   547 slightly worse then the matcher in Ruby and Python.
   553 slightly worse then the matcher in Ruby and Python.
   570 \addplot[red,mark=triangle*,mark options={fill=white}] table {re1.data};  
   576 \addplot[red,mark=triangle*,mark options={fill=white}] table {re1.data};  
   571 \end{axis}
   577 \end{axis}
   572 \end{tikzpicture}
   578 \end{tikzpicture}
   573 \end{center}
   579 \end{center}
   574 
   580 
   575 \noindent Analysing this failure we notice that for
   581 \noindent Analysing this failure we notice that for $a^{\{n\}}$, for
   576 $a^{\{n\}}$ we generate quite big regular expressions:
   582 example, we generate quite big regular expressions:
   577 
   583 
   578 \begin{center}
   584 \begin{center}
   579 \begin{tabular}{rl}
   585 \begin{tabular}{rl}
   580 1: & $a$\\
   586 1: & $a$\\
   581 2: & $a\cdot a$\\
   587 2: & $a\cdot a$\\
   589 \noindent Our algorithm traverses such regular expressions at
   595 \noindent Our algorithm traverses such regular expressions at
   590 least once every time a derivative is calculated. So having
   596 least once every time a derivative is calculated. So having
   591 large regular expressions will cause problems. This problem
   597 large regular expressions will cause problems. This problem
   592 is aggravated by $a^?$ being represented as $a + \ONE$.
   598 is aggravated by $a^?$ being represented as $a + \ONE$.
   593 
   599 
   594 We can however fix this by having an explicit constructor for
   600 We can however fix this easily by having an explicit constructor for
   595 $r^{\{n\}}$. In Scala we would introduce a constructor like
   601 $r^{\{n\}}$. In Scala we would introduce a constructor like
   596 
   602 
   597 \begin{center}
   603 \begin{center}
   598 \code{case class NTIMES(r: Rexp, n: Int) extends Rexp}
   604 \code{case class NTIMES(r: Rexp, n: Int) extends Rexp}
   599 \end{center}
   605 \end{center}
   632 
   638 
   633 \noindent Now we are talking business! The modified matcher can within
   639 \noindent Now we are talking business! The modified matcher can within
   634 25 seconds handle regular expressions up to $n = 1,100$ before a
   640 25 seconds handle regular expressions up to $n = 1,100$ before a
   635 StackOverflow is raised. Recall that Python and Ruby (and our first
   641 StackOverflow is raised. Recall that Python and Ruby (and our first
   636 version, Scala V1) could only handle $n = 27$ or so in 30
   642 version, Scala V1) could only handle $n = 27$ or so in 30
   637 seconds. There is no change for our second example $(a^*)^* \cdot
   643 seconds. We have not tried our algorithm on the second example $(a^*)^* \cdot
   638 b$---so this is still good.
   644 b$---but it is doing OK with it.
   639 
   645 
   640 
   646 
   641 The moral is that our algorithm is rather sensitive to the
   647 The moral is that our algorithm is rather sensitive to the
   642 size of regular expressions it needs to handle. This is of
   648 size of regular expressions it needs to handle. This is of
   643 course obvious because both $\textit{nullable}$ and $\textit{der}$ frequently
   649 course obvious because both $\textit{nullable}$ and $\textit{der}$ frequently
   654 $\textit{der}\,c\,r = ((\ZERO \cdot b) + \ZERO)\cdot r$
   660 $\textit{der}\,c\,r = ((\ZERO \cdot b) + \ZERO)\cdot r$
   655 \end{tabular}
   661 \end{tabular}
   656 \end{center}
   662 \end{center}
   657 
   663 
   658 \noindent 
   664 \noindent 
   659 If we simplify them according to the simple rules from the
   665 If we simplify them according to the simplification rules from the
   660 beginning, we can replace the right-hand sides by the 
   666 beginning, we can replace the right-hand sides by the smaller
   661 smaller equivalent regular expressions
   667 equivalent regular expressions
   662 
   668 
   663 \begin{center}
   669 \begin{center}
   664 \begin{tabular}{l}
   670 \begin{tabular}{l}
   665 $\textit{der}\,a\,r \equiv b \cdot r$\\
   671 $\textit{der}\,a\,r \equiv b \cdot r$\\
   666 $\textit{der}\,b\,r \equiv r$\\
   672 $\textit{der}\,b\,r \equiv r$\\
   724 string of 28 \texttt{a}s and the regular expression $a^{?\{n\}} \cdot
   730 string of 28 \texttt{a}s and the regular expression $a^{?\{n\}} \cdot
   725 a^{\{n\}}$.  We need a third of this time to do the same with strings
   731 a^{\{n\}}$.  We need a third of this time to do the same with strings
   726 up to 11,000 \texttt{a}s.  Similarly, Java and Python needed 30
   732 up to 11,000 \texttt{a}s.  Similarly, Java and Python needed 30
   727 seconds to find out the regular expression $(a^*)^* \cdot b$ does not
   733 seconds to find out the regular expression $(a^*)^* \cdot b$ does not
   728 match the string of 28 \texttt{a}s. We can do the same in
   734 match the string of 28 \texttt{a}s. We can do the same in
   729 for strings of 6,000,000 \texttt{a}s:
   735 for strings composed of nearly 6,000,000 \texttt{a}s:
   730 
   736 
   731 
   737 
   732 \begin{center}
   738 \begin{center}
   733 \begin{tikzpicture}
   739 \begin{tikzpicture}
   734 \begin{axis}[
   740 \begin{axis}[
   737     ylabel={time in secs},
   743     ylabel={time in secs},
   738     enlargelimits=false,
   744     enlargelimits=false,
   739     ymax=35,
   745     ymax=35,
   740     ytick={0,5,...,30},
   746     ytick={0,5,...,30},
   741     axis lines=left,
   747     axis lines=left,
   742     scaled ticks=false,
   748     %scaled ticks=false,
   743     x label style={at={(1.09,0.0)}},
   749     x label style={at={(1.09,0.0)}},
   744     %xmax=7700000,
   750     %xmax=7700000,
   745     width=9cm,
   751     width=9cm,
   746     height=5cm, 
   752     height=5cm, 
   747     legend entries={Scala V3},
   753     legend entries={Scala V3},
   753 \end{tikzpicture}
   759 \end{tikzpicture}
   754 \end{center}
   760 \end{center}
   755 
   761 
   756 \subsection*{Epilogue}
   762 \subsection*{Epilogue}
   757 
   763 
   758 (23/Aug/2016) I recently found another place where this algorithm can be 
   764 (23/Aug/2016) I recently found another place where this algorithm can
   759 sped up (this idea is not integrated with what is coming next,
   765 be sped up (this idea is not integrated with what is coming next, but
   760 but I present it nonetheless). The idea is to define \texttt{ders}
   766 I present it nonetheless). The idea is to not define \texttt{ders}
   761 not such that it iterates the derivative character-by-character, but
   767 that it iterates the derivative character-by-character, but in bigger
   762 in bigger chunks. The resulting code for \texttt{ders2} looks as
   768 chunks. The resulting code for \texttt{ders2} looks as follows:
   763 follows:
       
   764 
   769 
   765 \lstinputlisting[numbers=none]{../progs/app52.scala} 
   770 \lstinputlisting[numbers=none]{../progs/app52.scala} 
   766 
   771 
   767 \noindent
   772 \noindent
   768 I have not fully understood why this version is much faster,
   773 I have not fully understood why this version is much faster,
   788     xmax=7100000,
   793     xmax=7100000,
   789     ytick={0,5,...,30},
   794     ytick={0,5,...,30},
   790     ymax=33,
   795     ymax=33,
   791     %scaled ticks=false,
   796     %scaled ticks=false,
   792     axis lines=left,
   797     axis lines=left,
   793     width=5.5cm,
   798     width=5.3cm,
   794     height=5cm, 
   799     height=5cm, 
   795     legend entries={Scala V3, Scala V4},
   800     legend entries={Scala V3, Scala V4},
   796     legend style={at={(0.1,-0.2)},anchor=north}]
   801     legend style={at={(0.1,-0.2)},anchor=north}]
   797 \addplot[black,mark=square*,mark options={fill=white}] table {re3.data};
   802 \addplot[black,mark=square*,mark options={fill=white}] table {re3.data};
   798 \addplot[purple,mark=square*,mark options={fill=white}] table {re4.data};
   803 \addplot[purple,mark=square*,mark options={fill=white}] table {re4.data};
   804     title={Graph: $(a^*)^* \cdot b$ and strings $\underbrace{a\ldots a}_{n}$},
   809     title={Graph: $(a^*)^* \cdot b$ and strings $\underbrace{a\ldots a}_{n}$},
   805     xlabel={$n$},
   810     xlabel={$n$},
   806     x label style={at={(1.09,0.0)}},
   811     x label style={at={(1.09,0.0)}},
   807     ylabel={time in secs},
   812     ylabel={time in secs},
   808     enlargelimits=false,
   813     enlargelimits=false,
   809     xmax=8100000,
   814     xmax=8200000,
   810     ytick={0,5,...,30},
   815     ytick={0,5,...,30},
   811     ymax=33,
   816     ymax=33,
   812     %scaled ticks=false,
   817     %scaled ticks=false,
   813     axis lines=left,
   818     axis lines=left,
   814     width=5.5cm,
   819     width=5.3cm,
   815     height=5cm, 
   820     height=5cm, 
   816     legend entries={Scala V3, Scala V4},
   821     legend entries={Scala V3, Scala V4},
   817     legend style={at={(0.1,-0.2)},anchor=north}]
   822     legend style={at={(0.1,-0.2)},anchor=north}]
   818 \addplot[black,mark=square*,mark options={fill=white}] table {re3a.data};
   823 \addplot[black,mark=square*,mark options={fill=white}] table {re3a.data};
   819 \addplot[purple,mark=square*,mark options={fill=white}] table {re4a.data};
   824 \addplot[purple,mark=square*,mark options={fill=white}] table {re4a.data};
   825 
   830 
   826 \section*{Proofs}
   831 \section*{Proofs}
   827 
   832 
   828 You might not like doing proofs. But they serve a very
   833 You might not like doing proofs. But they serve a very
   829 important purpose in Computer Science: How can we be sure that
   834 important purpose in Computer Science: How can we be sure that
   830 our algorithm matches its specification. We can try to test
   835 our algorithm matches its specification? We can try to test
   831 the algorithm, but that often overlooks corner cases and an
   836 the algorithm, but that often overlooks corner cases and an
   832 exhaustive testing is impossible (since there are infinitely
   837 exhaustive testing is impossible (since there are infinitely
   833 many inputs). Proofs allow us to ensure that an algorithm
   838 many inputs). Proofs allow us to ensure that an algorithm
   834 really meets its specification. 
   839 really meets its specification. 
   835 
   840 
   846         & $\mid$ & $r_1 \cdot r_2$      & sequence\\
   851         & $\mid$ & $r_1 \cdot r_2$      & sequence\\
   847         & $\mid$ & $r^*$                & star (zero or more)\\
   852         & $\mid$ & $r^*$                & star (zero or more)\\
   848   \end{tabular}
   853   \end{tabular}
   849 \end{center}
   854 \end{center}
   850 
   855 
   851 \noindent If you want to show a property $P(r)$ for all 
   856 \noindent If you want to show a property $P(r)$ for \emph{all} 
   852 regular expressions $r$, then you have to follow essentially 
   857 regular expressions $r$, then you have to follow essentially 
   853 the recipe:
   858 the recipe:
   854 
   859 
   855 \begin{itemize}
   860 \begin{itemize}
   856 \item $P$ has to hold for $\ZERO$, $\ONE$ and $c$
   861 \item $P$ has to hold for $\ZERO$, $\ONE$ and $c$
   898 \textit{nullable}(r_1 + r_2) \;\;\text{if and only if}\;\; 
   903 \textit{nullable}(r_1 + r_2) \;\;\text{if and only if}\;\; 
   899 []\in L(r_1 + r_2)
   904 []\in L(r_1 + r_2)
   900 \label{propalt}
   905 \label{propalt}
   901 \end{equation}
   906 \end{equation}
   902 
   907 
   903 \noindent The difference to the base cases is that in this
   908 \noindent The difference to the base cases is that in the inductive
   904 case we can already assume we proved
   909 cases we can already assume we proved $P$ for the components, that is
       
   910 we can assume.
   905 
   911 
   906 \begin{center}
   912 \begin{center}
   907 \begin{tabular}{l}
   913 \begin{tabular}{l}
   908 $\textit{nullable}(r_1) \;\;\text{if and only if}\;\; []\in L(r_1)$ and\\
   914 $\textit{nullable}(r_1) \;\;\text{if and only if}\;\; []\in L(r_1)$ and\\
   909 $\textit{nullable}(r_2) \;\;\text{if and only if}\;\; []\in L(r_2)$\\
   915 $\textit{nullable}(r_2) \;\;\text{if and only if}\;\; []\in L(r_2)$\\
   910 \end{tabular}
   916 \end{tabular}
   911 \end{center}
   917 \end{center}
   912 
   918 
   913 \noindent These are the induction hypotheses. To check this 
   919 \noindent These are called the induction hypotheses. To check this 
   914 case, we can start from $\textit{nullable}(r_1 + r_2)$, which by 
   920 case, we can start from $\textit{nullable}(r_1 + r_2)$, which by 
   915 definition is
   921 definition of $\textit{nullable}$ is
   916 
   922 
   917 \[
   923 \[
   918 \textit{nullable}(r_1) \vee \textit{nullable}(r_2)
   924 \textit{nullable}(r_1) \vee \textit{nullable}(r_2)
   919 \]
   925 \]
   920 
   926 
   933 
   939 
   934 \[
   940 \[
   935 [] \in L(r_1)\cup L(r_2)
   941 [] \in L(r_1)\cup L(r_2)
   936 \]
   942 \]
   937 
   943 
   938 \noindent but this is by definition of $L$ exactly $[] \in
   944 \noindent but this is by definition of $L$ exactly $[] \in L(r_1 +
   939 L(r_1 + r_2)$, which we needed to establish according to
   945 r_2)$, which we needed to establish according to statement in
   940 \eqref{propalt}. What we have shown is that starting from
   946 \eqref{propalt}. What we have shown is that starting from
   941 $\textit{nullable}(r_1 + r_2)$ we have done equivalent transformations
   947 $\textit{nullable}(r_1 + r_2)$ we have done equivalent transformations
   942 to end up with $[] \in L(r_1 + r_2)$. Consequently we have
   948 to end up with $[] \in L(r_1 + r_2)$. Consequently we have established
   943 established that $P(r_1 + r_2)$ holds.
   949 that $P(r_1 + r_2)$ holds.
   944 
   950 
   945 In order to complete the proof we would now need to look 
   951 In order to complete the proof we would now need to look 
   946 at the cases \mbox{$P(r_1\cdot r_2)$} and $P(r^*)$. Again I let you
   952 at the cases \mbox{$P(r_1\cdot r_2)$} and $P(r^*)$. Again I let you
   947 check the details.
   953 check the details.
   948 
   954 
   949 You might have to do induction proofs over strings. 
   955 You might also have to do induction proofs over strings. 
   950 That means you want to establish a property $P(s)$ for all
   956 That means you want to establish a property $P(s)$ for all
   951 strings $s$. For this remember strings are lists of 
   957 strings $s$. For this remember strings are lists of 
   952 characters. These lists can be either the empty list or a
   958 characters. These lists can be either the empty list or a
   953 list of the form $c::s$. If you want to perform an induction
   959 list of the form $c::s$. If you want to perform an induction
   954 proof for strings you need to consider the cases
   960 proof for strings you need to consider the cases
   980 
   986 
   981 \[
   987 \[
   982 L(\textit{der}\,c\,r) = \textit{Der}\,c\,(L(r))
   988 L(\textit{der}\,c\,r) = \textit{Der}\,c\,(L(r))
   983 \]
   989 \]
   984 
   990 
   985 \noindent holds (this would be of course a property that
   991 \noindent holds (this would be of course another property that needs
   986 needs to be proved in a side-lemma by induction on $r$).
   992 to be proved in a side-lemma by induction on $r$). This is a bit
       
   993 more challenging, but not impossible.
   987 
   994 
   988 To sum up, using reasoning like the one shown above allows us 
   995 To sum up, using reasoning like the one shown above allows us 
   989 to show the correctness of our algorithm. To see this,
   996 to show the correctness of our algorithm. To see this,
   990 start from the specification
   997 start from the specification
   991 
   998 
  1000 \begin{equation}
  1007 \begin{equation}
  1001 [] \in \textit{Ders}\,s\,(L(r))
  1008 [] \in \textit{Ders}\,s\,(L(r))
  1002 \label{dersstep}
  1009 \label{dersstep}
  1003 \end{equation}
  1010 \end{equation}
  1004 
  1011 
  1005 \noindent But we have shown above in \eqref{dersprop}, that
  1012 \noindent You agree?  But we have shown above in \eqref{dersprop},
  1006 the $\textit{Ders}$ can be replaced by $L(\textit{ders}\ldots)$. That means 
  1013 that the $\textit{Ders}$ can be replaced by
  1007 \eqref{dersstep} is equivalent to 
  1014 $L(\textit{ders}\ldots)$. That means \eqref{dersstep} is equivalent to
  1008 
  1015 
  1009 \begin{equation}
  1016 \begin{equation}
  1010 [] \in L(\textit{ders}\,s\,r)
  1017 [] \in L(\textit{ders}\,s\,r)
  1011 \label{prefinalstep}
  1018 \label{prefinalstep}
  1012 \end{equation}
  1019 \end{equation}
  1031 \[
  1038 \[
  1032 matches\,s\,r\;\;\text{if and only if}\;\;
  1039 matches\,s\,r\;\;\text{if and only if}\;\;
  1033 s\in L(r)
  1040 s\in L(r)
  1034 \]
  1041 \]
  1035 
  1042 
  1036 \noindent which is the property we set out to prove:
  1043 \noindent which is the property we set out to prove: our algorithm
  1037 our algorithm meets its specification. To have done
  1044 meets its specification. To have done so, requires a few induction
  1038 so, requires a few induction proofs about strings and
  1045 proofs about strings and regular expressions. Following the \emph{induction
  1039 regular expressions. Following the recipes is already a big 
  1046 recipes} is already a big step in actually performing these proofs.
  1040 step in performing these proofs.
  1047 If you do not believe it, proofs have helped me to make sure my code
       
  1048 is correct and in several instances prevented me of letting slip
       
  1049 embarassing mistakes into the `wild'.
  1041 
  1050 
  1042 \end{document}
  1051 \end{document}
  1043 
  1052 
  1044 
  1053 
  1045 
  1054