# HG changeset patch # User cu # Date 1508244585 -3600 # Node ID 2849c305b12d3aedc7abf74b2fe6333eb6d866f9 # Parent 955d5b3b06195c953e704fb6ad87bc70652d339e updated diff -r 955d5b3b0619 -r 2849c305b12d handouts/ho04.pdf Binary file handouts/ho04.pdf has changed diff -r 955d5b3b0619 -r 2849c305b12d handouts/ho04.tex --- a/handouts/ho04.tex Sun Oct 15 20:47:14 2017 +0100 +++ b/handouts/ho04.tex Tue Oct 17 13:49:45 2017 +0100 @@ -5,7 +5,7 @@ \begin{document} -\fnote{\copyright{} Christian Urban, King's College London, 2014, 2015, 2016} +\fnote{\copyright{} Christian Urban, King's College London, 2014, 2015, 2016, 2017} \section*{Handout 4 (Sulzmann \& Lu Algorithm)} @@ -28,7 +28,7 @@ mathematical proof that their algorithm is really correct---the proof Sulzmann \& Lu had originally given contained major flaws. Such correctness proofs are important: Kuklewicz maintains a unit-test library -for the kind of algorithma we are interested in here and he showed +for the kind of algorithms we are interested in here and he showed that many implementations in the ``wild'' are buggy, that is not satisfy his unit tests: @@ -81,8 +81,8 @@ corresponding to the two alternatives. Note that $r^*$ is associated with a list of values, one for each copy of $r$ that was needed to match the string. This means we might also -return the empty list $Stars []$, if no copy was needed in case -of $r^*$. For sequence, there is exactly one value, composed +return the empty list $Stars []$, if no copy was needed +for $r^*$. For sequence, there is exactly one value, composed of two component values ($v_1$ and $v_2$). My implementation of regular expressions and values in Scala is @@ -381,7 +381,7 @@ $r_2$ or $r_{2s}$. Unfortunately, this is still not the right value in general because there might be some simplifications that happened inside $r_2$ and for which the simplification -function retuned also a rectification function $f_{2s}$. So in +function returned also a rectification function $f_{2s}$. So in fact we need to apply this one too which gives \begin{center} @@ -587,7 +587,7 @@ {\ifodd\value{lstnumber}\color{capri!3}\fi}]{../progs/app61.scala} \caption{The Scala code for the simplification function. The -first part defines some auxillary functions for the rectification. +first part defines some auxiliary functions for the rectification. The second part give the simplification function. \label{simprect}} \end{figure} @@ -607,7 +607,7 @@ \noindent This corresponds to the $matches$ function we have seen in earlier lectures. In the first clause we are given an -empty string, $[]$, and need to test wether the regular +empty string, $[]$, and need to test whether the regular expression is $nullable$. If yes, we can proceed normally and just return the value calculated by $\textit{mkeps}$. The second clause is for strings where the first character is $c$, say, and the diff -r 955d5b3b0619 -r 2849c305b12d progs/app02.scala --- a/progs/app02.scala Sun Oct 15 20:47:14 2017 +0100 +++ b/progs/app02.scala Tue Oct 17 13:49:45 2017 +0100 @@ -1,7 +1,7 @@ abstract class Val case object Empty extends Val case class Chr(c: Char) extends Val -case class Seq(v1: Val, v2: Val) extends Val +case class Sequ(v1: Val, v2: Val) extends Val case class Left(v: Val) extends Val case class Right(v: Val) extends Val case class Stars(vs: List[Val]) extends Val diff -r 955d5b3b0619 -r 2849c305b12d progs/app04.scala --- a/progs/app04.scala Sun Oct 15 20:47:14 2017 +0100 +++ b/progs/app04.scala Tue Oct 17 13:49:45 2017 +0100 @@ -1,7 +1,7 @@ abstract class Val case object Empty extends Val case class Chr(c: Char) extends Val -case class Seq(v1: Val, v2: Val) extends Val +case class Sequ(v1: Val, v2: Val) extends Val case class Left(v: Val) extends Val case class Right(v: Val) extends Val case class Stars(vs: List[Val]) extends Val diff -r 955d5b3b0619 -r 2849c305b12d progs/app61.scala --- a/progs/app61.scala Sun Oct 15 20:47:14 2017 +0100 +++ b/progs/app61.scala Tue Oct 17 13:49:45 2017 +0100 @@ -6,12 +6,12 @@ case Left(v) => Left(f1(v)) } def F_SEQ(f1: Val => Val, f2: Val => Val) = (v:Val) => v match { - case Seq(v1, v2) => Seq(f1(v1), f2(v2)) + case Sequ(v1, v2) => Sequ(f1(v1), f2(v2)) } def F_SEQ_Empty1(f1: Val => Val, f2: Val => Val) = - (v:Val) => Seq(f1(Empty), f2(v)) + (v:Val) => Sequ(f1(Empty), f2(v)) def F_SEQ_Empty2(f1: Val => Val, f2: Val => Val) = - (v:Val) => Seq(f1(v), f2(Empty)) + (v:Val) => Sequ(f1(v), f2(Empty)) def F_ERROR(v: Val): Val = throw new Exception("error") // simplification of regular expressions returning also a diff -r 955d5b3b0619 -r 2849c305b12d progs/token.scala --- a/progs/token.scala Sun Oct 15 20:47:14 2017 +0100 +++ b/progs/token.scala Tue Oct 17 13:49:45 2017 +0100 @@ -13,7 +13,7 @@ abstract class Val case object Empty extends Val case class Chr(c: Char) extends Val -case class Seq(v1: Val, v2: Val) extends Val +case class Sequ(v1: Val, v2: Val) extends Val case class Left(v: Val) extends Val case class Right(v: Val) extends Val case class Stars(vs: List[Val]) extends Val @@ -79,7 +79,7 @@ case Chr(c) => c.toString case Left(v) => flatten(v) case Right(v) => flatten(v) - case Seq(v1, v2) => flatten(v1) + flatten(v2) + case Sequ(v1, v2) => flatten(v1) + flatten(v2) case Stars(vs) => vs.map(flatten).mkString case Rec(_, v) => flatten(v) } @@ -90,7 +90,7 @@ case Chr(c) => Nil case Left(v) => env(v) case Right(v) => env(v) - case Seq(v1, v2) => env(v1) ::: env(v2) + case Sequ(v1, v2) => env(v1) ::: env(v2) case Stars(vs) => vs.flatMap(env) case Rec(x, v) => (x, flatten(v))::env(v) } @@ -100,17 +100,17 @@ case ONE => Empty case ALT(r1, r2) => if (nullable(r1)) Left(mkeps(r1)) else Right(mkeps(r2)) - case SEQ(r1, r2) => Seq(mkeps(r1), mkeps(r2)) + case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) case STAR(r) => Stars(Nil) case RECD(x, r) => Rec(x, mkeps(r)) } def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { - case (STAR(r), Seq(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) - case (SEQ(r1, r2), Seq(v1, v2)) => Seq(inj(r1, c, v1), v2) - case (SEQ(r1, r2), Left(Seq(v1, v2))) => Seq(inj(r1, c, v1), v2) - case (SEQ(r1, r2), Right(v2)) => Seq(mkeps(r1), inj(r2, c, v2)) + case (STAR(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) + case (SEQ(r1, r2), Sequ(v1, v2)) => Sequ(inj(r1, c, v1), v2) + case (SEQ(r1, r2), Left(Sequ(v1, v2))) => Sequ(inj(r1, c, v1), v2) + case (SEQ(r1, r2), Right(v2)) => Sequ(mkeps(r1), inj(r2, c, v2)) case (ALT(r1, r2), Left(v1)) => Left(inj(r1, c, v1)) case (ALT(r1, r2), Right(v2)) => Right(inj(r2, c, v2)) case (CHAR(d), Empty) => Chr(c) @@ -140,12 +140,12 @@ case Left(v) => Left(f1(v)) } def F_SEQ(f1: Val => Val, f2: Val => Val) = (v:Val) => v match { - case Seq(v1, v2) => Seq(f1(v1), f2(v2)) + case Sequ(v1, v2) => Sequ(f1(v1), f2(v2)) } def F_SEQ_Empty1(f1: Val => Val, f2: Val => Val) = - (v:Val) => Seq(f1(Empty), f2(v)) + (v:Val) => Sequ(f1(Empty), f2(v)) def F_SEQ_Empty2(f1: Val => Val, f2: Val => Val) = - (v:Val) => Seq(f1(v), f2(Empty)) + (v:Val) => Sequ(f1(v), f2(Empty)) def F_RECD(f: Val => Val) = (v:Val) => v match { case Rec(x, v) => Rec(x, f(v)) } diff -r 955d5b3b0619 -r 2849c305b12d slides/slides04.pdf Binary file slides/slides04.pdf has changed diff -r 955d5b3b0619 -r 2849c305b12d slides/slides04.tex --- a/slides/slides04.tex Sun Oct 15 20:47:14 2017 +0100 +++ b/slides/slides04.tex Tue Oct 17 13:49:45 2017 +0100 @@ -86,141 +86,141 @@ \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\begin{frame}[c] -\frametitle{DFA to Rexp} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \begin{frame}[c] +% \frametitle{DFA to Rexp} -\begin{center} -\begin{tikzpicture}[scale=2,>=stealth',very thick, - every state/.style={minimum size=0pt, - draw=blue!50,very thick,fill=blue!20},] - \node[state, initial] (q0) at ( 0,1) {$q_0$}; - \node[state] (q1) at ( 1,1) {$q_1$}; - \node[state, accepting] (q2) at ( 2,1) {$q_2$}; - \path[->] (q0) edge[bend left] node[above] {\alert{$a$}} (q1) - (q1) edge[bend left] node[above] {\alert{$b$}} (q0) - (q2) edge[bend left=50] node[below] {\alert{$b$}} (q0) - (q1) edge node[above] {\alert{$a$}} (q2) - (q2) edge [loop right] node {\alert{$a$}} () - (q0) edge [loop below] node {\alert{$b$}} (); -\end{tikzpicture} -\end{center}\bigskip +% \begin{center} +% \begin{tikzpicture}[scale=2,>=stealth',very thick, +% every state/.style={minimum size=0pt, +% draw=blue!50,very thick,fill=blue!20},] +% \node[state, initial] (q0) at ( 0,1) {$q_0$}; +% \node[state] (q1) at ( 1,1) {$q_1$}; +% \node[state, accepting] (q2) at ( 2,1) {$q_2$}; +% \path[->] (q0) edge[bend left] node[above] {\alert{$a$}} (q1) +% (q1) edge[bend left] node[above] {\alert{$b$}} (q0) +% (q2) edge[bend left=50] node[below] {\alert{$b$}} (q0) +% (q1) edge node[above] {\alert{$a$}} (q2) +% (q2) edge [loop right] node {\alert{$a$}} () +% (q0) edge [loop below] node {\alert{$b$}} (); +% \end{tikzpicture} +% \end{center}\bigskip -\begin{center} -\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@{\hspace{7mm}}l} -\bl{$q_0$} & \bl{$=$} & \bl{$\ONE + q_0\,b + q_1\,b + q_2\,b$} & (start state)\\ -\bl{$q_1$} & \bl{$=$} & \bl{$q_0\,a$}\\ -\bl{$q_2$} & \bl{$=$} & \bl{$q_1\,a + q_2\,a$}\\ +% \begin{center} +% \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@{\hspace{7mm}}l} +% \bl{$q_0$} & \bl{$=$} & \bl{$\ONE + q_0\,b + q_1\,b + q_2\,b$} & (start state)\\ +% \bl{$q_1$} & \bl{$=$} & \bl{$q_0\,a$}\\ +% \bl{$q_2$} & \bl{$=$} & \bl{$q_1\,a + q_2\,a$}\\ -\end{tabular} -\end{center} +% \end{tabular} +% \end{center} -Arden's Lemma: -\begin{center} -If \bl{$q = q\,r + s$}\; then\; \bl{$q = s\, r^*$} -\end{center} +% Arden's Lemma: +% \begin{center} +% If \bl{$q = q\,r + s$}\; then\; \bl{$q = s\, r^*$} +% \end{center} -\end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \end{frame} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\begin{frame}[c] -\frametitle{DFA Minimisation} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \begin{frame}[c] +% \frametitle{DFA Minimisation} -\begin{enumerate} -\item Take all pairs \bl{$(q, p)$} with \bl{$q \not= p$} -\item Mark all pairs that accepting and non-accepting states -\item For all unmarked pairs \bl{$(q, p)$} and all characters \bl{$c$} test whether -\begin{center} -\bl{$(\delta(q, c), \delta(p,c))$} -\end{center} -are marked. If yes, then also mark \bl{$(q, p)$}. -\item Repeat last step until no change. -\item All unmarked pairs can be merged. -\end{enumerate} +% \begin{enumerate} +% \item Take all pairs \bl{$(q, p)$} with \bl{$q \not= p$} +% \item Mark all pairs that accepting and non-accepting states +% \item For all unmarked pairs \bl{$(q, p)$} and all characters \bl{$c$} test whether +% \begin{center} +% \bl{$(\delta(q, c), \delta(p,c))$} +% \end{center} +% are marked. If yes, then also mark \bl{$(q, p)$}. +% \item Repeat last step until no change. +% \item All unmarked pairs can be merged. +% \end{enumerate} -\end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \end{frame} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\begin{frame}[c] +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \begin{frame}[c] -\begin{center} -\begin{tabular}{@{\hspace{-8mm}}cc@{}} -\begin{tikzpicture}[>=stealth',very thick,auto, - every state/.style={minimum size=0pt,inner sep=2pt,draw=blue!50,very thick,fill=blue!20},] -\node[state,initial] (q_0) {$q_0$}; -\node[state] (q_1) [right=of q_0] {$q_1$}; -\node[state] (q_2) [below right=of q_0] {$q_2$}; -\node[state] (q_3) [right=of q_2] {$q_3$}; -\node[state, accepting] (q_4) [right=of q_1] {$q_4$}; -\path[->] (q_0) edge node [above] {\alert{$a$}} (q_1); -\path[->] (q_1) edge node [above] {\alert{$a$}} (q_4); -\path[->] (q_4) edge [loop right] node {\alert{$a, b$}} (); -\path[->] (q_3) edge node [right] {\alert{$a$}} (q_4); -\path[->] (q_2) edge node [above] {\alert{$a$}} (q_3); -\path[->] (q_1) edge node [right] {\alert{$b$}} (q_2); -\path[->] (q_0) edge node [above] {\alert{$b$}} (q_2); -\path[->] (q_2) edge [loop left] node {\alert{$b$}} (); -\path[->] (q_3) edge [bend left=95, looseness=1.3] node [below] {\alert{$b$}} (q_0); -\end{tikzpicture} -& -\raisebox{9mm}{\begin{tikzpicture}[scale=0.6,line width=0.8mm] -\draw (0,0) -- (4,0); -\draw (0,1) -- (4,1); -\draw (0,2) -- (3,2); -\draw (0,3) -- (2,3); -\draw (0,4) -- (1,4); +% \begin{center} +% \begin{tabular}{@{\hspace{-8mm}}cc@{}} +% \begin{tikzpicture}[>=stealth',very thick,auto, +% every state/.style={minimum size=0pt,inner sep=2pt,draw=blue!50,very thick,fill=blue!20},] +% \node[state,initial] (q_0) {$q_0$}; +% \node[state] (q_1) [right=of q_0] {$q_1$}; +% \node[state] (q_2) [below right=of q_0] {$q_2$}; +% \node[state] (q_3) [right=of q_2] {$q_3$}; +% \node[state, accepting] (q_4) [right=of q_1] {$q_4$}; +% \path[->] (q_0) edge node [above] {\alert{$a$}} (q_1); +% \path[->] (q_1) edge node [above] {\alert{$a$}} (q_4); +% \path[->] (q_4) edge [loop right] node {\alert{$a, b$}} (); +% \path[->] (q_3) edge node [right] {\alert{$a$}} (q_4); +% \path[->] (q_2) edge node [above] {\alert{$a$}} (q_3); +% \path[->] (q_1) edge node [right] {\alert{$b$}} (q_2); +% \path[->] (q_0) edge node [above] {\alert{$b$}} (q_2); +% \path[->] (q_2) edge [loop left] node {\alert{$b$}} (); +% \path[->] (q_3) edge [bend left=95, looseness=1.3] node [below] {\alert{$b$}} (q_0); +% \end{tikzpicture} +% & +% \raisebox{9mm}{\begin{tikzpicture}[scale=0.6,line width=0.8mm] +% \draw (0,0) -- (4,0); +% \draw (0,1) -- (4,1); +% \draw (0,2) -- (3,2); +% \draw (0,3) -- (2,3); +% \draw (0,4) -- (1,4); -\draw (0,0) -- (0, 4); -\draw (1,0) -- (1, 4); -\draw (2,0) -- (2, 3); -\draw (3,0) -- (3, 2); -\draw (4,0) -- (4, 1); +% \draw (0,0) -- (0, 4); +% \draw (1,0) -- (1, 4); +% \draw (2,0) -- (2, 3); +% \draw (3,0) -- (3, 2); +% \draw (4,0) -- (4, 1); -\draw (0.5,-0.5) node {$q_0$}; -\draw (1.5,-0.5) node {$q_1$}; -\draw (2.5,-0.5) node {$q_2$}; -\draw (3.5,-0.5) node {$q_3$}; +% \draw (0.5,-0.5) node {$q_0$}; +% \draw (1.5,-0.5) node {$q_1$}; +% \draw (2.5,-0.5) node {$q_2$}; +% \draw (3.5,-0.5) node {$q_3$}; -\draw (-0.5, 3.5) node {$q_1$}; -\draw (-0.5, 2.5) node {$q_2$}; -\draw (-0.5, 1.5) node {$q_3$}; -\draw (-0.5, 0.5) node {$q_4$}; +% \draw (-0.5, 3.5) node {$q_1$}; +% \draw (-0.5, 2.5) node {$q_2$}; +% \draw (-0.5, 1.5) node {$q_3$}; +% \draw (-0.5, 0.5) node {$q_4$}; -\draw (0.5,0.5) node {\large$\star$}; -\draw (1.5,0.5) node {\large$\star$}; -\draw (2.5,0.5) node {\large$\star$}; -\draw (3.5,0.5) node {\large$\star$}; -\draw (0.5,1.5) node {\large$\star$}; -\draw (2.5,1.5) node {\large$\star$}; -\draw (0.5,3.5) node {\large$\star$}; -\draw (1.5,2.5) node {\large$\star$}; -\end{tikzpicture}} -\end{tabular} -\end{center} +% \draw (0.5,0.5) node {\large$\star$}; +% \draw (1.5,0.5) node {\large$\star$}; +% \draw (2.5,0.5) node {\large$\star$}; +% \draw (3.5,0.5) node {\large$\star$}; +% \draw (0.5,1.5) node {\large$\star$}; +% \draw (2.5,1.5) node {\large$\star$}; +% \draw (0.5,3.5) node {\large$\star$}; +% \draw (1.5,2.5) node {\large$\star$}; +% \end{tikzpicture}} +% \end{tabular} +% \end{center} -\mbox{}\\[-20mm]\mbox{} +% \mbox{}\\[-20mm]\mbox{} -\begin{center} -\begin{tikzpicture}[>=stealth',very thick,auto, - every state/.style={minimum size=0pt,inner sep=2pt,draw=blue!50,very thick,fill=blue!20},] -\node[state,initial] (q_02) {$q_{0, 2}$}; -\node[state] (q_13) [right=of q_02] {$q_{1, 3}$}; -\node[state, accepting] (q_4) [right=of q_13] {$q_{4\phantom{,0}}$}; -\path[->] (q_02) edge [bend left] node [above] {\alert{$a$}} (q_13); -\path[->] (q_13) edge [bend left] node [below] {\alert{$b$}} (q_02); -\path[->] (q_02) edge [loop below] node {\alert{$b$}} (); -\path[->] (q_13) edge node [above] {\alert{$a$}} (q_4); -\path[->] (q_4) edge [loop above] node {\alert{$a, b$}} (); -\end{tikzpicture}\\ -minimal automaton -\end{center} +% \begin{center} +% \begin{tikzpicture}[>=stealth',very thick,auto, +% every state/.style={minimum size=0pt,inner sep=2pt,draw=blue!50,very thick,fill=blue!20},] +% \node[state,initial] (q_02) {$q_{0, 2}$}; +% \node[state] (q_13) [right=of q_02] {$q_{1, 3}$}; +% \node[state, accepting] (q_4) [right=of q_13] {$q_{4\phantom{,0}}$}; +% \path[->] (q_02) edge [bend left] node [above] {\alert{$a$}} (q_13); +% \path[->] (q_13) edge [bend left] node [below] {\alert{$b$}} (q_02); +% \path[->] (q_02) edge [loop below] node {\alert{$b$}} (); +% \path[->] (q_13) edge node [above] {\alert{$a$}} (q_4); +% \path[->] (q_4) edge [loop above] node {\alert{$a, b$}} (); +% \end{tikzpicture}\\ +% minimal automaton +% \end{center} -\end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \end{frame} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{frame}[c] @@ -319,18 +319,18 @@ \frametitle{Survey: Thanks!} \small -\begin{itemize} -\item {\bf My Voice} ``lecturer speaks in a low voice and - is hard to hear him'' ``please use mic'' ``please use mic - \& lecture recording'' -\item {\bf Pace} ``faster pace'' ``a bit quick for me -personally'' -\item {\bf Recording} ``please use recording class'' -\item {\bf Module Name} ``misleading'' -\item {\bf Examples} ``more examples'' -\item {\bf Assessment} ``really appreciate extension of - first coursework'' -\end{itemize} +% \begin{itemize} +% \item {\bf My Voice} ``lecturer speaks in a low voice and +% is hard to hear him'' ``please use mic'' ``please use mic +% \& lecture recording'' +% \item {\bf Pace} ``faster pace'' ``a bit quick for me +% personally'' +% \item {\bf Recording} ``please use recording class'' +% \item {\bf Module Name} ``misleading'' +% \item {\bf Examples} ``more examples'' +% \item {\bf Assessment} ``really appreciate extension of +% first coursework'' +% \end{itemize} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%