handouts/ho01.tex
changeset 550 71fc4a7a7039
parent 507 fdbc7d0ec04f
child 551 bd551ede2be6
--- a/handouts/ho01.tex	Sat May 05 10:31:00 2018 +0100
+++ b/handouts/ho01.tex	Fri Jun 01 15:28:37 2018 +0100
@@ -36,7 +36,7 @@
 
 %https://www.youtube.com/watch?v=gmhMQfFQu20
 \begin{document}
-\fnote{\copyright{} Christian Urban, King's College London, 2014, 2015, 2016, 2017}
+\fnote{\copyright{} Christian Urban, King's College London, 2014, 2015, 2016, 2017, 2018}
 
 \section*{Handout 1}
 
@@ -46,8 +46,8 @@
 Knuth-Morris-Pratt algorithm, which is currently the most efficient
 general string search algorithm. But often we do \emph{not} just look
 for a particular string, but for string patterns. For example, in
-program code we need to identify what are the keywords (if, then,
-while, for, etc), what are the identifiers (variable names). A pattern for
+program code we need to identify what are the keywords (\texttt{if}, \texttt{then},
+\texttt{while}, \texttt{for}, etc), what are the identifiers (variable names). A pattern for
 identifiers could be stated as: they start with a letter, followed by
 zero or more letters, numbers and underscores.  Often we also face the
 problem that we are given a string (for example some user input) and
@@ -106,7 +106,7 @@
 \noindent according to the regular expression we specified in line
 \eqref{email} above. Whether this is intended or not is a different
 question (the second email above is actually an acceptable email
-address acording to the RFC 5322 standard for email addresses).
+address according to the RFC 5322 standard for email addresses).
  
 As mentioned above, identifiers, or variables, in program code
 are often required to satisfy the constraints that they start
@@ -140,7 +140,7 @@
 \pcode{re\{n\}}	& matches exactly \pcode{n} number of 
 occurrences of preceding  expression\\
 \pcode{re\{n,m\}} & matches at least \pcode{n} and at most {\tt m}
-occurences of the preceding expression\\
+occurrences of the preceding expression\\
 \pcode{[...]} & matches any single character inside the 
 brackets\\
 \pcode{[^...]} & matches any single character not inside the 
@@ -191,7 +191,7 @@
 before (remember the PRA module?). Why on earth then is there any
 interest in studying them again in depth in this module? Well, one
 answer is in the following two graphs about regular expression
-matching in Python, Ruby and Java.
+matching in Python, Ruby and Java (Version 8).
 
 \begin{center}
 \begin{tabular}{@{\hspace{-1mm}}c@{\hspace{1mm}}c@{}}
@@ -211,7 +211,7 @@
     axis lines=left,
     width=5.5cm,
     height=4.5cm, 
-    legend entries={Python, Java},  
+    legend entries={Python, Java 8},  
     legend pos=north west,
     legend cell align=left]
 \addplot[blue,mark=*, mark options={fill=white}] table {re-python2.data};
@@ -273,7 +273,7 @@
 \end{center}
 
 \noindent
-A similar problem also occured in the Atom editor:
+A similar problem also occurred in the Atom editor:
 
 \begin{center}
 \url{http://davidvgalbraith.com/how-i-fixed-atom/}
@@ -283,14 +283,15 @@
 Such troublesome regular expressions are sometimes called \emph{evil
   regular expressions} because they have the potential to make regular
 expression matching engines to topple over, like in Python, Ruby and
-Java. This ``toppling over'' is also sometimes called \emph{catastrophic
-  backtracking}.  The problem with evil regular expressions is that
-they can have some serious consequences, for example, if you use them
-in your web-application. The reason is that hackers can look for these
-instances where the matching engine behaves badly and then mount a
-nice DoS-attack against your application. These attacks are already
-have their own name: \emph{Regular Expression Denial of Service
-  Attacks (ReDoS)}.
+Java. This ``toppling over'' is also sometimes called
+\emph{catastrophic backtracking}.  I have also seen the term
+\emph{eternal matching} used for this.  The problem with evil regular
+expressions is that they can have some serious consequences, for
+example, if you use them in your web-application. The reason is that
+hackers can look for these instances where the matching engine behaves
+badly and then mount a nice DoS-attack against your application. These
+attacks are already have their own name: \emph{Regular Expression
+  Denial of Service Attacks (ReDoS)}.
 
 It will be instructive to look behind the ``scenes'' to find
 out why Python and Ruby (and others) behave so badly when
@@ -405,23 +406,23 @@
 will be helpful. For example we will write $(r_1 + r_2)^*$,
 which is different from, say $r_1 + (r_2)^*$. The former means
 roughly zero or more times $r_1$ or $r_2$, while the latter
-means $r_1$ or zero or more times $r_2$. This will turn out to
+means $r_1$, or zero or more times $r_2$. This will turn out to
 be two different patterns, which match in general different
 strings. We should also write $(r_1 + r_2) + r_3$, which is
 different from the regular expression $r_1 + (r_2 + r_3)$, but
 in case of $+$ and $\cdot$ we actually do not care about the
 order and just write $r_1 + r_2 + r_3$, or $r_1 \cdot r_2
-\cdot r_3$, respectively. The reasons for this will become
+\cdot r_3$, respectively. The reasons for this carelessness will become
 clear shortly. 
 
 In the literature you will often find that the choice $r_1 +
 r_2$ is written as $r_1\mid{}r_2$ or $r_1\mid\mid{}r_2$. Also,
 often our $\ZERO$ and $\ONE$ are written $\varnothing$ and
 $\epsilon$, respectively. Following the convention in the
-literature, we will often omit the $\cdot$ all together. This
+literature, we will often omit the $\cdot$. This
 is to make some concrete regular expressions more readable.
 For example the regular expression for email addresses shown
-in \eqref{email} would look like
+in \eqref{email} would fully expanded look like
 
 \[
 \texttt{[...]+} \;\cdot\;  \texttt{@} \;\cdot\; 
@@ -559,7 +560,8 @@
 \]
 
 \noindent That means two regular expressions are said to be
-equivalent if they match the same set of strings. Therefore we
+equivalent if they match the same set of strings. That is
+there meaning is the same. Therefore we
 do not really distinguish between the different regular
 expression $(r_1 + r_2) + r_3$ and $r_1 + (r_2 + r_3)$,
 because they are equivalent. I leave you to the question
@@ -584,7 +586,7 @@
   was really a long time ago.} I got utterly confused about $\ONE$
 (which my lecturer wrote as $\epsilon$) and the empty string (which he
 also wrote as $\epsilon$).\footnote{Obviously the lecturer must have
-  been bad ;o)} Since my then, I have used regular expressions for
+  been bad ;o)} Since then, I have used regular expressions for
 implementing lexers and parsers as I have always been interested in
 all kinds of programming languages and compilers, which invariably
 need regular expressions in some form or shape.
