ChengsongTanPhdThesis/Chapters/Cubic.tex
changeset 628 7af4e2420a8c
parent 625 b797c9a709d9
child 630 d50a309a0645
equal deleted inserted replaced
627:94db2636a296 628:7af4e2420a8c
    14 We intend to formalise this part, which
    14 We intend to formalise this part, which
    15 we have not been able to finish due to time constraints of the PhD.
    15 we have not been able to finish due to time constraints of the PhD.
    16 Nevertheless, we outline the ideas we intend to use for the proof.
    16 Nevertheless, we outline the ideas we intend to use for the proof.
    17 
    17 
    18 We present further improvements
    18 We present further improvements
    19 made to our lexer algorithm $\blexersimp$.
    19 for our lexer algorithm $\blexersimp$.
    20 We devise a stronger simplification algorithm,
    20 We devise a stronger simplification algorithm,
    21 called $\bsimpStrong$, which can prune away
    21 called $\bsimpStrong$, which can prune away
    22 similar components in two regular expressions at the same 
    22 similar components in two regular expressions at the same 
    23 alternative level,
    23 alternative level,
    24 even if these regular expressions are not exactly the same.
    24 even if these regular expressions are not exactly the same.
    25 We call the lexer that uses this stronger simplification function
    25 We call the lexer that uses this stronger simplification function
    26 $\blexerStrong$.
    26 $\blexerStrong$.
       
    27 Unfortunately we did not have time to 
       
    28 work out the proofs, like in
       
    29 the previous chapters.
    27 We conjecture that both
    30 We conjecture that both
    28 \begin{center}
    31 \begin{center}
    29 	$\blexerStrong \;r \; s = \blexer\; r\;s$
    32 	$\blexerStrong \;r \; s = \blexer\; r\;s$
    30 \end{center}
    33 \end{center}
    31 and
    34 and
    32 \begin{center}
    35 \begin{center}
    33 	$\llbracket \bdersStrong{a}{s} \rrbracket = O(\llbracket a \rrbracket^3)$
    36 	$\llbracket \bdersStrong{a}{s} \rrbracket = O(\llbracket a \rrbracket^3)$
    34 \end{center}
    37 \end{center}
    35 hold, but formalising
    38 hold, but a formalisation
    36 them is still work in progress.
    39 is still future work.
    37 We give reasons why the correctness and cubic size bound proofs
    40 We give an informal justification 
    38 can be achieved,
    41 why the correctness and cubic size bound proofs
       
    42 can be achieved
    39 by exploring the connection between the internal
    43 by exploring the connection between the internal
    40 data structure of our $\blexerStrong$ and
    44 data structure of our $\blexerStrong$ and
    41 Animirov's partial derivatives.\\
    45 Animirov's partial derivatives.\\
    42 %We also present the idempotency property proof
    46 %We also present the idempotency property proof
    43 %of $\bsimp$, which leverages the idempotency proof of $\rsimp$.
    47 %of $\bsimp$, which leverages the idempotency proof of $\rsimp$.
    59 For example, the regular expression 
    63 For example, the regular expression 
    60 \[
    64 \[
    61 	aa \cdot a^*+ a \cdot a^* + aa\cdot a^*
    65 	aa \cdot a^*+ a \cdot a^* + aa\cdot a^*
    62 \]
    66 \]
    63 contains three terms, 
    67 contains three terms, 
    64 expressing three possibilities it will match future input.
    68 expressing three possibilities for how it can match some input.
    65 The first and the third terms are identical, which means we can eliminate
    69 The first and the third terms are identical, which means we can eliminate
    66 the latter as we know it will not be picked up by $\bmkeps$.
    70 the latter as it will not contribute to a POSIX value.
    67 In $\bsimps$, the $\distinctBy$ function takes care of this.
    71 In $\bsimps$, the $\distinctBy$ function takes care of 
       
    72 such instances.
    68 The criteria $\distinctBy$ uses for removing a duplicate
    73 The criteria $\distinctBy$ uses for removing a duplicate
    69 $a_2$ in the list
    74 $a_2$ in the list
    70 \begin{center}
    75 \begin{center}
    71 	$rs_a@[a_1]@rs_b@[a_2]@rs_c$
    76 	$rs_a@[a_1]@rs_b@[a_2]@rs_c$
    72 \end{center}
    77 \end{center}
    73 is that 
    78 is that 
    74 \begin{center}
    79 \begin{center}
    75 	$\rerase{a_1} = \rerase{a_2}$.
    80 	$\rerase{a_1} = \rerase{a_2}$.
    76 \end{center}
    81 \end{center}
    77 It can be characterised as the $LD$ 
    82 It is characterised as the $LD$ 
    78 rewrite rule in \ref{rrewriteRules}.\\
    83 rewrite rule in figure \ref{rrewriteRules}.\\
    79 The problem , however, is that identical components
    84 The problem , however, is that identical components
    80 in two slightly different regular expressions cannot be removed:
    85 in two slightly different regular expressions cannot be removed.
    81 \begin{figure}[H]
    86 Consider the simplification
    82 \[
    87 \begin{equation}
       
    88 	\label{eqn:partialDedup}
    83 	(a+b+d) \cdot r_1 + (a+c+e) \cdot r_1 \stackrel{?}{\rightsquigarrow} (a+b+d) \cdot r_1 + (c+e) \cdot r_1
    89 	(a+b+d) \cdot r_1 + (a+c+e) \cdot r_1 \stackrel{?}{\rightsquigarrow} (a+b+d) \cdot r_1 + (c+e) \cdot r_1
    84 \]
    90 \end{equation}
    85 \caption{Desired simplification, but not done in $\blexersimp$}\label{partialDedup}
    91 where the $(a+\ldots)\cdot r_1$ is deleted in the right alternative.
    86 \end{figure}
    92 This is permissible because we have $(a+\ldots)\cdot r_1$ in the left
    87 \noindent
    93 alternative.
    88 A simplification like this actually
    94 The difficulty is that such  ``buried''
       
    95 alternatives-sequences are not easily recognised.
       
    96 But simplification like this actually
    89 cannot be omitted,
    97 cannot be omitted,
    90 as without it the size could blow up even with our $\textit{bsimp}$ 
    98 as without it the size of derivatives can still
    91 function: for the chapter \ref{Finite} example
    99 blow up even with our $\textit{bsimp}$ 
       
   100 function: 
       
   101 consider again the example
    92 $\protect((a^* + (aa)^* + \ldots + (\underbrace{a\ldots a}_{n a's})^* )^*)^*$,
   102 $\protect((a^* + (aa)^* + \ldots + (\underbrace{a\ldots a}_{n a's})^* )^*)^*$,
    93 by just setting n to a small number,
   103 and set $n$ to a relatively small number,
    94 we get exponential growth that does not stop before it becomes huge: 
   104 we get exponential growth:
    95 \begin{figure}[H]
   105 \begin{figure}[H]
    96 \centering
   106 \centering
    97 \begin{tikzpicture}
   107 \begin{tikzpicture}
    98 \begin{axis}[
   108 \begin{axis}[
    99     %xlabel={$n$},
   109     %xlabel={$n$},
   102     ylabel={size},
   112     ylabel={size},
   103     ]
   113     ]
   104 \addplot[blue,mark=*, mark options={fill=white}] table {bsimpExponential.data};
   114 \addplot[blue,mark=*, mark options={fill=white}] table {bsimpExponential.data};
   105 \end{axis}
   115 \end{axis}
   106 \end{tikzpicture}
   116 \end{tikzpicture}
   107 \caption{Runtime of $\blexersimp$ for matching 
   117 \caption{Size of derivatives of $\blexersimp$ for matching 
   108 	$\protect((a^* + (aa)^* + \ldots + (aaaaa)^* )^*)^*$ 
   118 	$\protect((a^* + (aa)^* + \ldots + (aaaaa)^* )^*)^*$ 
   109 	with strings 
   119 	with strings 
   110 	of the form $\protect\underbrace{aa..a}_{n}$.}\label{blexerExp}
   120 	of the form $\protect\underbrace{aa..a}_{n}$.}\label{blexerExp}
   111 \end{figure}
   121 \end{figure}
   112 \noindent
   122 \noindent
   113 We would like to apply the rewriting at some stage
   123 One possible approach would be to apply the rewriting
   114 \begin{figure}[H]
   124 rule
   115 \[
   125 \[
   116 	(a+b+d) \cdot r_1  \longrightarrow a \cdot r_1 + b \cdot r_1 + d \cdot r_1
   126 	(a+b+d) \cdot r_1  \longrightarrow a \cdot r_1 + b \cdot r_1 + d \cdot r_1
   117 \]
   127 \]
   118 \caption{Desired simplification, but not done in $\blexersimp$}\label{desiredSimp}
       
   119 \end{figure}
       
   120 \noindent
   128 \noindent
   121 in our $\simp$ function,
   129 in our $\simp$ function,
   122 so that it makes the simplification in \ref{partialDedup} possible.
   130 so that it makes the simplification in \eqref{eqn:partialDedup} possible.
   123 Translating the rule into our $\textit{bsimp}$ function simply
   131 Translating the rule into our $\textit{bsimp}$ function simply
   124 involves adding a new clause to the $\textit{bsimp}_{ASEQ}$ function:
   132 involves adding a new clause to the $\textit{bsimp}_{ASEQ}$ function:
   125 \begin{center}
   133 \begin{center}
   126 	\begin{tabular}{@{}lcl@{}}
   134 	\begin{tabular}{@{}lcl@{}}
   127 		$\textit{bsimp}_{ASEQ} \; bs\; a \; b$ & $\dn$ & $ (a,\; b) \textit{match}$\\
   135 		$\textit{bsimp}_{ASEQ} \; bs\; a \; b$ & $\dn$ & $ (a,\; b) \textit{match}$\\
   129    &&$\quad\textit{case} \; (_{bs1}\sum as, a_2') \Rightarrow _{bs1}\sum (
   137    &&$\quad\textit{case} \; (_{bs1}\sum as, a_2') \Rightarrow _{bs1}\sum (
   130    \map \; (_{[]}\textit{ASEQ} \; \_ \; a_2') \; as)$\\
   138    \map \; (_{[]}\textit{ASEQ} \; \_ \; a_2') \; as)$\\
   131    &&$\quad\textit{case} \; (a_1', a_2') \Rightarrow   _{bs}a_1' \cdot a_2'$ \\
   139    &&$\quad\textit{case} \; (a_1', a_2') \Rightarrow   _{bs}a_1' \cdot a_2'$ \\
   132 	\end{tabular}
   140 	\end{tabular}
   133 \end{center}
   141 \end{center}
   134 
   142 \noindent
   135 
       
   136 
       
   137 Unfortunately,
   143 Unfortunately,
   138 if we introduce them in our
   144 if we introduce them in our
   139 setting we would lose the POSIX property of our calculated values. 
   145 setting we would lose the POSIX property of our calculated values. 
   140 For example given the regular expression 
   146 For example given the regular expression 
   141 \begin{center}
   147 \begin{center}
   142 	$(a + ab)(bc + c)$
   148 	$(a + ab)(bc + c)$
   143 \end{center}
   149 \end{center}
   144 and the string
   150 and the string $ab$,
   145 \begin{center}
       
   146 	$ab$,
       
   147 \end{center}
       
   148 then our algorithm generates the following
   151 then our algorithm generates the following
   149 correct POSIX value
   152 correct POSIX value
   150 \begin{center}
   153 \begin{center}
   151 	$\Seq \; (\Right \; ab) \; (\Right \; c)$.
   154 	$\Seq \; (\Right \; ab) \; (\Right \; c)$.
   152 \end{center}
   155 \end{center}
   163 is that the new rule splits this regular expression up into 
   166 is that the new rule splits this regular expression up into 
   164 \begin{center}
   167 \begin{center}
   165 	$a\cdot(b c + c) + ab \cdot (bc + c)$,
   168 	$a\cdot(b c + c) + ab \cdot (bc + c)$,
   166 \end{center}
   169 \end{center}
   167 which becomes a regular expression with a 
   170 which becomes a regular expression with a 
   168 totally different structure--the original
   171 quite different structure--the original
   169 was a sequence, and now it becomes an alternative.
   172 was a sequence, and now it becomes an alternative.
   170 With an alternative the maximum munch rule no longer works.\\
   173 With an alternative the maximal munch rule no longer works.\\
   171 A method to reconcile this is to do the 
   174 A method to reconcile this is to do the 
   172 transformation in \ref{desiredSimp} ``non-invasively'',
   175 transformation in \eqref{eqn:partialDedup} ``non-invasively'',
   173 meaning that we traverse the list of regular expressions
   176 meaning that we traverse the list of regular expressions
   174 \begin{center}
   177 \begin{center}
   175 	$rs_a@[a]@rs_c$
   178 	$rs_a@[a]@rs_c$
   176 \end{center}
   179 \end{center}
   177 in the alternative
   180 in the alternative
   179 	$\sum ( rs_a@[a]@rs_c)$
   182 	$\sum ( rs_a@[a]@rs_c)$
   180 \end{center}
   183 \end{center}
   181 using  a function similar to $\distinctBy$,
   184 using  a function similar to $\distinctBy$,
   182 but this time 
   185 but this time 
   183 we allow a more general list rewrite:
   186 we allow a more general list rewrite:
   184 \begin{mathpar}\label{cubicRule}
   187 \begin{figure}[H]
       
   188 \begin{mathpar}	
   185 	\inferrule * [Right = cubicRule]{\vspace{0mm} }{rs_a@[a]@rs_c 
   189 	\inferrule * [Right = cubicRule]{\vspace{0mm} }{rs_a@[a]@rs_c 
   186 			\stackrel{s}{\rightsquigarrow }
   190 			\stackrel{s}{\rightsquigarrow }
   187 		rs_a@[\textit{prune} \; a \; rs_a]@rs_c }
   191 		rs_a@[\textit{prune} \; a \; rs_a]@rs_c }
   188 \end{mathpar}
   192 \end{mathpar}
       
   193 \caption{The rule capturing the pruning simplification needed to achieve
       
   194 a cubic bound}
       
   195 \label{fig:cubicRule}
       
   196 \end{figure}
   189 %L \; a_1' = L \; a_1 \setminus (\cup_{a \in rs_a} L \; a)
   197 %L \; a_1' = L \; a_1 \setminus (\cup_{a \in rs_a} L \; a)
   190 where $\textit{prune} \;a \; acc$ traverses $a$
   198 where $\textit{prune} \;a \; acc$ traverses $a$
   191 without altering the structure of $a$, removing components in $a$
   199 without altering the structure of $a$, removing components in $a$
   192 that have appeared in the accumulator $acc$.
   200 that have appeared in the accumulator $acc$.
   193 For example
   201 For example
   203 that have not appeared in the accumulator list 
   211 that have not appeared in the accumulator list 
   204 \begin{center}
   212 \begin{center}
   205 $[(r_a+r_b+r_c)r_d, (r_e+r_f)r_d]$.
   213 $[(r_a+r_b+r_c)r_d, (r_e+r_f)r_d]$.
   206 \end{center}
   214 \end{center}
   207 We implemented 
   215 We implemented 
   208 function $\textit{prune}$ in Scala,
   216 function $\textit{prune}$ in Scala:
   209 and incorporated into our lexer,
       
   210 by replacing the $\simp$ function 
       
   211 with a stronger version called $\bsimpStrong$
       
   212 that prunes regular expressions.
       
   213 \begin{figure}[H]
   217 \begin{figure}[H]
   214 
       
   215 \begin{lstlisting}
   218 \begin{lstlisting}
   216     def atMostEmpty(r: Rexp) : Boolean = r match {
       
   217       case ZERO => true
       
   218       case ONE => true
       
   219       case STAR(r) => atMostEmpty(r)
       
   220       case SEQ(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2)
       
   221       case ALTS(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2)
       
   222       case CHAR(_) => false
       
   223     }
       
   224 
       
   225 
       
   226     def isOne(r: Rexp) : Boolean = r match {
       
   227       case ONE => true
       
   228       case SEQ(r1, r2) => isOne(r1) && isOne(r2)
       
   229       case ALTS(r1, r2) => (isOne(r1) || isOne(r2)) && (atMostEmpty(r1) && atMostEmpty(r2))//rs.forall(atMostEmpty) && rs.exists(isOne)
       
   230       case STAR(r0) => atMostEmpty(r0)
       
   231       case CHAR(c) => false
       
   232       case ZERO => false
       
   233     }
       
   234 
       
   235     //r = r' ~ tail' : If tail' matches tail => returns r'
       
   236     def removeSeqTail(r: Rexp, tail: Rexp) : Rexp = r match {
       
   237       case SEQ(r1, r2) => 
       
   238         if(r2 == tail) 
       
   239           r1
       
   240         else
       
   241           ZERO
       
   242       case r => ZERO
       
   243     }
       
   244 
       
   245     def prune(r: ARexp, acc: Set[Rexp]) : ARexp = r match{
   219     def prune(r: ARexp, acc: Set[Rexp]) : ARexp = r match{
   246       case AALTS(bs, rs) => rs.map(r => prune(r, acc)).filter(_ != ZERO) match
   220       case AALTS(bs, rs) => rs.map(r => prune(r, acc)).filter(_ != AZERO) match
   247       {
   221       {
   248         //all components have been removed, meaning this is effectively a duplicate
   222         //all components have been removed, meaning this is effectively a duplicate
   249         //flats will take care of removing this AZERO 
   223         //flats will take care of removing this AZERO 
   250         case Nil => AZERO
   224         case Nil => AZERO
   251         case r::Nil => fuse(bs, r)
   225         case r::Nil => fuse(bs, r)
   263         }
   237         }
   264         //this does the duplicate component removal task
   238         //this does the duplicate component removal task
   265       case r => if(acc(erase(r))) AZERO else r
   239       case r => if(acc(erase(r))) AZERO else r
   266     }
   240     }
   267 \end{lstlisting}
   241 \end{lstlisting}
   268 \caption{pruning function together with its helper functions}
   242 \caption{The function $\textit{prune}$ }
   269 \end{figure}
   243 \end{figure}
   270 \noindent
   244 \noindent
   271 The benefits of using 
   245 The function $\textit{prune}$ 
   272 $\textit{prune}$ such as refining the finiteness bound
   246 is a stronger version of $\textit{distinctBy}$.
   273 to a cubic bound has not been formalised yet.
   247 It does not just walk through a list looking for exact duplicates,
   274 Therefore we choose to use Scala code rather than an Isabelle-style formal 
   248 but prunes sub-expressions recursively.
   275 definition like we did for $\simp$, as the definitions might change
   249 It manages proper contexts by the helper functions
   276 to suit proof needs.
   250 $\textit{removeSeqTail}$, $\textit{isOne}$ and $\textit{atMostEmpty}$.
   277 In the rest of the chapter we will use this convention consistently.
       
   278 \begin{figure}[H]
   251 \begin{figure}[H]
   279 \begin{lstlisting}
   252 \begin{lstlisting}
   280   def distinctWith(rs: List[ARexp], 
   253     def atMostEmpty(r: Rexp) : Boolean = r match {
   281     pruneFunction: (ARexp, Set[Rexp]) => ARexp, 
   254       case ZERO => true
   282     acc: Set[Rexp] = Set()) : List[ARexp] = 
   255       case ONE => true
   283       rs match{
   256       case STAR(r) => atMostEmpty(r)
   284         case Nil => Nil
   257       case SEQ(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2)
   285         case r :: rs => 
   258       case ALTS(r1, r2) => atMostEmpty(r1) && atMostEmpty(r2)
   286           if(acc(erase(r)))
   259       case CHAR(_) => false
   287             distinctWith(rs, pruneFunction, acc)
   260     }
   288           else {
   261 
   289             val pruned_r = pruneFunction(r, acc)
   262     def isOne(r: Rexp) : Boolean = r match {
   290             pruned_r :: 
   263       case ONE => true
   291             distinctWith(rs, 
   264       case SEQ(r1, r2) => isOne(r1) && isOne(r2)
   292               pruneFunction, 
   265       case ALTS(r1, r2) => (isOne(r1) || isOne(r2)) && (atMostEmpty(r1) && atMostEmpty(r2))
   293               turnIntoTerms(erase(pruned_r)) ++: acc
   266       case STAR(r0) => atMostEmpty(r0)
   294               )
   267       case CHAR(c) => false
   295           }
   268       case ZERO => false
       
   269     }
       
   270 
       
   271     def removeSeqTail(r: Rexp, tail: Rexp) : Rexp = 
       
   272       if (r == tail)
       
   273         ONE
       
   274       else {
       
   275         r match {
       
   276           case SEQ(r1, r2) => 
       
   277             if(r2 == tail) 
       
   278               r1
       
   279             else
       
   280               ZERO
       
   281           case r => ZERO
       
   282         }
   296       }
   283       }
       
   284 
       
   285 
       
   286 \end{lstlisting}
       
   287 \caption{The helper functions of $\textit{prune}$}
       
   288 \end{figure}
       
   289 \noindent
       
   290 Suppose we feed 
       
   291 \begin{center}
       
   292 	$r= (\underline{\ONE}+(\underline{f}+b)\cdot g)\cdot (a\cdot(d\cdot e))$
       
   293 \end{center}
       
   294 and 
       
   295 \begin{center}
       
   296 	$acc = \{a\cdot(d\cdot e),f\cdot (g \cdot (a \cdot (d \cdot e))) \}$
       
   297 \end{center}
       
   298 as the input for $\textit{prune}$.
       
   299 The end result will be
       
   300 \[
       
   301 	b\cdot(g\cdot(a\cdot(d\cdot e)))
       
   302 \]
       
   303 where the underlined components in $r$ are eliminated.
       
   304 Looking more closely, at the topmost call 
       
   305 \[
       
   306 	\textit{prune} \quad (\ONE+
       
   307 	(f+b)\cdot g)\cdot (a\cdot(d\cdot e)) \quad
       
   308 	\{a\cdot(d\cdot e),f\cdot (g \cdot (a \cdot (d \cdot e))) \}
       
   309 \]
       
   310 The sequence clause will be called,
       
   311 where a sub-call
       
   312 \[
       
   313 	\textit{prune} \;\; (\ONE+(f+b)\cdot g)\;\; \{\ONE, f\cdot g \}
       
   314 \]
       
   315 is made. The terms in the new accumulator $\{\ONE,\; f\cdot g \}$ come from
       
   316 the two calls to $\textit{removeSeqTail}$:
       
   317 \[
       
   318 	\textit{removeSeqTail} \quad\;\; a \cdot(d\cdot e) \quad\;\; a \cdot(d\cdot e) 
       
   319 \]
       
   320 and
       
   321 \[
       
   322 	\textit{removeSeqTail} \quad \;\; 
       
   323 	f\cdot(g\cdot (a \cdot(d\cdot e)))\quad  \;\; a \cdot(d\cdot e).
       
   324 \]
       
   325 The idea behind $\textit{removeSeqTail}$ is that
       
   326 when pruning recursively, we need to ``zoom in''
       
   327 to sub-expressions, and this ``zoom in'' needs to be performed
       
   328 on the
       
   329 accumulators as well, otherwise we will be comparing
       
   330 apples with oranges.
       
   331 The sub-call 
       
   332 $\textit{prune} \;\; (\ONE+(f+b)\cdot g)\;\; \{\ONE, f\cdot g \}$
       
   333 is simpler, which will trigger the alternative clause, causing
       
   334 a pruning on each element in $(\ONE+(f+b)\cdot g)$,
       
   335 leaving us $b\cdot g$ only.
       
   336 
       
   337 Our new lexer with stronger simplification
       
   338 uses $\textit{prune}$ by making it 
       
   339 the core component of the deduplicating function
       
   340 called $\textit{distinctWith}$.
       
   341 $\textit{DistinctWith}$ ensures that all verbose
       
   342 parts of a regular expression are pruned away.
       
   343 
       
   344 \begin{figure}[H]
       
   345 \begin{lstlisting}
       
   346     def turnIntoTerms(r: Rexp): List[Rexp] = r match {
       
   347       case SEQ(r1, r2)  => 
       
   348         turnIntoTerms(r1).flatMap(r11 => furtherSEQ(r11, r2))
       
   349           case ALTS(r1, r2) => turnIntoTerms(r1) ::: turnIntoTerms(r2)
       
   350           case ZERO => Nil
       
   351           case _ => r :: Nil
       
   352     }
       
   353 
       
   354     def distinctWith(rs: List[ARexp], 
       
   355       pruneFunction: (ARexp, Set[Rexp]) => ARexp, 
       
   356       acc: Set[Rexp] = Set()) : List[ARexp] = 
       
   357         rs match{
       
   358           case Nil => Nil
       
   359           case r :: rs => 
       
   360             if(acc(erase(r)))
       
   361               distinctWith(rs, pruneFunction, acc)
       
   362             else {
       
   363               val pruned_r = pruneFunction(r, acc)
       
   364               pruned_r :: 
       
   365               distinctWith(rs, 
       
   366                 pruneFunction, 
       
   367                 turnIntoTerms(erase(pruned_r)) ++: acc
       
   368                 )
       
   369             }
       
   370         }
       
   371 
   297 \end{lstlisting}
   372 \end{lstlisting}
   298 \caption{A Stronger Version of $\textit{distinctBy}$}
   373 \caption{A Stronger Version of $\textit{distinctBy}$}
   299 \end{figure}
   374 \end{figure}
   300 \noindent
   375 \noindent
   301 The function $\textit{prune}$ is used in $\distinctWith$.
   376 Once a regular expression has been pruned,
   302 $\distinctWith$ is a stronger version of $\distinctBy$
   377 all its components will be added to the accumulator
   303 which not only removes duplicates as $\distinctBy$ would
   378 to remove any future regular expressions' duplicate components.
   304 do, but also uses the $\textit{pruneFunction}$
   379 
   305 argument to prune away verbose components in a regular expression.\\
   380 The function $\textit{bsimpStrong}$
       
   381 is very much the same as $\textit{bsimp}$, just with
       
   382 $\textit{distinctBy}$ replaced 
       
   383 by $\textit{distinctWith}$.
   306 \begin{figure}[H]
   384 \begin{figure}[H]
   307 \begin{lstlisting}
   385 \begin{lstlisting}
   308    //a stronger version of simp
   386 
   309     def bsimpStrong(r: ARexp): ARexp =
   387     def bsimpStrong(r: ARexp): ARexp =
   310     {
   388     {
   311       r match {
   389       r match {
   312         case ASEQ(bs1, r1, r2) => (bsimpStrong(r1), bsimpStrong(r2)) match {
   390         case ASEQ(bs1, r1, r2) => (bsimpStrong(r1), bsimpStrong(r2)) match {
   313           //normal clauses same as simp
       
   314         case (AZERO, _) => AZERO
   391         case (AZERO, _) => AZERO
   315         case (_, AZERO) => AZERO
   392         case (_, AZERO) => AZERO
   316         case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s)
   393         case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s)
   317         //bs2 can be discarded
       
   318         case (r1s, AONE(bs2)) => fuse(bs1, r1s) //assert bs2 == Nil
   394         case (r1s, AONE(bs2)) => fuse(bs1, r1s) //assert bs2 == Nil
   319         case (r1s, r2s) => ASEQ(bs1, r1s, r2s)
   395         case (r1s, r2s) => ASEQ(bs1, r1s, r2s)
   320         }
   396         }
   321         case AALTS(bs1, rs) => {
   397         case AALTS(bs1, rs) => {
   322           //distinctBy(flat_res, erase)
       
   323           distinctWith(flats(rs.map(bsimpStrong(_))), prune) match {
   398           distinctWith(flats(rs.map(bsimpStrong(_))), prune) match {
   324             case Nil => AZERO
   399             case Nil => AZERO
   325             case s :: Nil => fuse(bs1, s)
   400             case s :: Nil => fuse(bs1, s)
   326             case rs => AALTS(bs1, rs)
   401             case rs => AALTS(bs1, rs)
   327           }
   402           }
   328         }
   403         }
   329         //stars that can be treated as 1
       
   330         case ASTAR(bs, r0) if(atMostEmpty(erase(r0))) => AONE(bs)
   404         case ASTAR(bs, r0) if(atMostEmpty(erase(r0))) => AONE(bs)
   331         case r => r
   405         case r => r
   332       }
   406       }
   333     }
   407     }
   334 \end{lstlisting}
   408     def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match {
   335 \caption{The function $\bsimpStrong$ and $\bdersStrongs$}
       
   336 \end{figure}
       
   337 \noindent
       
   338 $\distinctWith$, is in turn used in $\bsimpStrong$:
       
   339 \begin{figure}[H]
       
   340 \begin{lstlisting}
       
   341       //Conjecture: [| bdersStrong(s, r) |] = O([| r |]^3)
       
   342       def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match {
       
   343         case Nil => r
   409         case Nil => r
   344         case c::s => bdersStrong(s, bsimpStrong(bder(c, r)))
   410         case c::s => bdersStrong(s, bsimpStrong(bder(c, r)))
   345       }
   411       }
       
   412 
   346 \end{lstlisting}
   413 \end{lstlisting}
   347 \caption{The function $\bsimpStrong$ and $\bdersStrongs$}
   414 \caption{The function
       
   415 $\textit{bsimpStrong}$: a stronger version of $\textit{bsimp}$}
   348 \end{figure}
   416 \end{figure}
   349 \noindent
   417 \noindent
       
   418 The benefits of using 
       
   419 $\textit{prune}$ refining the finiteness bound
       
   420 to a cubic bound has not been formalised yet.
       
   421 Therefore we choose to use Scala code rather than an Isabelle-style formal 
       
   422 definition like we did for $\simp$, as the definitions might change
       
   423 to suit our proof needs.
       
   424 In the rest of the chapter we will use this convention consistently.
       
   425 
       
   426 %The function $\textit{prune}$ is used in $\distinctWith$.
       
   427 %$\distinctWith$ is a stronger version of $\distinctBy$
       
   428 %which not only removes duplicates as $\distinctBy$ would
       
   429 %do, but also uses the $\textit{pruneFunction}$
       
   430 %argument to prune away verbose components in a regular expression.\\
       
   431 %\begin{figure}[H]
       
   432 %\begin{lstlisting}
       
   433 %   //a stronger version of simp
       
   434 %    def bsimpStrong(r: ARexp): ARexp =
       
   435 %    {
       
   436 %      r match {
       
   437 %        case ASEQ(bs1, r1, r2) => (bsimpStrong(r1), bsimpStrong(r2)) match {
       
   438 %          //normal clauses same as simp
       
   439 %        case (AZERO, _) => AZERO
       
   440 %        case (_, AZERO) => AZERO
       
   441 %        case (AONE(bs2), r2s) => fuse(bs1 ++ bs2, r2s)
       
   442 %        //bs2 can be discarded
       
   443 %        case (r1s, AONE(bs2)) => fuse(bs1, r1s) //assert bs2 == Nil
       
   444 %        case (r1s, r2s) => ASEQ(bs1, r1s, r2s)
       
   445 %        }
       
   446 %        case AALTS(bs1, rs) => {
       
   447 %          //distinctBy(flat_res, erase)
       
   448 %          distinctWith(flats(rs.map(bsimpStrong(_))), prune) match {
       
   449 %            case Nil => AZERO
       
   450 %            case s :: Nil => fuse(bs1, s)
       
   451 %            case rs => AALTS(bs1, rs)
       
   452 %          }
       
   453 %        }
       
   454 %        //stars that can be treated as 1
       
   455 %        case ASTAR(bs, r0) if(atMostEmpty(erase(r0))) => AONE(bs)
       
   456 %        case r => r
       
   457 %      }
       
   458 %    }
       
   459 %    def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match {
       
   460 %        case Nil => r
       
   461 %        case c::s => bdersStrong(s, bsimpStrong(bder(c, r)))
       
   462 %      }
       
   463 %\end{lstlisting}
       
   464 %\caption{The function $\bsimpStrong$ and $\bdersStrongs$}
       
   465 %\end{figure}
       
   466 %\noindent
       
   467 %$\distinctWith$, is in turn used in $\bsimpStrong$:
       
   468 %\begin{figure}[H]
       
   469 %\begin{lstlisting}
       
   470 %      //Conjecture: [| bdersStrong(s, r) |] = O([| r |]^3)
       
   471 %      def bdersStrong(s: List[Char], r: ARexp) : ARexp = s match {
       
   472 %        case Nil => r
       
   473 %        case c::s => bdersStrong(s, bsimpStrong(bder(c, r)))
       
   474 %      }
       
   475 %\end{lstlisting}
       
   476 %\caption{The function $\bsimpStrong$ and $\bdersStrongs$}
       
   477 %\end{figure}
       
   478 %\noindent
   350 We conjecture that the above Scala function $\bdersStrongs$,
   479 We conjecture that the above Scala function $\bdersStrongs$,
   351 written $\bdersStrong{\_}{\_}$ as an infix notation, 
   480 written $\bdersStrong{\_}{\_}$ as an infix notation, 
   352 satisfies the following property:
   481 satisfies the following property:
   353 \begin{conjecture}
   482 \begin{conjecture}
   354 	$\llbracket \bdersStrong{a}{s} \rrbracket = O(\llbracket a \rrbracket^3)$
   483 	$\llbracket \bdersStrong{a}{s} \rrbracket = O(\llbracket a \rrbracket^3)$
   355 \end{conjecture}
   484 \end{conjecture}
       
   485 \noindent
   356 The stronger version of $\blexersimp$'s
   486 The stronger version of $\blexersimp$'s
   357 code in Scala looks like: 
   487 code in Scala looks like: 
   358 \begin{figure}[H]
   488 \begin{figure}[H]
   359 \begin{lstlisting}
   489 \begin{lstlisting}
   360       def strongBlexer(r: Rexp, s: String) : Option[Val] = {
   490       def strongBlexer(r: Rexp, s: String) : Option[Val] = {
   374       }
   504       }
   375 \end{lstlisting}
   505 \end{lstlisting}
   376 \end{figure}
   506 \end{figure}
   377 \noindent
   507 \noindent
   378 We call this lexer $\blexerStrong$.
   508 We call this lexer $\blexerStrong$.
   379 $\blexerStrong$ is able to drastically reduce the
   509 This version is able to drastically reduce the
   380 internal data structure size which could
   510 internal data structure size which 
       
   511 otherwise could
   381 trigger exponential behaviours in
   512 trigger exponential behaviours in
   382 $\blexersimp$.
   513 $\blexersimp$.
   383 \begin{figure}[H]
   514 \begin{figure}[H]
   384 \centering
   515 \centering
   385 \begin{tabular}{@{}c@{\hspace{0mm}}c@{\hspace{0mm}}c@{}}
   516 \begin{tabular}{@{}c@{\hspace{0mm}}c@{\hspace{0mm}}c@{}}
   422 \end{conjecture}
   553 \end{conjecture}
   423 \noindent
   554 \noindent
   424 The idea is to maintain key lemmas in
   555 The idea is to maintain key lemmas in
   425 chapter \ref{Bitcoded2} like
   556 chapter \ref{Bitcoded2} like
   426 $r \stackrel{*}{\rightsquigarrow} \textit{bsimp} \; r$
   557 $r \stackrel{*}{\rightsquigarrow} \textit{bsimp} \; r$
   427 with the new rewriting rule \ref{cubicRule} .
   558 with the new rewriting rule 
       
   559 shown in figure \ref{fig:cubicRule} .
   428 
   560 
   429 In the next sub-section,
   561 In the next sub-section,
   430 we will describe why we 
   562 we will describe why we 
   431 believe a cubic bound can be achieved.
   563 believe a cubic size bound can be achieved with
   432 We give an introduction to the
   564 the stronger simplification.
       
   565 For this we give a short introduction to the
   433 partial derivatives,
   566 partial derivatives,
   434 which was invented by Antimirov \cite{Antimirov95},
   567 which were invented by Antimirov \cite{Antimirov95},
   435 and then link it with the result of the function
   568 and then link them with the result of the function
   436 $\bdersStrongs$.
   569 $\bdersStrongs$.
   437  
   570  
   438 \subsection{Antimirov's partial derivatives}
   571 \subsection{Antimirov's partial derivatives}
   439 Partial derivatives were first introduced by 
   572 Partial derivatives were first introduced by 
   440 Antimirov \cite{Antimirov95}.
   573 Antimirov \cite{Antimirov95}.
   441 It does derivatives in a similar way as suggested by Brzozowski, 
   574 Partial derivatives are very similar
       
   575 to Brzozowski derivatives,
   442 but splits children of alternative regular expressions into 
   576 but splits children of alternative regular expressions into 
   443 multiple independent terms, causing the output to become a 
   577 multiple independent terms. This means the output of
       
   578 partial derivatives become a 
   444 set of regular expressions:
   579 set of regular expressions:
   445 \begin{center}  
   580 \begin{center}  
   446  	\begin{tabular}{lcl}
   581  	\begin{tabular}{lcl}
   447 		$\partial_x \; (a \cdot b)$ & 
   582 		$\partial_x \; (r_1 \cdot r_2)$ & 
   448 		$\dn$ & $\partial_x \; a\cdot b \cup
   583 		$\dn$ & $(\partial_x \; r_1) \cdot r_2 \cup
   449 		\partial_x \; b \; \textit{if} \; \; \nullable\; a$\\
   584 		\partial_x \; r_2 \; \textit{if} \; \; \nullable\; r_1$\\
   450 		      & & $\partial_x \; a\cdot b \quad\quad 
   585 		      & & $(\partial_x \; r_1)\cdot r_2 \quad\quad 
   451 		      \textit{otherwise}$\\ 
   586 		      \textit{otherwise}$\\ 
   452 		$\partial_x \; r^*$ & $\dn$ & $\partial_x \; r \cdot r^*$\\
   587 		$\partial_x \; r^*$ & $\dn$ & $(\partial_x \; r) \cdot r^*$\\
   453 		$\partial_x \; c $ & $\dn$ & $\textit{if} \; x = c \; 
   588 		$\partial_x \; c $ & $\dn$ & $\textit{if} \; x = c \; 
   454 		\textit{then} \;
   589 		\textit{then} \;
   455 		\{ \ONE\} \;\;\textit{else} \; \varnothing$\\
   590 		\{ \ONE\} \;\;\textit{else} \; \varnothing$\\
   456 		$\partial_x(a+b)$ & $=$ & $\partial_x(a) \cup \partial_x(b)$\\
   591 		$\partial_x(r_1+r_2)$ & $=$ & $\partial_x(r_1) \cup \partial_x(r_2)$\\
   457 		$\partial_x(\ONE)$ & $=$ & $\varnothing$\\
   592 		$\partial_x(\ONE)$ & $=$ & $\varnothing$\\
   458 		$\partial_x(\ZERO)$ & $\dn$ & $\varnothing$\\
   593 		$\partial_x(\ZERO)$ & $\dn$ & $\varnothing$\\
   459 	\end{tabular}
   594 	\end{tabular}
   460 \end{center}
   595 \end{center}
   461 \noindent
   596 \noindent
   462 The $\cdot$ between for example 
   597 The $\cdot$ between for example 
   463 $\partial_x \; a\cdot b $ 
   598 $(\partial_x \; r_1) \cdot r_2 $ 
   464 is a shorthand notation for the cartesian product 
   599 is a shorthand notation for the cartesian product 
   465 $\partial_x \; a \times \{ b\}$.
   600 $(\partial_x \; r_1) \times \{ r_2\}$.
   466 %Each element in the set generated by a partial derivative
   601 %Each element in the set generated by a partial derivative
   467 %corresponds to a (potentially partial) match
   602 %corresponds to a (potentially partial) match
   468 %TODO: define derivatives w.r.t string s
   603 %TODO: define derivatives w.r.t string s
   469 Rather than joining the calculated derivatives $\partial_x a$ and $\partial_x b$ together
   604 Rather than joining the calculated derivatives $\partial_x r_1$ and $\partial_x r_2$ together
   470 using the $\sum$ constructor, Antimirov put them into
   605 using the $\sum$ constructor, Antimirov put them into
   471 a set.  This causes maximum de-duplication to happen, 
   606 a set.  This means many subterms will be de-duplicated
   472 allowing us to understand what are the "atomic" components of it.
   607 because they are sets, 
   473 For example, To compute what regular expression $x^*(xx + y)^*$'s 
   608 For example, to compute what regular expression $x^*(xx + y)^*$'s 
   474 derivative against $x$ is made of, one can do a partial derivative
   609 derivative w.r.t. $x$ is, one can compute a partial derivative
   475 of it and get two singleton sets $\{x^* \cdot (xx + y)^*\}$ and $\{x \cdot (xx + y) ^* \}$
   610 and get two singleton sets $\{x^* \cdot (xx + y)^*\}$ and $\{x \cdot (xx + y) ^* \}$
   476 from $\partial_x(x^*) \cdot (xx + y) ^*$ and $\partial_x((xx + y)^*)$.
   611 from $\partial_x(x^*) \cdot (xx + y) ^*$ and $\partial_x((xx + y)^*)$.
   477 
   612 
       
   613 The partial derivative w.r.t. a string is defined recursively:
       
   614 \[
       
   615 	\partial_{c::cs} r \dn \bigcup_{r'\in (\partial_c r)}
       
   616 	\partial_{cs} r'
       
   617 \]
       
   618 Given an alphabet $\Sigma$, we denote the set of all possible strings
       
   619 from this alphabet as $\Sigma^*$. 
   478 The set of all possible partial derivatives is defined
   620 The set of all possible partial derivatives is defined
   479 as the union of derivatives w.r.t all the strings in the universe:
   621 as the union of derivatives w.r.t all the strings in the universe:
   480 \begin{center}
   622 \begin{center}
   481 	\begin{tabular}{lcl}
   623 	\begin{tabular}{lcl}
   482 		$\textit{PDER}_{UNIV} \; r $ & $\dn $ & $\bigcup_{w \in A^*}\partial_w \; r$
   624 		$\textit{PDER}_{\Sigma^*} \; r $ & $\dn $ & $\bigcup_{w \in \Sigma^*}\partial_w \; r$
   483 	\end{tabular}
   625 	\end{tabular}
   484 \end{center}
   626 \end{center}
   485 \noindent
   627 \noindent
   486 
   628 Consider now again our pathological case where the derivatives
   487 Back to our 
   629 grow with a rather aggressive simplification
   488 \begin{center}
   630 \begin{center}
   489 	$((a^* + (aa)^* + \ldots + (\underbrace{a\ldots a}_{n a's})^* )^*)^*$
   631 	$((a^* + (aa)^* + \ldots + (\underbrace{a\ldots a}_{n a's})^* )^*)^*$
   490 \end{center}
   632 \end{center}
   491 example, if we denote this regular expression as $A$,
   633 example, if we denote this regular expression as $r$,
   492 we have that
   634 we have that
   493 \begin{center}
   635 \begin{center}
   494 $\textit{PDER}_{UNIV} \; A = 
   636 $\textit{PDER}_{\Sigma^*} \; r = 
   495 \bigcup_{i=1}^{n}\bigcup_{j=0}^{i-1} \{ 
   637 \bigcup_{i=1}^{n}\bigcup_{j=0}^{i-1} \{ 
   496 	(\underbrace{a \ldots a}_{\text{j a's}}\cdot
   638 	(\underbrace{a \ldots a}_{\text{j a's}}\cdot
   497 (\underbrace{a \ldots a}_{\text{i a's}})^*)\cdot A \}$, 
   639 (\underbrace{a \ldots a}_{\text{i a's}})^*)\cdot r \}$, 
   498 \end{center}
   640 \end{center}
   499 with exactly $n * (n + 1) / 2$ terms.
   641 with exactly $n * (n + 1) / 2$ terms.
   500 This is in line with our speculation that only $n*(n+1)/2$ terms are
   642 This is in line with our speculation that only $n*(n+1)/2$ terms are
   501 needed. We conjecture that $\bsimpStrong$ is also able to achieve this
   643 needed. We conjecture that $\bsimpStrong$ is also able to achieve this
   502 upper limit in general
   644 upper limit in general
   503 \begin{conjecture}\label{bsimpStrongInclusionPder}
   645 \begin{conjecture}\label{bsimpStrongInclusionPder}
   504 	Using a suitable transformation $f$, we have 
   646 	Using a suitable transformation $f$, we have 
   505 	\begin{center}
   647 	\begin{center}
   506 		$\forall s.\; f \; (r \bdersStrong  \; s) \subseteq
   648 		$\forall s.\; f \; (r \bdersStrong  \; s) \subseteq
   507 		 \textit{PDER}_{UNIV} \; r$
   649 		 \textit{PDER}_{\Sigma^*} \; r$
   508 	\end{center}
   650 	\end{center}
   509 \end{conjecture}
   651 \end{conjecture}
   510 \noindent
   652 \noindent
   511 because our \ref{cubicRule} will keep only one copy of each term,
   653 because our \ref{fig:cubicRule} will keep only one copy of each term,
   512 where the function $\textit{prune}$ takes care of maintaining
   654 where the function $\textit{prune}$ takes care of maintaining
   513 a set like structure similar to partial derivatives.
   655 a set like structure similar to partial derivatives.
   514 It is anticipated we might need to adjust $\textit{prune}$
   656 We might need to adjust $\textit{prune}$
   515 slightly to make sure all duplicate terms are eliminated,
   657 slightly to make sure all duplicate terms are eliminated,
   516 which should be doable.
   658 which should be doable.
   517 
   659 
   518 Antimirov had proven that the sum of all the partial derivative 
   660 Antimirov had proven that the sum of all the partial derivative 
   519 terms' sizes is bounded by the cubic of the size of that regular
   661 terms' sizes is bounded by the cubic of the size of that regular
   520 expression:
   662 expression:
   521 \begin{property}\label{pderBound}
   663 \begin{property}\label{pderBound}
   522 	$\llbracket \textit{PDER}_{UNIV} \; r \rrbracket \leq O((\llbracket r \rrbracket)^3)$
   664 	$\llbracket \textit{PDER}_{\Sigma^*} \; r \rrbracket \leq O(\llbracket r \rrbracket^3)$
   523 \end{property}
   665 \end{property}
   524 This property was formalised by Urban, and the details are in the PDERIVS.thy file
   666 This property was formalised by Wu et al. \cite{Wu2014}, and the 
   525 in our repository.
   667 details can be found in the archive of formal proofs. \footnote{https://www.isa-afp.org/entries/Myhill-Nerode.html}
   526 Once conjecture \ref{bsimpStrongInclusionPder} is proven, then property \ref{pderBound}
   668 Once conjecture \ref{bsimpStrongInclusionPder} is proven, then property \ref{pderBound}
   527 would yield us a cubic bound for our $\blexerStrong$ algorithm: 
   669 would yield us also a cubic bound for our $\blexerStrong$ algorithm: 
   528 \begin{conjecture}\label{strongCubic}
   670 \begin{conjecture}\label{strongCubic}
   529 	$\llbracket r \bdersStrong\; s \rrbracket \leq \llbracket r \rrbracket^3$
   671 	$\llbracket r \bdersStrong\; s \rrbracket \leq \llbracket r \rrbracket^3$
   530 \end{conjecture}
   672 \end{conjecture}
       
   673 \noindent
       
   674 We leave this as future work.
   531 
   675 
   532 
   676 
   533 %To get all the "atomic" components of a regular expression's possible derivatives,
   677 %To get all the "atomic" components of a regular expression's possible derivatives,
   534 %there is a procedure Antimirov called $\textit{lf}$, short for "linear forms", that takes
   678 %there is a procedure Antimirov called $\textit{lf}$, short for "linear forms", that takes
   535 %whatever character is available at the head of the string inside the language of a
   679 %whatever character is available at the head of the string inside the language of a
   746 %		cs \; r \; [\Some \; ([c], n)]$\\
   890 %		cs \; r \; [\Some \; ([c], n)]$\\
   747 %		$\ntset \; r\; 0 \; \_$ &  $\dn$ &  $\None$\\
   891 %		$\ntset \; r\; 0 \; \_$ &  $\dn$ &  $\None$\\
   748 %		$\ntset \; r \; \_ \; [] $ & $ \dn$ & $[]$\\
   892 %		$\ntset \; r \; \_ \; [] $ & $ \dn$ & $[]$\\
   749 %	\end{tabular}
   893 %	\end{tabular}
   750 %\end{center}
   894 %\end{center}
       
   895