@@ -596,7 +598,7 @@
 them.\footnote{\url{http://isabelle.in.tum.de}} Theorem
 provers are systems in which you can formally reason about
 mathematical concepts, but also about programs. In this way
-theorem provers can help with the manacing problem of writing bug-free code. Theorem provers have
+theorem provers can help with the menacing problem of writing bug-free code. Theorem provers have
 proved already their value in a number of cases (even in
 terms of hard cash), but they are still clunky and difficult
 to use by average programmers.
@@ -607,7 +609,7 @@
 expressions, not needing any automata (you will see we only touch
 briefly on automata in lecture 3). Automata are usually the main
 object of study in formal language courses.  The avoidance of automata
-is crucial because automata are graphs and it is rather difficult to
+is crucial for me because automata are graphs and it is rather difficult to
 reason about graphs in theorem provers. In contrast, reasoning about
 regular expressions is easy-peasy in theorem provers. Is this
 important? I think yes, because according to Kuklewicz nearly all
@@ -629,20 +631,21 @@
 theorem we can show that regular languages are closed under
 complementation, something which Gasarch in his
 blog\footnote{\url{http://goo.gl/2R11Fw}} assumed can only be
-shown via automata. Even sombody who has written a 700+-page
+shown via automata. So even somebody who has written a 700+-page
 book\footnote{\url{http://goo.gl/fD0eHx}} on regular
-exprssions did not know better. Well, we showed it can also be
+expressions did not know better. Well, we showed it can also be
 done with regular expressions only.\footnote{\url{http://nms.kcl.ac.uk/christian.urban/Publications/posix.pdf}}
 What a feeling when you are an outsider to the subject!
 
 To conclude: Despite my early ignorance about regular expressions, I
-find them now very interesting. They have a beautiful mathematical
-theory behind them, which can be sometimes quite deep and which
-sometimes contains hidden snares. They have practical importance
+find them now extremely interesting. They have practical importance
 (remember the shocking runtime of the regular expression matchers in
 Python, Ruby and Java in some instances and the problems in Stack
-Exchange and the Atom editor).  People who are not very familiar with
-the mathematical background of regular expressions get them
+Exchange and the Atom editor). They are used in tools like Snort and
+Bro in order to monitor network traffic. They have a beautiful mathematical
+theory behind them, which can be sometimes quite deep and which
+sometimes contains hidden snares.  People who are not very familiar
+with the mathematical background of regular expressions get them
 consistently wrong (this is surprising given they are a supposed to be
 core skill for computer scientists). The hope is that we can do better
 in the future---for example by proving that the algorithms actually
@@ -653,7 +656,7 @@
 expressions have their shortcomings. There are some well-known
 ``theoretical'' shortcomings, for example recognising strings of the
 form $a^{n}b^{n}$ is not possible with regular expressions. This means
-for example if we try to regognise whether parentheses are well-nested
+for example if we try to recognise whether parentheses are well-nested
 in an expression is impossible with (basic) regular expressions.  I am
 not so bothered by these shortcomings. What I am bothered about is
 when regular expressions are in the way of practical programming. For
@@ -702,7 +705,7 @@
 
 
 \begin{figure}[p]\small
-  \lstinputlisting[linebackgroundcolor={\ifodd\value{lstnumber}\color{capri!3}\fi}]
+  \lstinputlisting[numbers=left,linebackgroundcolor={\ifodd\value{lstnumber}\color{capri!3}\fi}]
                   {../progs/crawler1.scala}
 
 \caption{The Scala code for a simple web-crawler that checks
@@ -716,7 +719,7 @@
 
 
 \begin{figure}[p]\small
-  \lstinputlisting[linebackgroundcolor={\ifodd\value{lstnumber}\color{capri!3}\fi}]
+  \lstinputlisting[numbers=left,linebackgroundcolor={\ifodd\value{lstnumber}\color{capri!3}\fi}]
                   {../progs/crawler2.scala}
 
 \caption{A version of the web-crawler that only follows links
@@ -731,7 +734,7 @@
 \end{figure}
 
 \begin{figure}[p]\small
-  \lstinputlisting[linebackgroundcolor={\ifodd\value{lstnumber}\color{capri!3}\fi}]
+  \lstinputlisting[numbers=left,linebackgroundcolor={\ifodd\value{lstnumber}\color{capri!3}\fi}]
                   {../progs/crawler3.scala}
 
 \caption{A small email harvester---whenever we download a