(************** Content-type: application/mathematica ************** CreatedBy='Mathematica 5.0' Mathematica-Compatible Notebook This notebook can be used with any Mathematica-compatible application, such as Mathematica, MathReader or Publicon. The data for the notebook starts with the line containing stars above. To get the notebook into a Mathematica-compatible application, do one of the following: * Save the data starting with the line of stars above into a file with a name ending in .nb, then open the file inside the application; * Copy the data starting with the line of stars above to the clipboard, then use the Paste menu command inside the application. Data for notebooks contains only printable 7-bit ASCII and can be sent directly in email or through ftp in text mode. Newlines can be CR, LF or CRLF (Unix, Macintosh or MS-DOS style). NOTE: If you modify the data for this notebook not in a Mathematica- compatible application, you must delete the line below containing the word CacheID, otherwise Mathematica-compatible applications may try to use invalid cache data. For more information on notebooks and Mathematica-compatible applications, contact Wolfram Research: web: http://www.wolfram.com email: info@wolfram.com phone: +1-217-398-0700 (U.S.) Notebook reader applications are available free of charge from Wolfram Research. *******************************************************************) (*CacheID: 232*) (*NotebookFileLineBreakTest NotebookFileLineBreakTest*) (*NotebookOptionsPosition[ 208925, 7035]*) (*NotebookOutlinePosition[ 264100, 8810]*) (* CellTagsIndexPosition[ 262695, 8757]*) (*WindowFrame->Normal*) Notebook[{ Cell["\[Copyright] 2003 K. Sutner ", "SmallText"], Cell[TextData[StyleBox["Words and Machines", FontFamily->"Charter"]], "Title", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:1"], Cell[CellGroupData[{ Cell["Words and Languages", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:5"], Cell[CellGroupData[{ Cell[" Words", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:6"], Cell[TextData[{ "Words are naturally implemented in ", StyleBox["Mathematica", FontSlant->"Italic"], " as strings and a number of string operations are built-in. For example, \ one can determine the length of strings, concatenate, reverse them or perform \ substitutions." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(StringLength["\"]\), "\n", \(StringJoin["\", "\"]\), "\n", \(StringReverse["\"]\), "\n", \(StringReplace["\", "\" \[Rule] "\<\>"]\)}], "Input"], Cell[TextData[{ "However, strings must be typed with quotes, a process that becomes quite \ cumbersome after a while. Also, there is the problem that the empty word is \ invisible as a string. From an algebraic point of view, the empty word serves \ as the one-element in the monoid of all words under concatenation and is thus \ used quite often. We have reserved a special symbol for it: ", StyleBox["Eps", "MR"], " or \[Epsilon]. Within this package, a word may be either a string or a ", StyleBox["Mathematica", FontSlant->"Italic"], " symbol (whose atoms should be chosen from some reasonable alphabet like \ ", Cell[BoxData[ \(TraditionalForm\`{a, b}\)]], "). Thus one can type" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(L\ = \ {\ Eps, \ aa, \ abc\ };\)\)], "InputOnly"], Cell["rather than", "Text"], Cell[BoxData[ \(\(L\ = \ {\ "\<\>", \ "\", \ "\"\ };\)\)], "InputOnly"], Cell[TextData[{ "While this will occasionally lead to problems when symbols are already \ assigned some value, in general the convenience far outstrips the problems. \ To avoid clutter in the ", StyleBox["Global", "MR"], " context, though, all procedures that generate words as output will use \ strings to represent them. Note that ", StyleBox["Automata", "MR"], " modifies the built-in function ", ButtonBox["ToString", ButtonStyle->"RefGuideLink"], " so that it treats ", StyleBox["Eps", "MR"], " properly. Also, there is a function ", ButtonBox["ToCharacters", ButtonStyle->"AddOnsLink"], " that behaves like the built-in ", ButtonBox["Characters", ButtonStyle->"RefGuideLink"], " except that it also treats ", StyleBox["Eps", "MR"], " properly and takes symbols as input. With those two function it should be \ easy to write your own procedures that manipulate words." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(ToString[Eps]\), "\n", \(FullForm[%]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(ToCharacters /@ {Eps, abab, "\"}\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The predicate ", ButtonBox["WordQ", ButtonStyle->"AddOnsLink"], " tests if a ", StyleBox["Mathematica", FontSlant->"Italic"], " expression is a word in the sense of ", StyleBox["Automata", "MR"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordQ /@ {Eps, "\", \[Epsilon], aaaaaaaaaaa, "\", 5555, \ Sin[x]\ }\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The length of a word is computed by ", ButtonBox["WordLength", ButtonStyle->"AddOnsLink"], ":" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordLength /@ {\[Epsilon], \ Eps, "\", aaaaaaaaaaa, "\"}\)], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["WordReverse", ButtonStyle->"AddOnsLink"], " flips a word around:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordReverse /@ {\[Epsilon], \ Eps, "\", aaaaaaaaaab, "\"}\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "To concatenate two or more words one can use the command ", ButtonBox["Concatenate", ButtonStyle->"AddOnsLink"], ". (", ButtonBox["StringJoin", ButtonStyle->"RefGuideLink"], " will not work on symbols). ", StyleBox["Concatenate", "MR"], " is polyadic, takes symbols as input and treats ", StyleBox["Eps", "MR"], " properly. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Concatenate[bbb, Eps, aaa]\), "\n", \(Concatenate[bbb, \[Epsilon], aaa]\), "\n", \(Concatenate[aba, bbb, aaa]\), "\n", \(Concatenate["\", bbb, "\"]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ StyleBox["Concatenate", "MR"], " also behaves properly on lists of words." }], "Text"], Cell[BoxData[ \(Concatenate[{a, b}, {a, b}, {a, b}]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["WordFusion", ButtonStyle->"AddOnsLink"], " returns the 1-fusion of two words. If the corresponding letters \ disagree, ", StyleBox["Null", "MR"], " is returned (there is no warning message since this operation is \ naturally partial)." }], "Text"], Cell[BoxData[{ \(WordFusion[aaab, bccc]\), "\[IndentingNewLine]", \(WordFusion[\ aaab, aabcc, 3\ ]\)}], "Input"], Cell[BoxData[ \(WordFusion[aaab, ccc]\ // \ FullForm\)], "Input"], Cell[TextData[{ "The command ", ButtonBox["Words", ButtonStyle->"AddOnsLink"], " produces a list of words of length ", Cell[BoxData[ \(TraditionalForm\`r\)]], " over alphabet ", Cell[BoxData[ \(TraditionalForm\`K\)]], ". If the parameter ", Cell[BoxData[ \(TraditionalForm\`r\)]], " is negative, ", StyleBox["Words", "MR"], " generates a (flat) list of all words up to length ", Cell[BoxData[ \(TraditionalForm\`\(\(|\)\(r\)\(|\)\)\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Words[3, {a, b}]\), "\n", \(Words[\(-3\), {a, b}]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "No new symbols are introduced into the ", StyleBox["Global", "MR"], " context by this call, all the words save for ", StyleBox["Eps", "MR"], " are strings." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Head /@ %\)], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["Words", ButtonStyle->"AddOnsLink"], " is one of the commands where the alphabet defaults to ", ButtonBox["$alphabet", ButtonStyle->"AddOnsLink"], ". Thus" }], "Text"], Cell[BoxData[{ \(Words[\(-3\)]\), "\[IndentingNewLine]", \(Words[\(-3\), Full \[Rule] False]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["Words", ButtonStyle->"AddOnsLink"], " can be abused in various ways:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Clear[ab]\), "\n", \(Words[\(-3\), {"\<01\>", "\<10\>"}]\), "\n", \(Words[\(-8\), {ab}]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "To generate standard digit and letter alphabets without having to type all \ the symbols you can use the command ", ButtonBox["MakeAlphabet", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(MakeAlphabet[5]\), "\n", \(MakeAlphabet[\(-5\)]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Command ", ButtonBox["RandomWord", ButtonStyle->"AddOnsLink"], StyleBox["[r,K]", "MR"], " generates one random word of length ", Cell[BoxData[ \(TraditionalForm\`r\)]], " over alphabet ", Cell[BoxData[ \(TraditionalForm\`K\)]], " (with uniformly distributed symbols). " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(RandomWord[10, 2]\)], "Input"], Cell[TextData[{ "The commands ", ButtonBox["WordPrefixes", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["WordSuffixes", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["WordFactors", ButtonStyle->"AddOnsLink"], " generate a list of all prefixes, suffixes and factors of a given word, \ respectively. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(With[\ {w = RandomWord[8, 2]}, \[IndentingNewLine]{\ WordPrefixes[w], \ WordSuffixes[w], \ WordFactors[w]}]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["WordFactorizations", ButtonStyle->"AddOnsLink"], " produces all factorizations ", Cell[BoxData[ \(TraditionalForm\`w\ = \ u\[VeryThinSpace]v\)]], " of a word ", Cell[BoxData[ \(TraditionalForm\`w\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(TableForm[WordFactorizations[abbb]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Command ", ButtonBox["WordBinomial", ButtonStyle->"RefGuideLink"], " counts the number of a occurrences of one word as a subword (a \ subsequence, not necessarily contiguous) of another. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordBinomial[abbbabb, ab]\)], "Input"], Cell["\<\ For one-letter alphabets we are dealing with simple binomial \ coefficients.\ \>", "Text"], Cell[BoxData[ \(Table[\ WordBinomial[MakeWord[a, j], MakeWord[a, i]], \ {j, 0, 5}, \ {i, 0, j}]\ // \ TableForm\)], "Input"], Cell[TextData[{ "On occasion it is more convenient to think of words as elements in the \ free monoid over the corresponding alphabet and write them in the standard \ exponential notation, see ", ButtonBox["WordPower", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["AlgebraicForm", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(w\ = \ WordPower[aaaab, 3]\), "\[IndentingNewLine]", \(AlgebraicForm[w]\)}], "Input"], Cell[TextData[{ "A word is ", StyleBox["primitive", FontColor->RGBColor[0, 0, 1]], " if it cannot be written as a power of a shorter word. The ", StyleBox["root", FontColor->RGBColor[0, 0, 1]], " of a word ", Cell[BoxData[ \(TraditionalForm\`w\)]], " is the shortest word ", Cell[BoxData[ \(TraditionalForm\`u\)]], " such that ", Cell[BoxData[ \(TraditionalForm\`w = u\^\(\(\ \)\(i\)\)\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Select[Words[6, {a, b}], WordPrimitiveQ\ ]\), "\n", \(Length[%]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(w = WordPower[abc, 10]\), "\n", \(WordRoot[w]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(WordLength[WordRoot[RandomWord[20, 2]]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "To compute ", Cell[BoxData[ \(TraditionalForm\`p[n, k]\)]], ", the number of primitive words of length ", Cell[BoxData[ \(TraditionalForm\`n\)]], " over an alphabet of size ", Cell[BoxData[ \(TraditionalForm\`k\)]], ", one can use recursion: \n\t", Cell[BoxData[ FormBox[ RowBox[{\(p[n, k]\), " ", "=", " ", FormBox[\(k\^\(\(\ \)\(n\)\) - \ \ \[Sum]\_\(\(\ \)\(d\ | \ n, \ \ \ d < n\)\)\ p[d, k]\), "TraditionalForm"]}], TraditionalForm]]], "\nwhere the sum is over all proper divisors ", Cell[BoxData[ \(TraditionalForm\`d\)]], " of ", Cell[BoxData[ \(TraditionalForm\`n\)]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Clear[prim]\), "\n", \(\(Attributes[prim] = {Listable};\)\), "\[IndentingNewLine]", \(\(prim[1, k_] := k;\)\), "\n", \(prim[n_, k_] := \(prim[n, k] = k\^n - Total[prim[Most[Divisors[n]], k]]\)\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(prim[10, 2]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "A better approach is to realize that \n\t", Cell[BoxData[ FormBox[ RowBox[{" ", FormBox[\(k\^n = \ \ \[Sum]\_\(\(d\)\(\ \)\(|\)\(\ \)\(n\)\(\ \)\)\ p[d, k]\), "TraditionalForm"]}], TraditionalForm]]], "\nand then to use M\[ODoubleDot]bius inversion to compute the number of \ primitive words. This approach is taken in ", Cell[BoxData[ ButtonBox["WordPrimitiveCount", ButtonStyle->"AddOnsLink"]]], ". Note that there are lots of primitive words." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(WordPrimitiveCount[#, 2] &\) /@ Range[12]\)], "Input", AspectRatioFixed->True], Cell["A simple correctness test.", "Text"], Cell[BoxData[ \(Select[Words[10], WordPrimitiveQ\ ]\ // \ Length\)], "Input"], Cell["Note that there are lots of primitive words.", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(N[\(WordPrimitiveCount[#, 2] &\) /@ Range[20]/2^Range[20]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["WordConjugateQ", ButtonStyle->"AddOnsLink"], " tests whether two words are conjugate, and ", ButtonBox["WordConjugates", ButtonStyle->"AddOnsLink"], " generates all conjugates of a given word." }], "Text"], Cell[BoxData[ \(WordConjugateQ[aaabb, abbaa]\)], "Input"], Cell["All conjugates of a primitive word are also primitive.", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(WordConjugates[Select[Words[6], WordPrimitiveQ]]\ // \ Flatten\)\ // \ Union\), "\[IndentingNewLine]", \(\(%\ // \ WordPrimitiveQ\)\ // \ Union\)}], "Input"], Cell[TextData[{ "Command ", ButtonBox["WordShuffle", ButtonStyle->"AddOnsLink"], " produces all possible interleavings of given words:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordShuffle[aabb, ccaa]\)], "Input", AspectRatioFixed->True], Cell["\<\ In general it is quite difficult to count the number of words that \ arise from a shuffle operation. There is one special case, though, where the \ computation is simple:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordShuffle[aaaa, bbb]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(Length[%] === Binomial[7, 4]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["ToIndex", ButtonStyle->"AddOnsLink"], StyleBox["[w,K]", "MR"], " converts a word ", Cell[BoxData[ \(TraditionalForm\`w = \(w\_1\) \(w\_2\) \[Ellipsis]w\_l\)]], " into a corresponding list of numbers ", Cell[BoxData[ \(TraditionalForm\`{i\_1, i\_2, \[Ellipsis], i\_l}\)]], " where ", Cell[BoxData[ \(TraditionalForm\`i\_j\)]], " is the position of symbol ", Cell[BoxData[ \(TraditionalForm\`w\_j\)]], " in ", Cell[BoxData[ \(TraditionalForm\`K\)]], " (which we may safely assume to be ordered since we use lists to represent \ sets). If no second input field is specified, the default ", StyleBox["$alphabet", "MR"], " is substituted. ", ButtonBox["ToWord", ButtonStyle->"AddOnsLink"], " performs the inverse operation. The two commands can be combined to \ perform substitutions. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(ToIndex[#, {x, y}] &\) /@ WordPrefixes[RandomWord[8, {x, y}]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(\(ToWord[#, {a, b}] &\) /@ %\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Here is a simple one-dimensional Lindenmayer system based on ", StyleBox["ToIndex", "MR"], " and ", StyleBox["ToWords", "MR"], ". Note that strings and ", StyleBox["Mathematica", FontSlant->"Italic"], " symbols can be mixed in an alphabet." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Lindenmayer[x_] := ToWord[ToIndex[x, \(-2\)], {"\<1\>", "\<10\>"}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(LS = NestList[Lindenmayer, "\<0\>", 9];\)\), "\n", \(ColumnForm[LS]\)}], "Input", AspectRatioFixed->True], Cell["The lengths of these strings are the Fibonacci numbers:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordLength[LS]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The same effect can be obtained using the command ", ButtonBox["MakeHomomorphism", ButtonStyle->"AddOnsLink"], " (which uses the built-in ", ButtonBox["StringReplace", ButtonStyle->"RefGuideLink"], " internally and is therefore faster). " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(MakeHomomorphism[lind, {0, 1}, {1, 10}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(NestList[lind, "\<0\>", 9]\ // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell["Another famous example: the Morse-Thue word.", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(MakeHomomorphism[mt, {0, 1}, {"\<01\>", "\<10\>"}]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The Morse-Thue word is cube-free: it contains no (non-empty) factor of the \ form ", Cell[BoxData[ FormBox[ StyleBox["xxx", FontSlant->"Italic"], TraditionalForm]]], ". In fact, the word is even overlap-free, so one cannot have a factor of \ the form ", Cell[BoxData[ \(TraditionalForm\`x\ x\ x\_1\)]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(NestList[mt, "\<0\>", 6]\ // \ ColumnForm\)], "Input"], Cell["\<\ There are many equivalent ways to define the digits of the infinite \ word that arises as the limit of these finite words. Here is one based on \ binary digitsums.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(With[\ {k\ = \ 8}, \[IndentingNewLine]ToWord[\ Mod[\ DigitCount[Range[2^k] - 1, 2, 1], \ 2\ ] + 1, \(-2\)\ ]\ \[Equal] \ Nest[mt, "\<0\>", k\ ]\ ]\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell[" Order relations on words", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:7"], Cell[TextData[{ "There are various ways to introduce an order relation on words. The most \ standard one is lexicographic order and is used in the built-in command ", ButtonBox["Sort", ButtonStyle->"RefGuideLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(L\ = \ Table[\ RandomWord[Random[Integer, {1, 10}], 2], \ {10}]\), "\[IndentingNewLine]", \(L\ // \ Sort\)}], "Input"], Cell[TextData[{ "The standard lexicographic ordering of words over ", Cell[BoxData[ \(TraditionalForm\`{a, b}\)]], " can be expressed by a rational rank function using ", ButtonBox["ToIndex", ButtonStyle->"AddOnsLink"], " as follows. Let" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(ClearAll[rank]\), "\[IndentingNewLine]", \(\(Attributes[rank] = {Listable};\)\), "\[IndentingNewLine]", \(\(rank[\[Epsilon] | Eps | "\"] = 0;\)\), "\[IndentingNewLine]", \(\(rank[w_?WordQ]\ := \ ToIndex[w, 2]\ . \((1/3)\)^ Range[0, WordLength[w] - 1];\)\)}], "Input"], Cell[BoxData[{ \(L\ // \ rank\ \), "\[IndentingNewLine]", \(\(\(L\ // \ Sort\)\ // \ rank\) // \ OrderedQ\)}], "Input"], Cell[BoxData[ \(Table[\ rank[MakeWord[a, i]], {i, 10}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \({W = Words[2, {a, b}], rank /@ W}\ // \ TableForm\), "\[IndentingNewLine]", \({W = Words[3, {a, b}], rank /@ W}\ // \ TableForm\)}], "Input", AspectRatioFixed->True], Cell["\<\ Lexicographic order will occasionally produce undesired results \ when applied to languages. For example, \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(L = WordSuffixes[aababbababa];\)\), "\n", \(Sort[L]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Command ", ButtonBox["WordSort", ButtonStyle->"AddOnsLink"], " uses length-lex order rather than lexicographic order." }], "Text"], Cell[BoxData[ \(WordSort[L]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(WordSort[\((RandomWord[\(-6\), {a, b}] &)\) /@ Range[10]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Length-lex order is the product order of length and lexicographic order: \n\ \t\t", Cell[BoxData[ \(TraditionalForm\`u\ < \ v\)]], " iff \t", Cell[BoxData[ \(TraditionalForm\`\(\(\(|\)\(u\)\(|\)\(<\)\)\(\ \)\(|\)\(v\)\(|\)\(\ \ \)\)\)]], " or \n\t\t\t\t", Cell[BoxData[ \(TraditionalForm\`\(\(\(\(\(\(\(|\)\(u\)\(|\)\)\(\ \)\(=\)\)\(\ \ \)\(|\)\) v\)\(|\)\)\(\ \)\)\)]], " and ", Cell[BoxData[ \(TraditionalForm\`u\)]], " precedes ", Cell[BoxData[ \(TraditionalForm\`v\)]], " lexicographically.\t\t\t\n", ButtonBox["WordSort", ButtonStyle->"AddOnsLink"], " is used automatically in commands like ", ButtonBox["WordPrefixes", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["WordSuffixes", ButtonStyle->"AddOnsLink"], ". This is essential in some applications (see the section on the KMP \ string searching algorithm). ", StyleBox["WordSort", "MR"], " uses the built in sorting procedure ", ButtonBox["Sort", ButtonStyle->"RefGuideLink"], " and has comparable speed. \nThere is another sorting command ", ButtonBox["LanguageSort", ButtonStyle->"AddOnsLink"], " that applies to lists of languages. It is useful primarily to display \ syntactic congruence classes, see below. \nHere is another, natural ranking \ function for the ", StyleBox["WordSort", "MR"], " order." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(ClearAll[rank];\)\), "\n", \(\(rank[\[Epsilon] | Eps | "\", _] = 0;\)\), "\n", \(\(rank[w_, alph_] := \[IndentingNewLine]Block[{k, l}, \[IndentingNewLine]\t k = Length[alph]; l = WordLength[ w]; \(k\^l - 1\)\/\(k - 1\) + \((ToIndex[w, alph] - 1)\) . Reverse[k\^Range[0, l - 1]]\[IndentingNewLine]];\)\)}], "Input",\ AspectRatioFixed->True], Cell[TextData[{ "Define ", StyleBox["W3", "MR"], " to be all words over ", Cell[BoxData[ \(TraditionalForm\`{a, b}\)]], " of length at most 3. Their ranks over alphabets ", Cell[BoxData[ \(TraditionalForm\`{a, b}\)]], " and ", Cell[BoxData[ \(TraditionalForm\`{a, b, c}\)]], " are" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(W3 = Words[\(-3\), {a, b}]\), "\n", \(r0 = \((rank[#1, {a, b}] &)\) /@ W3\), "\n", \(r1 = \((rank[#1, {a, b, c}] &)\) /@ W3\)}], "Input", AspectRatioFixed->True], Cell["\<\ There are also predicates that test whether one word is a \ prefix/suffix/factor of another. \ \>", "Text"], Cell[BoxData[{ \(Select[\ Words[5], \ WordPrefixQ[aab, #] &]\), "\[IndentingNewLine]", \(Select[\ Words[5], \ WordSuffixQ[aab, #] &]\), "\[IndentingNewLine]", \(Select[\ Words[5], \ WordFactorQ[aab, #] &]\)}], "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Structure of a Finite State Machine", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:8"], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Types\ of\ Finite\ State\ Machines\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:9"], Cell[TextData[{ "The most basic type of finite state machine is a semiautomaton, or SA for \ short. A semiautomaton consists of a \n\t- a finite set of states ", StyleBox["Q", FontSlant->"Italic"], ",\n\t- an alphabet ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma]\)]], ",\n\t- a transition relation ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\ \[SubsetEqual] \ Q\ \[Cross]\ \((\[CapitalSigma] \[Union] {\[Epsilon]})\)\ \[Cross]\ Q\)]], ". \nA triple ", StyleBox["(p,s,q)", FontSlant->"Italic"], " in ", StyleBox["\[Tau]", FontFamily->"Symbol"], " is a transition of the automaton, and ", StyleBox["s", FontSlant->"Italic"], " is its label. As we will see, it is convenient to allow the empty word as \ a label. If we think of an SA as simple system that responds to an external \ stimulus (some symbol ", StyleBox["s", FontSlant->"Italic"], " from the alphabet ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma]\)]], ") by performing a transition from state ", StyleBox["p", FontSlant->"Italic"], " into a new state ", StyleBox["q", FontSlant->"Italic"], " according to the transition relation, then transition labeled correspond \ to autonomous transitions: the system changes its state without an external \ stimulus. If no transitions of the form ", Cell[BoxData[ \(TraditionalForm\`\((p, \[Epsilon], q)\)\)]], " occur the machine is ", StyleBox["\[Epsilon]", FontFamily->"Symbol"], "-free. \nA semiautomaton can perform simple computations as follows: it \ receives a sequence of symbols as input, and for every input symbol it \ performs a state transition according to the transition relation. Hence, a \ computation is a sequence \n\t", Cell[BoxData[ \(TraditionalForm\`\(p\_0\) \(s\_1\) \(p\_1\) \(s\_2\) p\_3. \ \[Ellipsis]\ \(p\_\(n - 1\)\) \(s\_n\) p\_n\)]], StyleBox[" ", FontSlant->"Italic"], "\nwhere the ", Cell[BoxData[ \(TraditionalForm\`p\_i\)]], " are states and is ", Cell[BoxData[ \(TraditionalForm\`\(\(s\_i\)\(\ \)\)\)]], "in ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma] \[Union] {\[Epsilon]}\)]], ". The label of the computation is ", Cell[BoxData[ \(TraditionalForm\`s = \(s\_1. .. \) s\_n \[Element] \ \(\[CapitalSigma]\^*\)\)]], " and ", Cell[BoxData[ \(TraditionalForm\`p\_0, p\_1, \(\(...\)\(,\)\(p\_n\)\)\)]], " its trace. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "In order to use SAs as acceptors, we have to limit admissible computations \ by insisting that the source state ", Cell[BoxData[ \(TraditionalForm\`p\_0\)]], " is from a special set of states ", Cell[BoxData[ \(TraditionalForm\`I\)]], ", the set of initial states, and similarly the target state ", Cell[BoxData[ \(TraditionalForm\`p\_n\)]], " is from a designated set of states ", Cell[BoxData[ \(TraditionalForm\`F\)]], ", the set of final states. A finite automaton, or FA, correspondingly \ consists of a semiautomaton together with a set of initial and final states. \ A finite automaton ", Cell[BoxData[ \(TraditionalForm\`M\)]], " accepts a word ", StyleBox["x", FontSlant->"Italic"], " if there is a computation in M from an initial to a final state whose \ label is ", StyleBox["x", FontSlant->"Italic"], ". The set of all words accepted by ", Cell[BoxData[ \(TraditionalForm\`M\)]], " is the acceptance language of ", Cell[BoxData[ \(TraditionalForm\`M\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "There are some special types of machines that are of particular interest. \ Suppose M is some semiautomaton. We can think of its transition relation ", StyleBox["\[Tau] ", FontFamily->"Symbol"], "as defining, for each symbol ", StyleBox["a", FontSlant->"Italic"], " in ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma] \[Union] {\[Epsilon]}\)]], ", a binary relation ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_a\)]], " on ", StyleBox["Q", FontSlant->"Italic"], ". We have already introduced the notion of epsilon-freeness: ", Cell[BoxData[ \(TraditionalForm\`M\)]], " is epsilon-free iff ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_\[Epsilon]\)]], " is empty. \n", Cell[BoxData[ \(TraditionalForm\`M\)]], " is ", StyleBox["deterministic", FontColor->RGBColor[0, 0, 1]], " if it is epsilon-free and ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_a\)]], " is a partial function for each symbol ", StyleBox["a", FontSlant->"Italic"], ". \n", Cell[BoxData[ \(TraditionalForm\`M\)]], " is ", StyleBox["complete", FontColor->RGBColor[0, 0, 1]], " if it is epsilon-free and the domain of ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_a\)]], " is all of ", StyleBox["Q", FontSlant->"Italic"], " for each symbol ", StyleBox["a", FontSlant->"Italic"], ".\nA deterministic finite automaton (DFA) is deterministic and complete \ (i.e., the relations ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_a\)]], " are functions from Q to Q), and there is exactly one initial state. \ Hence ", StyleBox["\[Tau]", FontFamily->"Symbol"], " can be written conveniently as an ", Cell[BoxData[ \(TraditionalForm\`K\ \[Cross]\ Q\)]], " matrix over ", StyleBox["Q", FontSlant->"Italic"], ". In a nondeterministic finite automaton (NFA) the relations ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_a\)]], " can be construed as partial multi valued functions, which can be \ represented by a ", Cell[BoxData[ \(TraditionalForm\`K\ \[Cross]\ Q\)]], " matrix over ", Cell[BoxData[ \(TraditionalForm\`\[ScriptCapitalP](Q)\)]], ". \t\nIn this package, a FSM is represented by a ", StyleBox["Mathematica", FontSlant->"Italic"], " expression of the form\n\t", StyleBox["SA[ Q, K, T ]", FontWeight->"Bold"], "\n\t", StyleBox["FA[ Q, K, T, I, F ]", FontWeight->"Bold"], "\n\t", StyleBox["NFA[ Q, K, T, I, F ]", FontWeight->"Bold"], "\n\t", StyleBox["DFA[ Q, K, T, q0, F ]\n", FontWeight->"Bold"], "See the constructors ", ButtonBox["SA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["FA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["DFA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["NFA", ButtonStyle->"AddOnsLink"], ". The first type of expression stands for a semiautomaton, the second for \ an arbitrary finite automaton, the third for an epsilon-free automaton, and \ the fourth for a ", StyleBox["DFA", "MR"], ", a deterministic complete machine with exactly one initial state. The \ constructors ", ButtonBox["SA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["FA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["DFA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["NFA", ButtonStyle->"AddOnsLink"], " are all protected. As indicated above, for the last two types of \ machines, the transition relation ", StyleBox["T", "MR"], " is represented by a matrix. For ", StyleBox["SA", "MR"], "s and ", StyleBox["FA", "MR"], "s, however, the transitions are given as a list of triples. Here are some \ typical examples. The commands used in these examples will be explained in \ more detail later. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(AllDFA[{a, b}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(m = IthSymbolFA[a, \(-3\), {a, b}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(ToNFA[m]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(MatrixForm[Transitions[%]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(ToSA[m]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The various fields of a machine can be extracted by the following \ commands. Note that ", ButtonBox["States", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["Alphabet", ButtonStyle->"AddOnsLink"], " also return the cardinality of the respective sets. The size (number of \ states) of a machine is returned by ", ButtonBox["Size", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Through[\ {Size, States, Alphabet, Transitions, Initial, Final}[ m]]\ // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`The\ Truth\)], "Subsubsection", CellTags->"c:10"], Cell["\<\ Actually, the structure of a FSM in this package is slightly more \ complicated than the explanation above suggest. In reality, there are two \ more fields in a FSM that are simply not shown in the ordinary print form of \ a machine. Turning formatting off makes these fields visible.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(FormatAutomata[None]\), "\[IndentingNewLine]", \(m\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The entry in the second position from the end is the alphabet of the \ machine in explicit form: a list of characters. See also the discussion \ about short-cuts below. The last field shows the structured state set of the \ machine. The empty list here simply indicates that the states are ", Cell[BoxData[ FormBox[Cell[TextData[Cell[BoxData[ \(TraditionalForm\`{1, 2, \[Ellipsis], n}\)]]]], TraditionalForm]]], " where ", Cell[BoxData[ \(TraditionalForm\`n\)]], " is the number of states. In more complicated machines, this could be an \ arbitrary list of length ", Cell[BoxData[ \(TraditionalForm\`n\)]], ". \nHowever, to facilitate typing or other constructions of machines by \ hand, the package will automatically supply the missing fields. For example:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(SA[2, 2, {{1, 1, 2}, {2, 1, 1}, {2, 2, 2}}]\)], "Input"], Cell[TextData[{ "In general, it is best to set formatting to ", StyleBox["Automatic", "MR"], ", see ", ButtonBox["FormatAutomata", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(FormatAutomata[Automatic]\), "\[IndentingNewLine]", \(m\)}], "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["States and Structured States, Normalization ", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:11"], Cell[TextData[{ "For many purposes it is convenient to use ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\ = \ {1, 2, \(\(...\)\(,\)\(n\)\)}\)]], " as set of states. Machines of this form will be referred to as ", StyleBox["normalized", FontColor->RGBColor[0, 0, 1]], ". On occasion, however, it is preferable to use a state set ", Cell[BoxData[ \(TraditionalForm\`Q\)]], " of a different form. For example, if one computes the product machine of \ two given machines, the state set naturally is a set of pairs ", Cell[BoxData[ \(TraditionalForm\`\((p, q)\)\)]], " where ", Cell[BoxData[ \(TraditionalForm\`p\)]], " is a state of the first and ", Cell[BoxData[ \(TraditionalForm\`q\)]], " a state of the second machine. To allow the user to preserve such special \ state sets, many of the commands in this package have an option ", ButtonBox["Normalize", ButtonStyle->"AddOnsLink"], " associated with them. The default value for ", StyleBox["Normalize", "MR"], " is 0; therefore the states of the output machines are automatically \ normalized to ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\)]], ". If non-normalized output is desired use the option ", Cell[BoxData[ \(Normalize -> 1\)], "MR"], ". Note that normalization affects only the state set of an automaton. \ Transitions, initial and final states always use positional notation to \ represent states. Also note that non-normalized machines can be \ significantly bigger than their normalized counterparts. \nHere is a typical \ example. First, we construct two DFAs and their corresponding semiautomata:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m1 = BuildDFA[aaa, {a, b}];\)\), "\n", \(\(m2 = BuildDFA[bb, {a, b}];\)\), "\n", \(s1 = ToSA[m1]\), "\n", \(s2 = ToSA[m2]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The product of ", StyleBox["s1", "MR"], " and ", StyleBox["s2", "MR"], " has 20 states:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(ProductFA[s1, s2]\), "\[IndentingNewLine]", \(States[%]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "To preserve the structure of the states we can use the option ", StyleBox["Normalize->1", "MR"], ". In our case, we obtain the Cartesian product of [5] and [4]." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(ProductFA[s1, s2, Normalize \[Rule] 1]\), "\n", \(States[%]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Things become a little more interesting if we compute the product \ of the two DFAs. The algorithm constructs only the accessible part, hence a \ few pairs are missing from the full Cartesian product.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = UnionFA[m1, m2, Normalize \[Rule] 1]\), "\n", \(States[%]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Thus, option ", StyleBox["Normalize->1", "MR"], " preserves the structured state set during the constructions, whereas ", StyleBox["Normalize->0", "MR"], ", the default, renormalizes to ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\)]], ". The structure of the resulting state set depends on the operation under \ consideration: \n\t", StyleBox["AccessibleFA", "MR"], "\t\tsubset of ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\)]], "\n\t", StyleBox["ToDFA", "MR"], "\t\t\t\tsubset of ", Cell[BoxData[ \(TraditionalForm\`\[ScriptCapitalP](\([n]\))\)]], "\n\t", StyleBox["MinimizeFA", "MR"], "\t\t\tpartition of ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\)]], "\n\t", StyleBox["ProductFA", "MR"], "\t\t\tsubset of ", Cell[BoxData[ \(TraditionalForm\`\([n\_1]\)\[Cross]\([n\_2]\)\)]] }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ Note that in the last table the state set of the input machine(s) \ was assumed to be normalized. If it is not, the result will be the same as \ if normalization were performed before the actual operation. We can push things a little further and preserve the state set of the input \ machine. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(fa = WordToFA[aabb, 2, Normalize \[Rule] 1, Full \[Rule] True];\)\), "\n", \(States[fa]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(States[ToDFA[fa, Normalize \[Rule] 1]]\), "\n", \(States[ToDFA[fa, Normalize \[Rule] 2]]\)}], "Input", AspectRatioFixed->True], Cell["\<\ If we minimize the last FA, we get a state set consisting of sets \ of sets of words:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(States[MinimizeFA[fa, Normalize \[Rule] 2]]\ // \ \(Curry[TableForm]\)[ TableDepth \[Rule] 2]\)], "Input", AspectRatioFixed->True], Cell["\<\ How much information about the state is necessary depends very much \ on what one is trying to accomplish. With a little experience it will be \ quite obvious which level of normalization is appropriate. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Alphabets\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:12"], Cell[TextData[{ "The standard way to specify an alphabet is to provide a List of atomic \ symbols or strings of length 1. However, it is absolutely necessary to ", StyleBox["Clear", "MR"], " any symbols that might already be in use. Otherwise, strange things are \ bound to happen. It is a good idea to define a few frequently used alphabets \ such as ", Cell[BoxData[ \(TraditionalForm\`{a, b}, \ {a, b, c}\)]], " or ", Cell[BoxData[ \(TraditionalForm\`{0, 1}\)]], " beforehand, see also the section on shortcuts below. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Clear[a, b, x, y, z]\), "\n", \(al2 = {a, b}\), "\n", \(alx = {x, y, z}\), "\n", \(Words[3, al2]\), "\n", \(Words[3, alx]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Alphabets can also be produced with the command ", StyleBox["MakeAlphabet", "MR"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(MakeAlphabet[\(-10\)]\), "\n", \(MakeAlphabet[4]\), "\n", \(MakeAlphabet[4, Full \[Rule] True]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Since alphabets whose symbols are digits like ", Cell[BoxData[ \(TraditionalForm\`{0, 1}\)]], " or ", Cell[BoxData[ \(TraditionalForm\`{0, 1, 2}\)]], " are used frequently, there is a shortcut for them: integer ", Cell[BoxData[ \(TraditionalForm\`\(-k\)\)]], " represents alphabet ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma]\_k = {0, 1, \[Ellipsis], k - 1}\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Words[2, \(-5\)]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Note that leading zeros are suppressed by ", StyleBox["Mathematica", FontSlant->"Italic"], ", so it will often be necessary to quote strings over these alphabets. \ Command ", ButtonBox["Alphabet", ButtonStyle->"AddOnsLink"], " produces the underlying alphabet of a finite state machine :" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Alphabet[m]\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Transition\ Relation\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:13"], Cell[TextData[{ "The transition relation \[Tau] depends on the type of automaton under \ consideration. In ", StyleBox["Automata", "MR"], " we have adopted the following conventions.\n\t\[EmptyCircle] In an SA, \ ", StyleBox["\[Tau]", FontFamily->"Symbol"], " is list of triples ", Cell[BoxData[ \(TraditionalForm\`{p, s, q}\)]], " where ", Cell[BoxData[ \(TraditionalForm\`p\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\(\(s\)\(\ \ \)\)\)]], "and ", Cell[BoxData[ \(TraditionalForm\`q\)]], " are integers, ", Cell[BoxData[ \(TraditionalForm\`1\ \[LessEqual] \ p, q\ \[LessEqual] \ n\)]], " and ", Cell[BoxData[ \(TraditionalForm\`1\ \[LessEqual] \ s\ \[LessEqual] \ k\ = \ \(\(|\)\(\(\[CapitalSigma]\)\(|\)\)\)\)]], ". Epsilon transitions are indicated by ", Cell[BoxData[ \(TraditionalForm\`s = 0\)]], ". Intuitively, the triple ", Cell[BoxData[ \(TraditionalForm\`{p, s, q}\)]], " indicates that the automaton can move from state ", Cell[BoxData[ \(TraditionalForm\`p\)]], " to state ", Cell[BoxData[ \(TraditionalForm\`q\)]], " under input ", Cell[BoxData[ \(TraditionalForm\`s\)]], ". The same convention applies to FAs. \n\t\[EmptyCircle] In a NFA, the \ transition relation ", StyleBox["\[Tau]", FontFamily->"Symbol"], " is implemented as a ", Cell[BoxData[ \(TraditionalForm\`\(\(k\ \[Cross]\ n\)\(\ \)\)\)]], "matrix of lists representing subsets of ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\)]], " (where ", Cell[BoxData[ \(TraditionalForm\`n\)]], " is the number of states and ", Cell[BoxData[ \(TraditionalForm\`k\)]], " the size of the underlying alphabet). The list ", Cell[BoxData[ \(TraditionalForm\`{q\_1, \[Ellipsis], q\_i}\)]], " in position ", Cell[BoxData[ \(TraditionalForm\`\((s, p)\)\)]], " indicates that the automaton can move from state ", Cell[BoxData[ \(TraditionalForm\`p\)]], " under input ", Cell[BoxData[ \(TraditionalForm\`s\)]], " to one of the states ", Cell[BoxData[ \(TraditionalForm\`q\_1, \[Ellipsis], q\_i\)]], ". \n\t\[EmptyCircle] Lastly, in a DFA, the transitions are best viewed as \ a map ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\ : \ \[CapitalSigma]\ \[Cross]Q\ \ \[RightArrow] \ Q\)]], ". ", StyleBox["\n", FontFamily->"Symbol"], "Thus we represent ", StyleBox["\[Tau]", FontFamily->"Symbol"], " by an ", Cell[BoxData[ \(TraditionalForm\`k\ \[Cross]\ n\)]], " matrix with entries from ", Cell[BoxData[ \(TraditionalForm\`\([n]\)\)]], ". Entry ", Cell[BoxData[ \(TraditionalForm\`q\)]], " in position ", Cell[BoxData[ \(TraditionalForm\`\((s, p)\)\)]], " indicates that the automaton moves from state ", Cell[BoxData[ \(TraditionalForm\`p\)]], " to state ", Cell[BoxData[ \(TraditionalForm\`q\)]], " under input ", Cell[BoxData[ \(TraditionalForm\`s\)]], ". \nCommand ", ButtonBox["Transitions", ButtonStyle->"AddOnsLink"], " extracts the transition relation of a finite state machine. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Transitions[m]\), "\n", \(Transitions[ToNFA[m]]\), "\n", \(Transitions[ToFA[m]]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Again, note that the entries in the expressions representing transitions \ are all non-negative integers. Thus, integer ", Cell[BoxData[ \(TraditionalForm\`p\)]], " stands for the state ", Cell[BoxData[ \(TraditionalForm\`Q[\([p]\)]\)]], " (which may be an integer but could also be more complicated Mathematica \ object such as, say, a list of pairs of integers or a list of words). \nWhen \ one constructs FSMs by hand it is on occasion more convenient to initially \ define transitions in terms of the real states of the machine. The command ", ButtonBox["ConvertToFA", ButtonStyle->"AddOnsLink"], " effects translation into standard form. It can be used when: \n(1) \ Transitions are given with reference to states.\n(2) For a DFA or NFA \ transitions are given as a list, rather than in matrix form.\n(3) Initial \ and final states are given with reference to states.\nHere is a typical \ application: a machine that accepts any string of a's of length at least 2. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(ConvertToFA[\ FA, {Eps, a, aa}, {a, b}, {{Eps, a, a}, {a, a, aa}, {aa, a, aa}}, {Eps}, {aa}]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "If it is necessary to display the symbols in a list of transitions \ directly rather than their positions in the alphabet one can use the command \ ", ButtonBox["FullTransitions", ButtonStyle->"AddOnsLink"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(FullTransitions[ToFA[m]]\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Conversions\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:14"], Cell[TextData[{ "Conversions between the different types of machines can be effected by the \ commands ", ButtonBox["ToSA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["ToDFA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["ToNFA", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["ToFA", ButtonStyle->"AddOnsLink"], ". All four commands are polymorphic: they accept as input all four types \ of machines. ", StyleBox["ToDFA", "MR"], " uses the classical Rabin-Scott power set construction (deterministic \ simulation) and has therefore potentially exponential time and space \ requirements. By default, only the accessible part of the deterministic \ machine is constructed. If the full power set machine is required use the \ option ", StyleBox["Full->True", "MR"], ". Furthermore, the deterministic machine is automatically normalized. \ Normalization can be avoided with option ", StyleBox["Normalize->1", "MR"], ". The last option is also available for ", StyleBox["ToNFA", "MR"], " and ", StyleBox["ToFA", "MR"], ".\nOf course, stripping off the initial and final states to obtain the \ underlying semiautomaton destroys the acceptance language of the machine. All \ the other commands preserve the language of the automaton. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = IthSymbolFA[a, \(-3\), {a, b}]\), "\n", \(ToNFA[m]\), "\n", \(ToSA[m]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Special\ Automata\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:15"], Cell["\<\ Other than SAs, FAs, NFAs and DFAs, the package also uses several \ normal forms for FSMs. Currently there are McNaughton-Yamada style machines, \ begin/exit automata and frontier automata; see below for a discussion. No attempt has been made to extend all operations to all types of machines. \ The special machines can be converted to FAs and are used mostly for \ efficiency reasons, for example in the algorithm that translates regular \ expressions to finite automata. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Shortcuts", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:17"], Cell[TextData[{ "There are numerous commands in this package that require the user to type \ in an alphabet. To make this process a little less time consuming there is a \ global variable ", ButtonBox["$alphabet", ButtonStyle->"AddOnsLink"], " that provides a default for the alphabet in many commands. In the \ standard setup, ", StyleBox["$alphabet", "MR"], " is initialized to ", StyleBox["2", "MR"], " corresponding to the two-letter alphabet ", StyleBox["{a,b}", "MR"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \($alphabet\), "\n", \(Words[3]\), "\n", \(AllDFA[]\), "\n", \(LanguageFA[%, 3]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "In case of doubt, it is always a good idea to write the alphabet the \ standard way. For digit alphabets of the form ", Cell[BoxData[ \(TraditionalForm\`{0, 1, \(\(...\)\(,\)\(k\)\) - 1}\)]], " one can simply specify ", Cell[BoxData[ \(TraditionalForm\`\(-k\)\)]], " rather than typing in the corresponding list of integers. For letter \ alphabets like ", Cell[BoxData[ \(TraditionalForm\`{a, b, c}\)]], " positive integers serve as abbreviations (e.g., ", Cell[BoxData[ \(TraditionalForm\`{a, b, c}\)]], " is represented by 3)." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Words[3, 3]\), "\n", \(AllDFA[\(-3\)]\), "\n", \(LanguageFA[%, 3]\)}], "Input", AspectRatioFixed->True], Cell["\<\ To make life easy for the casual reader, we will not use any \ abbreviations in the browser notebooks. Well, mostly.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Generating Machines", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:16"], Cell[CellGroupData[{ Cell["Basics", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:9"], Cell[TextData[{ "The automata package contains several functions that generate FSMs from \ various parameters. Their usage should be fairly obvious from the examples \ given below and their description in the help browser. To display a FSM, we \ provide a function ", ButtonBox["PrintFA", ButtonStyle->"AddOnsLink"], " (which works reasonably well for machines of up to about 20 states). For \ non-normalized FAs (as well as for large normalized machines) one can use \ option ", StyleBox["Full->True", "MR"], " to obtain a list of transitions in table form. Option ", StyleBox["TransOnly->True", "MR"], " will display only the transitions of the automaton (as a matrix for DFAs \ and NFAs, and as a table for FAs). " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[CellGroupData[{ Cell["Finite Languages", "Subsubsection"], Cell[TextData[{ "The procedure ", ButtonBox["BuildDFA", ButtonStyle->"AddOnsLink"], " constructs a DFA that accepts a given word or list of words. The input \ may be given as a sequence or a list of words. The underlying alphabet is \ specified as the last input field. ", StyleBox["BuildDFA", "MR"], " automatically constructs the minimal automaton for the specified finite \ language." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m1 = BuildDFA[aaa, {a, b}, Normalize \[Rule] 1]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(PrintFA[m1]\), "\[IndentingNewLine]", \(States[m1]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(MinimizeFA[m1]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[m1, \(-5\)]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ StyleBox["BuildDFA", "MR"], " also accommodates finite sets of words. For example: " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(L = {Eps, aa, bb, aba}\), "\n", \(BuildDFA[L, {a, b, c}]\), "\n", \(LL = Flatten[LanguageFA[%, \(-4\)]]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The command ", StyleBox["BuildDFA", "MR"], " also accepts sequences of words as input. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(BuildDFA[Eps, aa, bb, {a, b, c, d}]\), "\[IndentingNewLine]", \(LanguageFA[%, \(-3\)]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["All Words and Stars", "Subsubsection"], Cell[TextData[{ "To obtain an automaton for all words of the form ", Cell[BoxData[ \(TraditionalForm\`\(w\[VeryThinSpace]w ... \) w\)]], " one can use the command ", ButtonBox["BuildStarDFA", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(BuildStarDFA[aaab, {a, b}]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "There are special constructors for DFAs accepting the empty set, ", Cell[BoxData[ \(TraditionalForm\`\(\[CapitalSigma]\^*\)\)]], " and \[CapitalSigma]", StyleBox["+", FontVariations->{"CompatibilityType"->"Superscript"}], " (the machines are chosen so that they remain invariant under application \ of ", ButtonBox["MinimizeFA", ButtonStyle->"AddOnsLink"], "):" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(EmptyDFA[{a, b, c}]\), "\n", \(AllDFA[{a, b, c}]\), "\n", \(AllDFA[{a, b, c}, Full \[Rule] False]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Counters", "Subsubsection"], Cell[TextData[{ "Command ", ButtonBox["LengthDFA", ButtonStyle->"AddOnsLink"], " generates a machine that accepts all words of a given length. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LengthDFA[\ 3, {a, b, c}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[%, \(-5\)]\)], "Input", AspectRatioFixed->True], Cell["A number of variants of the command work as expected.", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[\ LengthDFA[\ {2, 3}, {a, b}], \(-5\)]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[\ LengthDFA[\ \(-3\), {a, b}], \(-5\)]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[\ LengthDFA[\ 1, {a, b}, Modulus \[Rule] 3], \(-5\)]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "A DFA that accepts all words over some alphabet that contain a fixed \ number of occurrences of a certain symbol is generated by the command ", ButtonBox["CounterDFA", ButtonStyle->"AddOnsLink"], ". For example, all strings over ", Cell[BoxData[ \(TraditionalForm\`{0, 1}\)]], " with exactly three 1's are produced by:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(DIG = {"\<0\>", "\<1\>"};\)\), "\n", \(CounterDFA["\<1\>", 3, DIG]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Alternatively, we can use the shortcut to specify the alphabet ", StyleBox["DIG", "MR"], " by the integer ", StyleBox["-2", "MR"], ":" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(CounterDFA["\<1\>", 3, \(-2\)]\), "\n", \(Alphabet[%]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Command ", ButtonBox["CounterDFA", ButtonStyle->"AddOnsLink"], " can also be used to generate machines that count the occurrences of a \ symbol modulo some parameter. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(CounterDFA[b, 1, {a, b, c}, Modulus \[Rule] 3]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[%, \(-4\)]\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Factors", "Subsubsection"], Cell[TextData[{ "The command ", ButtonBox["WordToFA", ButtonStyle->"AddOnsLink"], " produces machines that accept words with a given prefix, infix and \ suffix, respectively. They all have the option ", StyleBox["Normalize->0", "MR"], " which sets the state set to the prefixes of the given word. (To avoid \ the standard confusion, we use the terminology infix or factor versus \ subword.)" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(WordToFA[abbb, {a, b}, \ Full \[Rule] True]\), "\n", \(WordToFA[abbb, {a, b}, Type -> "\", \ Full \[Rule] True]\), "\n", \(m = WordToFA[abbb, {a, b}, Type -> "\", \ Full \[Rule] True, Normalize \[Rule] 1]\), "\n", \(States[%]\)}], "Input", AspectRatioFixed->True], Cell["\<\ The structured state set becomes visible in other operations:\ \>", \ "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(AcceptQFA[m, abbabbb, DoTrace \[Rule] True]\ // \ TableForm\)], "Input",\ AspectRatioFixed->True], Cell[TextData[{ "A DFA that tests its input for the occurrence of some given word w as a \ subword is generated by the command ", ButtonBox["SubwordDFA", ButtonStyle->"AddOnsLink"], ". Similarly, a DFA that counts the number of occurrences of some given \ word w as a subword of its input modulo p is produced by ", ButtonBox["SubwordCounterDFA", ButtonStyle->"AddOnsLink"], StyleBox["[w,{i,p},K]", "MR"], ". Option ", StyleBox["Normalize->1", "MR"], " produces a state set of the form ", Cell[BoxData[ \(TraditionalForm\`Q \[SubsetEqual] {0, 1, \[Ellipsis], p - 1}\^\(\(|\)\ \(w\)\(|\)\)\)]], ", which is natural if one considers the algorithm used in the construction \ of the automaton." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(SubwordDFA[abb, {a, b}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(Maab = SubwordCounterDFA[aab, 1, {a, b}, Modulus \[Rule] 5, Normalize \[Rule] 1];\)\), "\n", \(Size[Maab]\), "\n", \(States[Maab]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Here are all words of length at most 6 with exactly 1 mod 5 subwords ", Cell[BoxData[ FormBox[Cell[TextData[StyleBox["aab", FontSlant->"Italic"]]], TraditionalForm]]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[Maab, \(-6\)]\ // \ EnumForm0\)], "Input", AspectRatioFixed->True], Cell["A sanity check:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(WordBinomial[\ LanguageFA[Maab, 6], aab]\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Fixing Letters", "Subsubsection"], Cell[TextData[{ "Lastly, the command ", ButtonBox["IthSymbolFA", ButtonStyle->"AddOnsLink"], " constructs deterministic and nondeterministic machines for languages of \ all strings whose ", Cell[BoxData[ \(TraditionalForm\`i\)]], "th symbol is fixed. Here ", Cell[BoxData[ \(TraditionalForm\`i\)]], " is an integer different from 0." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(IthSymbolFA[b, 3, {a, b, c}]\), "\n", \(IthSymbolFA[b, \(-3\), {a, b, c}]\), "\n", \(IthSymbolFA[b, 3, {a, b, c}, Full \[Rule] True]\), "\n", \(IthSymbolFA[b, \(-3\), {a, b, c}, Full \[Rule] True, Normalize \[Rule] 1]\), "\[IndentingNewLine]", \(%\ // \ States\)}], "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Accessible, Coaccessible and Trim Machines", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:9"], Cell[TextData[{ "A finite state machine may well contain states that are superfluous in the \ sense that their deletion does not affect the acceptance language. A state is \ accessible iff there it lies on a path starting at an initial state, and \ coaccessible iff it lies on a path ending at a final state. A machine is \ accessible (coaccessible) iff all its states are accessible (coaccessible). A \ machine that is both accessible and coaccessible is called trim. \nMost \ algorithms in ", StyleBox["Automata", FontFamily->"Courier"], " automatically generate only accessible machines. If a full machine is \ wanted one can force the some of the algorithms to include inaccessible state \ by setting option ", StyleBox["Full->True", FontFamily->"Courier"], ", see for example the discussion of ", StyleBox["ToDFA", FontFamily->"Courier"], " below. \nNote that the accessible part of a DFA is always a DFA. \ However, in general the coaccessible part of a DFA is not complete. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m = CounterDFA[b, 3, {a, b}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(AccessibleFA[m]\), "\n", \(CoAccessibleFA[m]\), "\n", \(TrimFA[m]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(m = IthSymbolFA[a, 3, {a, b}]\), "\n", \(mm = CompleteFA[m]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(TrimFA[mm] === m\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Disjoint Sum and Product of Semiautomata", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:10"], Cell[TextData[{ "For semiautomata there is a natural way to form a (disjoint) sum and \ product of two machines. The sum is obtained by considering two machines as \ one (which causes problems if the state sets are not disjoint; by renaming of \ states we can clearly always insure that the state sets are in fact \ disjoint). The corresponding command is ", ButtonBox["SumFA", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m1 = CounterDFA[a, 0, {a, b}, Modulus \[Rule] 3]\ // \ ToSA\)], "Input",\ AspectRatioFixed->True], Cell[BoxData[ \(m2 = CounterDFA[b, 0, {a, b}, Modulus \[Rule] 4]\ // \ ToSA\)], "Input",\ AspectRatioFixed->True], Cell[BoxData[ \(SumFA[m1, m2, Normalize \[Rule] 1]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Similarly we can define a product ", Cell[BoxData[ \(TraditionalForm\`M\_\(\(1\)\(\ \)\)\[Cross]\ M\_\(\(2\)\(\ \)\)\)]], "of two semiautomata ", Cell[BoxData[ \(TraditionalForm\`M\_1\)]], " and ", Cell[BoxData[ \(TraditionalForm\`M\_2\)]], ": the state set is the Cartesian product of the two machines and the \ transitions are defined by\n\t", Cell[BoxData[ \(TraditionalForm\`\((\((p, q)\), a, \((p\^\[Prime], q\^\[Prime])\))\)\ \ \[Element] \ \ Trans( M\_\(\(1\)\(\ \)\)\[Cross]\ M\_\(\(2\)\(\ \)\))\)]], " iff \n\t", Cell[BoxData[ \(TraditionalForm\`\((p, a, p\^\[Prime])\)\ \[Element] \ Trans(M\_1)\)]], " and ", Cell[BoxData[ \(TraditionalForm\`\((q, a, q\^\[Prime])\)\ \[Element] \ Trans(M\_2)\)]], "\nNote that the product construction is quadratic time whereas sum is \ linear." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(ProductFA[m1, m2, Normalize \[Rule] 1]\), "\n", \(Transitions[%]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Computations in a sum automaton are the union of the computations in the \ component machines. In a product automaton, however, every computation \ corresponds to a pair of computations in the component automata with the same \ input sequence. This can be used to generate automata that accept unions and \ intersections of given acceptance languages. \nNote that there is a little \ twist in the construction of the product automaton if one of the two machines \ contains epsilon moves. In this case we have to add trivial transitions ", Cell[BoxData[ \(TraditionalForm\`\((p, \[Epsilon], p)\)\)]], " to both machines (otherwise there may be computations with the same \ input sequence in both machines but no corresponding computation in the \ product automaton). \nThe following example using ", ButtonBox["ProductFA", ButtonStyle->"AddOnsLink"], " shows that the resulting product machines may have numerous epsilon \ transitions. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(sa1 = ToSA[RegularExpressionToFA[RES[aa + bb], 3, Thompson \[Rule] True, EpsElim \[Rule] False]]\), "\n", \(sa2 = ToSA[RegularExpressionToFA[RES[aa + cc], 3, Thompson \[Rule] True, EpsElim \[Rule] False]]\), "\n", \(sa = ProductFA[sa1, sa2]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Of course, the language accepted by the product automaton is simply \ all words consisting only of a's.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[\ sa, \(-6\)]\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Boolean Operations", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Boolean Operations", "c:11"}], Cell[TextData[{ "By choosing appropriate initial and final states in a sum or product \ automaton as defined in the last section we can construct machines for union, \ intersection and even complement (provided we start from DFAs). Note, though, \ that the sum operation necessarily produces a machine with multiple initial \ states, and in particular not a DFA. Also note that machines obtained from \ sums and products are in general not accessible. Thus, in our implementation, \ only the accessible part of these machines is generated. The commands ", ButtonBox["UnionFA", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["IntersectionFA", ButtonStyle->"AddOnsLink"], " preserve DFAs when given DFAs as input. ", ButtonBox["ComplementFA", ButtonStyle->"AddOnsLink"], " converts to DFAs first and is thus potentially exponential in time and \ space requirements.\nAs a simple example, consider the language ", Cell[BoxData[ \(TraditionalForm\`L\ = \ {\ aaa, \ bb\ }\)]], ". We can use a product machine construction to get a DFA for the language. \ " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m1 = BuildDFA[aaa, {a, b}];\)\), "\n", \(\(m2 = BuildDFA[bb, {a, b}];\)\), "\n", \(m3 = UnionFA[m1, m2]\), "\n", \(LanguageFA[m3, \(-5\)]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Machine ", StyleBox["m3", "MR"], " is the accessible part of the full product machine. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m4 = UnionFA[m1, m2, Full \[Rule] True]\), "\n", \(m5 = AccessibleFA[m4]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(IsomorphicQDFA[m3, m5]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Of course, we could obtain a DFA for ", Cell[BoxData[ \(TraditionalForm\`L\)]], " directly from ", StyleBox["BuildDFA", FontFamily->"Courier"], ". Internally, ", StyleBox["BuildDFA", FontFamily->"Courier"], " uses a quotient machine construction and therefore produces the minimal \ automaton which turns out to have only 6 states in this case." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(BuildDFA[aaa, bb, {a, b}]\ // \ Size\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "As another example, let us compute the intersection machine of two \ mod-counters to obtain an automaton that accepts all strings with an even \ number of a's and b's. Mod-counters naturally have state set ", Cell[BoxData[ \(TraditionalForm\`{0, 1, \(\(..\)\(,\)\(n\)\) - 1}\)]], ". This state set can be preserved by option ", StyleBox["Normalize->1", FontFamily->"Courier"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(Ma = CounterDFA[a, 0, {a, b}, Modulus \[Rule] 2, Normalize \[Rule] 1];\)\), "\n", \(\(Mb = CounterDFA[b, 0, {a, b}, Modulus \[Rule] 2, Normalize \[Rule] 1];\)\), "\n", \(\(m = IntersectionFA[Ma, Mb, Normalize \[Rule] 1];\)\), "\n", \(PrintFA[m, LongForm \[Rule] True, TransOnly \[Rule] True]\)}], "Input", AspectRatioFixed->True], Cell["\<\ As one can see clearly, the first component of each state in m \ counts a's modulo 2 and the second component counts b's modulo 2. \ Normalization hides this information. Here are some words in the language of \ m:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(L = LanguageFA[m, \(-6\)];\)\), "\n", \(L\ // \ ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "To check if these strings are all have even-even parity use the command ", ButtonBox["ParikhVector", ButtonStyle->"AddOnsLink"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(ParikhVector[Flatten[L], {a, b}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(Union[Mod[%, 2]]\)], "Input"], Cell["\<\ To make the operations visually more obvious it is often good to \ use infix notation in conjunction with abbreviations. The union and \ complement machines only differ in the choice of final states:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(IntersectionFA[Ma, Mb]\), "\n", \(UnionFA[Ma, Mb]\), "\n", \(ComplementFA[Ma, Mb]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Complementation of m produces a machine for all strings with an odd \ number of a's or b's.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(mcomp = ComplementFA[m]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(L = LanguageFA[mcomp, \(-6\)];\)\), "\n", \(L\ // \ ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(\(ParikhVector[Flatten[L], {a, b}]\ \ // \ Mod[#, 2] &\)\ // \ Union\)], "Input", AspectRatioFixed->True], Cell["Union of FAs is linear but intersection is quadratic:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m1 = IthSymbolFA[a, 3, {a, b}];\)\), "\n", \(\(m2 = IthSymbolFA[b, 3, {a, b}];\)\), "\n", \(Size[{m1, m2}]\), "\n", \(UnionFA[m1, m2]\), "\n", \(IntersectionFA[m1, m2]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Concatenation and Kleene Star", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Concatenation Star", "c:12"}], Cell[TextData[{ ButtonBox["ConcatenateFA", ButtonStyle->"AddOnsLink"], " produces a machine for the concatenation of the acceptance languages of \ the input FSMs. The command is a polyadic. Here is an example:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(Nall = AllDFA[{a, b, c}];\)\), "\n", \(\(Na = BuildDFA[a, {a, b, c}];\)\), "\n", \(\(Nabc = BuildDFA[a, b, c, {a, b, c}];\)\), "\n", \(N3a = ConcatenateFA[Nall, Na, Nabc, Nabc]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ StyleBox["ConcatenateFA", FontFamily->"Courier"], " uses epsilon transitions to glue the machines together and then removes \ them afterwards. The corresponding machine with epsilon transitions is \ obtained by setting option ", StyleBox["EpsElim->False", FontFamily->"Courier"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(ConcatenateFA[Nall, Na, Nabc, Nabc, EpsElim \[Rule] False]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(EpsilonEliminationFA[%] === N3a\)], "Input", AspectRatioFixed->True], Cell["Check the acceptance language:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[N3a, \(-4\)]\ // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Command ", ButtonBox["StarFA", ButtonStyle->"AddOnsLink"], " also has the option ", StyleBox["EpsElim->False", FontFamily->"Courier"], " which turns off automatic epsilon elimination. For example, let" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(M1 = StarFA[EmptyDFA[3], EpsElim \[Rule] False]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Since ", Cell[BoxData[ \(TraditionalForm\`\(\(\[EmptySet]\^*\)\(\ \)\(=\)\(\ \ \)\({\[Epsilon]}\)\(\ \)\)\)]], " we have " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["EquivalentQFA[ ToDFA[M1], BuildDFA[Eps,3] ]", "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Shuffle Product", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Shuffle", "c:13"}], Cell[TextData[{ "The command ", ButtonBox["WordShuffle", ButtonStyle->"AddOnsLink"], " implements the shuffle operation on words and (finite) languages." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["WordShuffle[ bbb, aa ]", "Input", AspectRatioFixed->True], Cell["WordShuffle[ {aa,bb}, {ab,ba} ]", "Input", AspectRatioFixed->True], Cell[TextData[{ "Regular languages are closed under shuffle product. Accordingly, we \ provide a command ", ButtonBox["ShuffleProductFA", ButtonStyle->"AddOnsLink"], " that generates an FA for the shuffle product of the languages of the two \ input machines. Here is an example of a shuffle product of two regular \ languages:\n\t", Cell[BoxData[ \(TraditionalForm\`L\ \ = \ \ \({aa}\ \ || \ \ \(b\^*\)\ = \ \ all\ \ words\ with\ exactly\ two\ a' s\)\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ m1 = ShuffleProductFA[ \t\tBuildStarDFA[b,{a,b}], BuildDFA[aa,{a,b}] ]\ \>", "Input", AspectRatioFixed->True], Cell["Of course, there is a smaller DFA for L.", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(mm = MinimizeFA[m1]\), "\n", \(LanguageFA[mm, \(-5\)]\ // \ ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The command ", StyleBox["ShuffleProductFA", FontFamily->"Courier"], " has the usual option ", StyleBox["Normalize", FontFamily->"Courier"], ". As with product automata, the state set is a Cartesian product. However, \ only one component state is updated, rather than both at the same time. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(mmm = ShuffleProductFA[\[IndentingNewLine]\tBuildStarDFA[b, {a, b}], BuildDFA[aa, {a, b}], Normalize \[Rule] 1]\)], "Input", AspectRatioFixed->True], Cell["\<\ Only one computation leads from the initial to the final \ state.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell["PlotComputationFA[mmm, bbabbabb,Full->True];", "Input", AspectRatioFixed->True], Cell[BoxData[ \(AcceptQFA[mmm, bbabbabb, DoTrace \[Rule] True]\ // \(Curry[TableForm]\)[ TableDepth \[Rule] 2]\)], "Input"], Cell[TextData[{ "The shuffle operation corresponds to Hurwitz products in ", Cell[BoxData[ \(TraditionalForm\`\[DoubleStruckCapitalN] \[LeftAngleBracket]\ \[LeftAngleBracket]\(\[CapitalSigma]\^*\)\[RightAngleBracket]\ \[RightAngleBracket]\)]], ", the formal power series over ", Cell[BoxData[ \(TraditionalForm\`\(\[CapitalSigma]\^*\)\)]], " with non-negative integer coefficients. To use the command ", ButtonBox["HurwitzProduct", ButtonStyle->"AddOnsLink"], " we first translate languages ", Cell[BoxData[ \(TraditionalForm\`{aa}\)]], " and ", Cell[BoxData[ \(TraditionalForm\`{\[Epsilon], b, bb, bbb}\)]], " into corresponding series (or rather polynomials)." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["S1 = {aa} // LanguageToSeries", "Input", AspectRatioFixed->True], Cell["S2 = {Eps,b,bb,bbb,bbbb} // LanguageToSeries", "Input", AspectRatioFixed->True], Cell["HurwitzProduct[S1,S2]", "Input", AspectRatioFixed->True], Cell[TextData[{ "The command ", ButtonBox["ToSeries", ButtonStyle->"AddOnsLink"], " displays the result as a power series in ", Cell[BoxData[ \(TraditionalForm\`\[DoubleStruckCapitalN] \[LeftAngleBracket]\ \[LeftAngleBracket]\(\[CapitalSigma]\^*\)\[RightAngleBracket]\ \[RightAngleBracket]\)]], ". In order to prevent ", StyleBox["Mathematica", FontSlant->"Italic"], " from rearranging the terms according to its own sorting algorithm we have \ wrapped the sum into ", StyleBox["HoldForm", "MR"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(ToSeries[%]\)], "Input", AspectRatioFixed->True], Cell["\<\ Clearly, every word in the shuffle product has multiplicity 1. \ Hence the coefficients in the last sum are all 1. Higher multiplicities occur \ in the next example.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(L = {aa, ab, ba, bb};\)\), "\n", \(WordShuffle[L, L]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(LL = LanguageToSeries[L];\)\), "\n", \(H = HurwitzProduct[LL, LL]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(\(ListPlot[Last /@ H, PlotJoined \[Rule] True, PlotStyle \[Rule] Blue];\)\)], "Input"], Cell[BoxData[ \(ToSeries[H]\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Interlaced Products", "Subsection", Evaluatable->False, AspectRatioFixed->True], Cell[CellGroupData[{ Cell["Implementing Interlaced Products", "Subsubsection"], Cell[TextData[{ "Here is an example of how one might go about implementing an operation not \ natively supported in Automata. First, we compute a special normal form, a \ begin/exit automaton, where we require exactly one initial state of indegree \ 0 and exactly one final state of outdegree 0. Unlike the ", ButtonBox["BEFA", ButtonStyle->"AddOnsLink"], " machines used in the conversion from regular expressions to machines \ these begin/exit automata have no \[Epsilon]-transitions and thus cannot \ accept the empty word. This constraint is irrelevant for the typical \ application of interlaced automata, the analysis of codes. One can easily \ obtain such a machine by performing a bit of surgery on the minimal \ automaton. We remove inaccessible and co-inaccessible states in the end via \ ", ButtonBox["TrimFA", ButtonStyle->"AddOnsLink"], ", and pipe the resulting trim automaton through ", ButtonBox["AccessibleFA", ButtonStyle->"AddOnsLink"], " to obtain a better numbering system for the states. " }], "Text"], Cell[BoxData[{ \(ClearAll[toBE]\), "\[IndentingNewLine]", \(toBE[\ m_DFA\ ]\ := \ \[IndentingNewLine]Module[{q0, G, mm, n, k, ind}, \[IndentingNewLine]\t q0\ = \ TheInitial[m]; \[IndentingNewLine]\t G\ = \ ToGraphFA[m]; \[IndentingNewLine]\t mm\ = \ ToFA[m]; \[IndentingNewLine]\t n\ = \ Size[m]; \[IndentingNewLine]\t k\ = \ AlphabetSize[m]; \[IndentingNewLine]\t If[\ \(DegreeGraph[G, q0, Full \[Rule] True]\)[\([1]\)]\ > \ 0, \[IndentingNewLine]\t\tmm\ = \ AddState[\ mm\ ]; \[IndentingNewLine]\t\t\(n++\); \[IndentingNewLine]\t\t\ trgs\ = \ \(Thread[ Transitions[m]]\)[\([q0]\)]; \[IndentingNewLine]\t\tmm\ = \ Fold[\ AddTransitionFA[#1, n, #2, trgs[\([#2]\)]] &, \ mm, \ Range[k]]; \[IndentingNewLine]\t\tmm\ = \ SetInitialFA[\ mm, n\ ]\[IndentingNewLine]\t]; \[IndentingNewLine]\t ind\ = \ Plus @@ \((\ Last /@ DegreeGraph[G, Final[m], Full \[Rule] True])\); \[IndentingNewLine]\t If[\ ind\ > \ 0, \ \[IndentingNewLine]\t\tmm\ = \ AddState[\ mm\ ]; \[IndentingNewLine]\t\t\(n++\); \[IndentingNewLine]\t\t\ mm\ = \ SetFinalFA[\[IndentingNewLine]\t\t\tFold[\ AddTransitionFA[#1, #2, 0, n] &, \ mm, \ Final[m]], \ n\ ]\[IndentingNewLine]\t]; \[IndentingNewLine]\t\(\(mm\ // \ EpsilonEliminationFA\)\ // \ TrimFA\)\ // \ AccessibleFA\[IndentingNewLine]]\)}], "Input"], Cell[TextData[{ "Here is a first test of ", StyleBox["toBE", "MR"], ". The resulting machine should be equivalent to the original one and have \ the proper degrees on the begin and exit." }], "Text"], Cell[BoxData[{ \(\(m\ = \ CounterDFA[a, 5, 2];\)\), "\[IndentingNewLine]", \(be\ = \ toBE[m]\)}], "Input"], Cell[BoxData[ \(EquivalentQFA[m, be]\)], "Input"], Cell[BoxData[ \({\ \ DegreesFA[be, Full \[Rule] False], \[IndentingNewLine]\ DegreesFA[be, Full \[Rule] False, Direction \[Rule] Backward]}\ // \ TableForm\)], "Input"], Cell["\<\ They are also unambiguous (the surgery introduces nondeterministic \ transitions but computations remain determined by their labels).\ \>", "Text"], Cell[BoxData[ \(AmbiguousQFA[be]\)], "Input"], Cell["A few more simple equivalence tests.", "Text"], Cell[BoxData[ \(With[\ {m\ = \ BuildDFA[\ a, aa, \ bb, ccc, 3\ ]}, \[IndentingNewLine]EquivalentQFA[m, toBE[m]]\ ]\)], "Input"], Cell[BoxData[ \(With[\ {m\ = \ IthSymbolFA[a, \(-3\), 2, Full \[Rule] True]}, \[IndentingNewLine]EquivalentQFA[m, toBE[m]]\ ]\)], "Input"], Cell[BoxData[ \(With[\ {m\ = \ DFA[3, 2, {{2, 3, 3}, {1, 3, 3}}, 1, {3}]}, \[IndentingNewLine]EquivalentQFA[m, toBE[m]]\ ]\ // \ FullForm\)], "Input"], Cell[TextData[{ "The interlaced product of two begin/exit automata is defined like the \ ordinary product except that there are additional reset-transitions of the \ form\n\t\t", Cell[BoxData[ \(TraditionalForm\`\((p, q)\)\ \[Rule] \ \((p\^\[Prime], b\_2)\)\)]], " instead of ", Cell[BoxData[ \(TraditionalForm\`\((p, q)\)\ \[Rule] \ \((p\^\[Prime], e\_2)\)\)]], " where ", Cell[BoxData[ \(TraditionalForm\`p\^\[Prime] \[NotEqual] \ e\_1\)]], " and likewise \n\t\t", Cell[BoxData[ \(TraditionalForm\`\((p, q)\)\ \[Rule] \ \((b\_1, q\^\[Prime])\)\)]], " instead of ", Cell[BoxData[ \(TraditionalForm\`\((p, q)\)\ \[Rule] \ \((e\_1, q\^\[Prime])\)\)]], " where ", Cell[BoxData[ \(TraditionalForm\`q\^\[Prime] \[NotEqual] \ e\_2\)]], ".\nThus the interlaced product automaton essentially produces a \ factorization of a word with respect to the two given languages.\nFor the \ actual product construction it is best to use the ", ButtonBox["Closure", ButtonStyle->"AddOnsLink"], " operation. Note the option ", ButtonBox["Filter", ButtonStyle->"AddOnsLink"], " that allows one to manipulate newly generated elements before they are \ being processed. In our situation, we need to replace elements ", Cell[BoxData[ \(TraditionalForm\`\((p, e\_2)\)\)]], " by ", Cell[BoxData[ \(TraditionalForm\`\((p, b\_2)\)\)]], " and likewise ", Cell[BoxData[ \(TraditionalForm\`\((e\_1, q)\)\)]], " by ", Cell[BoxData[ \(TraditionalForm\`\((b\_1, q)\)\)]], ". First, a little helper function that uses Closure and the transition \ functions " }], "Text"], Cell[BoxData[{ \(ClearAll[interlacedProduct]\), "\[IndentingNewLine]", \(\(interlacedProduct[\ d1_, \ d2_, \ alph_, \ \[IndentingNewLine]\t b1_Integer, \ e1_Integer, \ b2_Integer, \ e2_Integer\ \ ]\ := \ \n Module[\ {k, dd, filt}, \[IndentingNewLine]filt[{e1, q_}]\ := \ {b1, q}\ \ /; \ q\ =!= \ e2; \[IndentingNewLine]filt[{p_, e2}]\ := \ {p, b2}\ \ /; \ p\ =!= \ e1; \[IndentingNewLine]filt[{p_, q_}]\ := \ {p, q}; \[IndentingNewLine]\(dd[s_]\)[{p_, q_}]\ := \ CartesianProduct[\ \ d1[p, s], \ d2[q, s]]; \[IndentingNewLine]Closure[\ \ {{b1, b2}}, \ Map[\ dd, \ alph\ ], \ SetClosure \[Rule] True, \ DoTrace \[Rule] True, Filter \[Rule] filt\ ]\[IndentingNewLine]];\)\)}], "Input"], Cell[TextData[{ "The main function is essentially just a wrapper for ", StyleBox["interlaceProduct", "MR"], " that provides the proper inputs and formats the output." }], "Text"], Cell[BoxData[{ \(ClearAll[InterlacedProduct]\), "\[IndentingNewLine]", \(\(InterlacedProduct[\ m1_FA, \ m2_FA\ ]\ := \ \[IndentingNewLine]Module[\ {d1, d2, k, alph, \ b1, \ b2, \ e1, \ e2, \ QQ, \ tt}, \[IndentingNewLine]\t\t{k, alph}\ = \ Alphabet[m1, Full \[Rule] True]; \[IndentingNewLine]\t\tb1\ = \ \(Initial[ m1]\)[\([1]\)]; \[IndentingNewLine]\t\te1\ = \ \(Final[ m1]\)[\([1]\)]; \[IndentingNewLine]\t\tb2\ = \ \(Initial[ m2]\)[\([1]\)]; \[IndentingNewLine]\t\te2\ = \ \(Final[ m2]\)[\([1]\)]; \[IndentingNewLine]\t\tTransitionFunctionFA[\ m1, \ d1\ ]; \[IndentingNewLine]\t\tTransitionFunctionFA[\ m2, \ d2\ ]; \[IndentingNewLine]\t\t{QQ, tt}\ = \ interlacedProduct[\ d1, \ \ d2, alph, \ b1, \ e1, \ b2, \ e2\ \ ]; \[IndentingNewLine]\t\tFA[\ Length[QQ], \ k, \ tt, \ \(Position[ QQ, {b1, b2}]\)[\([1]\)], \[IndentingNewLine]\t\t\t\(Position[ QQ, {e1, e2}]\)[\([1]\)], {}, QQ\ ]\ \ \[IndentingNewLine]];\)\)}], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["An Example", "Subsubsection"], Cell[TextData[{ "An application. We construct two DFAs by conversion from regular \ expressions ", Cell[BoxData[ \(TraditionalForm\`\(a\^*\) b\ a\)]], " and ", Cell[BoxData[ \(TraditionalForm\`a\ \(\((\(b\^+\) a)\)\^*\) \((\ a\ + \ \(b\^+\)(a + b))\)\)]], "." }], "Text"], Cell[BoxData[{ \(\(re1\ = \ RET[\ RES[a], ba];\)\), "\[IndentingNewLine]", \(\(re2\ = \ RET[\ a, \ RES[RET[RES[b], ba]], \ REP[\ a, \ RET[RES[b], b, REP[a, b]]]];\)\)}], "Input"], Cell[BoxData[ \(re2\ // \ PrintRE\)], "Input"], Cell[BoxData[{ \(\(m1\ = \ MinimizeFA[\ RegularExpressionToFA[re1, 2]];\)\), "\[IndentingNewLine]", \(\(m2\ = \ MinimizeFA[\ RegularExpressionToFA[re2, 2]];\)\)}], "Input"], Cell["The DFAs are converted into begin/exit format.", "Text"], Cell[BoxData[{ \(mm1\ = \ toBE[m1]\), "\[IndentingNewLine]", \(mm2\ = \ toBE[m2]\ // \ TrimFA\)}], "Input"], Cell[TextData[{ "Actually, one can do better than ", StyleBox["mm2", "MR"], ". Constructing the same machine by hand produces a 4-state automaton." }], "Text"], Cell[BoxData[{ \(\(mm2\ = \ FA[4, 2, {{1, 1, 2}, {2, 1, 4}, {2, 2, 3}, {3, 1, 2}, {3, 1, 4}, {3, 2, 3}, {3, 2, 4}}, {1}, {4}];\)\), "\n", \(EquivalentQFA[mm2, m2]\)}], "Input"], Cell["\<\ Now for the interlaced product. Note how only the accessible part \ is constructed, otherwise we would obtain a machine of size 16.\ \>", "Text"], Cell[BoxData[ \(mi\ = \ InterlacedProduct[\ mm1, \ mm2\ ]\)], "Input"], Cell[TextData[{ "The state set is structured, ", Cell[BoxData[ \(TraditionalForm\`Q\ \[SubsetEqual] \ \([4]\)\[Cross]\([4]\)\)]], "." }], "Text"], Cell[BoxData[ \(Q\ = \ States[mi]\)], "Input"], Cell["Some accepted words.", "Text"], Cell[BoxData[ \(LanguageFA[mi, \(-11\)]\ // \ EnumForm0\)], "Input"], Cell["A accepting computation on a word of length 9. ", "Text"], Cell[BoxData[ \(cmp\ = \ First@Cases[\ ComputationFA[mi, aaabaaababa], \ {1, __, 6}]\)], "Input"], Cell["\<\ Substituting back the actual states shows the two underlying \ computations in the component machines (plus resets).\ \>", "Text"], Cell[BoxData[ \(\(cmp\ /. \ RankingRules[Q, Direction \[Rule] Backward]\ // \ Thread\)\ // \ MatrixForm\)], "Input"], Cell[TextData[{ "A picture that indicates how the computations in the two machines are \ interlaced. Note how at most one reset appears at any time. For clarity we \ replace the final state ", Cell[BoxData[ \(TraditionalForm\`\((4, 4)\)\)]], " by ", Cell[BoxData[ \(TraditionalForm\`\((1, 1)\)\)]], "." }], "Text"], Cell[BoxData[{ \(<< Graphics`MultipleListPlot`\), "\n", \(\(lists = Thread[\(Cases[cmp, _Integer] /. \[InvisibleSpace]6 \[Rule] 1\) /. \[InvisibleSpace]RankingRules[Q, Direction \[Rule] Backward]];\)\), "\n", \(\(MultipleListPlot[ lists\[LeftDoubleBracket]1\[RightDoubleBracket] - 1, \(-lists\[LeftDoubleBracket]2\[RightDoubleBracket]\) + 1, PlotJoined \[Rule] True, PlotStyle \[Rule] {Red, Blue}, SymbolShape \[Rule] {PlotSymbol[Box], PlotSymbol[Box]}, Ticks \[Rule] None];\)\)}], "Input", CellTags->"S5.37.1"] }, Closed]], Cell[CellGroupData[{ Cell["Another Example", "Subsubsection"], Cell[TextData[{ "Let's consider the finite language ", Cell[BoxData[ FormBox[ RowBox[{"X", " ", "=", " ", RowBox[{"{", " ", RowBox[{"b", ",", " ", StyleBox["ab", FontSlant->"Italic"], ",", " ", StyleBox["aab", FontSlant->"Italic"], ",", " ", StyleBox["aaba", FontSlant->"Italic"]}], " ", "}"}]}], TraditionalForm]]], " which is a basis for ", Cell[BoxData[ \(TraditionalForm\`X\^\(\(\ \)\(*\)\)\)]], ", but as we will see not a code." }], "Text"], Cell[BoxData[ \(m\ = \ BuildDFA[b, ab, aab, aaba, 2]\)], "Input"], Cell["The DFA in begin/exit format.", "Text"], Cell[BoxData[ \(mm\ = \ toBE[m]\)], "Input"], Cell["The interlaced product of the machine with itself.", "Text"], Cell[BoxData[ \(mi\ = \ InterlacedProduct[\ mm, \ mm\ ]\)], "Input"], Cell["Some accepted words.", "Text"], Cell[BoxData[ \(\(\(LanguageFA[mi, \(-16\)]\)\(\ \)\)\)], "Input"], Cell[TextData[{ "A picture that shows that ", Cell[BoxData[ FormBox[ RowBox[{ StyleBox["aabaabaabaabaab", FontSlant->"Italic"], " ", "\[Element]", " ", \(X\^\(\(\ \)\(*\)\)\)}], TraditionalForm]]], " can be factored in two ways over ", Cell[BoxData[ \(TraditionalForm\`X\)]], ", so ", Cell[BoxData[ \(TraditionalForm\`X\)]], " fails to be a code." }], "Text"], Cell[BoxData[{ \(<< Graphics`MultipleListPlot`\), "\n", \(\(Q\ = \ States[mi];\)\), "\[IndentingNewLine]", \(\(cmp\ = \ First@Cases[\ ComputationFA[mi, aabaabaabaabaab], \ {1, __, 3}];\)\), "\[IndentingNewLine]", \(\(lists = Thread[\(Cases[cmp, _Integer] /. \[InvisibleSpace]3 \[Rule] 1\) /. \[InvisibleSpace]RankingRules[Q, Direction \[Rule] Backward]];\)\), "\n", \(\(MultipleListPlot[ lists\[LeftDoubleBracket]1\[RightDoubleBracket] - 1, \(-lists\[LeftDoubleBracket]2\[RightDoubleBracket]\) + 1, PlotJoined \[Rule] True, PlotStyle \[Rule] {Red, Blue}, SymbolShape \[Rule] {PlotSymbol[Diamond], PlotSymbol[Diamond]}, Ticks \[Rule] None];\)\)}], "Input", CellTags->"S5.37.1"] }, Closed]] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["The Transition Diagram", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Graphs", "c:19"}], Cell[CellGroupData[{ Cell["Accessible/Coaccessible Machines", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:20"], Cell[TextData[{ "A finite state machine can be construed as a labelled graph, the so-called \ transition diagram of the machine, perhaps with additional information about \ initial and final states. Several important properties of a FSM can be most \ conveniently expressed in terms of the transition diagram of the machine. \ Moreover, standard graph algorithms can then be used to test these \ properties. The command ", ButtonBox["ToGraphFA", ButtonStyle->"AddOnsLink"], " translates a finite state machine into the corresponding labeled or \ unlabeled directed graph which graph is often useful to perform operations on \ the machines, or test various properties." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "As a first application, consider accessibility. The acceptance language of \ a FSM is clearly not affected by deletion of all states that fail to be \ accessible from an initial state and coaccessible from a final state in the \ diagram. Finding theses states comes down to computing weakly connected \ components in the transition diagram. Since DFAs are not usually accessible \ and coaccessible, the command ", ButtonBox["TrimFA", ButtonStyle->"AddOnsLink"], " returns an FA (or NFA). " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m = RegularExpressionToFA[a ** RES[b] + b ** RES[a], {a, b}];\)\), "\n", \(\(m1 = ToDFA[m, Full \[Rule] True, External \[Rule] False];\)\), "\n", \(Size[m1]\)}], "Input"], Cell["\<\ The accessible and coaccessible part can be computed via conversion \ to a directed graph.\ \>", "Text"], Cell[BoxData[{ \(\(g = ToGraphFA[m1, Unlabeled \[Rule] True];\)\), "\n", \(acc = WeaklyConnectedComponents[g, Initial[m1]]\), "\n", \(coa = WeaklyConnectedComponents[ReverseGraph[g], Final[m1]]\), "\n", \(Q = acc \[Intersection] coa\)}], "Input", AspectRatioFixed->True], Cell["We extract the corresponding subautomaton.", "Text"], Cell[BoxData[ \(m2 = SelectFA[m1, Q]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "This has the same effect as applying command ", ButtonBox["TrimFA", ButtonStyle->"AddOnsLink"], "." }], "Text"], Cell[BoxData[ \(TrimFA[m1]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(EquivalentQFA[m2, %]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[m2, \(-6\)] // EnumForm0\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Finite Acceptance Languages", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:21"], Cell["\<\ The most basic property of regular languages that can be expressed \ in terms of the transition diagram is finiteness: a FSM accepts infinitely \ many words if and only if its transition diagram contains a loop (not labeled \ \[Epsilon]) that is accessible from the initial state and coaccessible from \ the set of final states. The latter condition is easily tested using standard \ graph algorithms. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m = BuildDFA[Eps, aa, bb, abab, {a, b, c}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(g = ToGraphFA[m]\), "\n", \(ToGraphFA[m, Unlabeled \[Rule] False]\)}], "Input", AspectRatioFixed->True], Cell["\<\ We can now compute the strongly connected components of this graph.\ \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(StronglyConnectedComponents[g]\)], "Input", AspectRatioFixed->True], Cell["All the components other than the sink are trivial:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(TrapStatesFA[m]\), "\n", \(StronglyConnectedComponents[g, NonTrivial \[Rule] True]\)}], "Input", AspectRatioFixed->True], Cell["Hence the acceptance language is finite:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(InfiniteQFA[m]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "To obtain a more interesting underlying graph, consider a machine for the \ language ", Cell[BoxData[ \(TraditionalForm\`\(\((a\[VeryThinSpace]a)\)\^*\) \(\((b\ \[VeryThinSpace]b)\)\^*\) \(\((a\[VeryThinSpace]a)\)\^*\)\)]], Cell[BoxData[ FormBox[ RowBox[{Cell[""], " "}], TraditionalForm]]], " (an even number of a's, followed by an even number of b's, followed by an \ even number of a's). We use a regular expression to generate the machine. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(mm = RegularExpressionToFA[ RES[aa] ** RES[bb] ** RES[aa], {a, b}];\)\), "\n", \(mm = MinimizeFA[mm]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(gg = ToGraphFA[mm]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The transition diagram of ", StyleBox["mm", "MR"], " has three strongly connected components of size 2 and the sink." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(StronglyConnectedComponents[gg, NonTrivial \[Rule] True]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(TrapStatesFA[mm]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(InfiniteQFA[mm]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "A DFA is called transitive iff its transition diagram has only one \ strongly connected component. The command ", ButtonBox["TransitiveQFA", ButtonStyle->"AddOnsLink"], " tests whether an FA is transitive. The option ", StyleBox["DoTrace->True", "MR"], " causes the strongly connected components of the transition diagram of ", Cell[BoxData[ \(TraditionalForm\`M\)]], " to be displayed." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m = MinimizeFA[IthSymbolFA[b, \(-3\), 2]];\)\), "\n", \(TransitiveQFA[m]\)}], "Input", AspectRatioFixed->True], Cell["\<\ We can also compute the collapse of the transition diagram \ (obtained by collapsing the strongly connected components into points). \ \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(gg0 = ToAdjacencyList[ToDirectedAcyclicGraph[gg]]\), "\n", \(VertexSet[gg0]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Definite Automata", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:22"], Cell[TextData[{ "A word ", Cell[BoxData[ \(TraditionalForm\`x\)]], " is said to be ", StyleBox["synchronizing", FontColor->RGBColor[0, 0, 1]], " for a machine ", Cell[BoxData[ \(TraditionalForm\`M\)]], " if all computations with label ", Cell[BoxData[ \(TraditionalForm\`x\)]], " have the same target, regardless of the starting point of the \ computation: ", Cell[BoxData[ \(TraditionalForm\`\[Delta](Q, x)\ = {p}\)]], ". This notion is mostly of interest for deterministic transitive automata.\ \nHere is an example of a deterministic semiautomaton that has a \ synchronizing word. Except for one state the machine is also complete. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(m = SA[15, \(-2\), {{1, 1, 2}, {2, 1, 2}, {3, 1, 4}, {4, 1, 6}, {5, 1, 8}, {6, 1, 8}, {7, 1, 9}, {8, 1, 4}, {9, 1, 12}, {10, 1, 12}, {11, 1, 13}, {12, 1, 13}, {13, 1, 9}, {14, 1, 6}, {1, 2, 1}, {2, 2, 3}, {3, 2, 5}, {4, 2, 7}, {5, 2, 1}, {6, 2, 8}, {7, 2, 10}, {8, 2, 11}, {9, 2, 13}, {10, 2, 14}, {11, 2, 5}, {12, 2, 12}, {13, 2, 15}, {14, 2, 14}, {15, 2, 10}}];\)\)], "Input"], Cell[BoxData[ \(DegreesFA[m]\ // \ ColumnForm\)], "Input"], Cell["\<\ The transition function demonstrates that \"01010\" synchronizes \ this machine. \ \>", "Text"], Cell[BoxData[{ \(TransitionFunctionFA[m, delta]\), "\n", \(delta[Range[15], "\<01010\>"]\)}], "Input"], Cell["The corresponding plot.", "Text"], Cell[BoxData[ \(\(PlotComputationFA[m, "\<01010\>"];\)\)], "Input"], Cell["\<\ To find a synchronizing word one can apply brute force: compute a \ transfer sequence in the corresponding power automaton. \ \>", "Text"], Cell[BoxData[{ \(\(mm\ = \ ToDFA[m, Normalize \[Rule] 1];\)\), "\[IndentingNewLine]", \(mm\ // \ Size\)}], "Input"], Cell[BoxData[ \(targ\ = \ With[\ {Q = States[mm]}, \ PositionList[\ Q, \ Cases[Q, {_}]]]\)], "Input"], Cell[BoxData[ \(TransferSequenceFA[mm, {1}, targ]\)], "Input"], Cell["\<\ All these words are duly synchronizing, albeit with different \ target states.\ \>", "Text"], Cell[BoxData[ \(\(delta[Range[15], #] &\)\ /@ \ Flatten[%]\)], "Input"], Cell[TextData[{ "A DFA is ", StyleBox["definite", FontColor->RGBColor[0, 0, 1]], " if there is some number ", Cell[BoxData[ \(TraditionalForm\`n\)]], " such that all words ", Cell[BoxData[ \(TraditionalForm\`x\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\(\(|\)\(x\)\(|\)\(\ \)\(\(\[GreaterEqual]\)\(\ \ \)\(n\)\)\)\)]], ", are synchronizing. Thus, for all states ", Cell[BoxData[ \(TraditionalForm\`p\)]], " and ", Cell[BoxData[ \(TraditionalForm\`q\)]], ", we have: ", Cell[BoxData[ \(TraditionalForm\`\[Delta](p, x)\ = \ \[Delta](q, x)\)]], " provided ", Cell[BoxData[ \(TraditionalForm\`x\)]], " is sufficiently long. \nA moments thought shows that a DFA is definite if \ and only if its product automaton has only one nontrivial strongly connected \ component. Since initial and final states play no role in this, we may use \ the product construction for semiautomata. The machines generated by ", StyleBox["IthSymbolFA", "MR"], " are definite: the state is determined entirely be the last three input \ symbols. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = IthSymbolFA[a, \(-3\), {a, b}, Full \[Rule] True]\), "\n", \(DefiniteQFA[m]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "We can determine the critical length ", Cell[BoxData[ \(TraditionalForm\`n\)]], " in the definition of definiteness using the same command ", StyleBox["DefiniteQFA", "MR"], " with option ", StyleBox["Full->True", "MR"], "." }], "Text"], Cell[BoxData[ \(DefiniteQFA[m, Full \[Rule] True]\)], "Input"], Cell[TextData[{ "The method employed in the algorithm is to compute the product of the \ finite state machine with itself, and convert the product machine into a \ directed graph. The strongly connected components of this graph determine \ definiteness, and an analysis of the path length between the components \ determines the critical length ", Cell[BoxData[ \(TraditionalForm\`n\)]], ". More precisely, all sufficiently long paths must lead to a SCC that is \ part of the diagonal ", Cell[BoxData[ \(TraditionalForm\`{\ \((p, p)\)\ | \ p\ \[Element] \ Q\ }\ \ \[SubsetEqual] \ M\^\(\(\ \)\(2\)\)\)]], ". \nTo speed up the computation a bit, one can compute the product \ automaton based on unordered pairs of states rather than the usual ordered \ pairs. For the remaining analysis of the diagram, unordered pairs suffice." }], "Text"], Cell[BoxData[{ \(\(m2 = SquareSA[ToSA[m]];\)\), "\n", \(\(g = ToGraphFA[m2];\)\), "\n", \(StronglyConnectedComponents[g, NonTrivial \[Rule] True]\)}], "Input", AspectRatioFixed->True], Cell["\<\ There is only one non-trivial SCC, so the machine is definite. \ Similarly, the corresponding star automaton is definite. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m3 = ToSA[StarFA[m]];\)\), "\n", \(\(m4 = SquareSA[m3];\)\), "\n", \(\(g = ToGraphFA[m4];\)\), "\n", \(StronglyConnectedComponents[g, NonTrivial \[Rule] True]\)}], "Input"], Cell[TextData[{ "But machines for the language ", Cell[BoxData[ \(TraditionalForm\`\(\(\ \)\(\(\(a( b\[VeryThinSpace]b)\)\^*\)\ + \ \(\(b( a\[VeryThinSpace]a)\)\^*\)\)\)\)]], " should not be definite. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(RegularExpressionToFA[a ** RES[bb] + b ** RES[aa], {a, b}]\), "\n", \(\(m5 = SquareSA[ToSA[%], Normalize \[Rule] 1];\)\), "\n", \(\(g = ToGraphFA[m5];\)\), "\n", \(StronglyConnectedComponents[g, NonTrivial \[Rule] True]\)}], "Input"], Cell["\<\ There are several components, so we have to take a closer look. Not \ all the SCCs are part of the diagonal, so the machine in question is not \ definite.\ \>", "Text"], Cell[BoxData[ \(With[\ {Q = States[m5]}, PositionList[Q, Cases[Q, {x_, x_}]]]\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Ambiguous Automata", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:23"], Cell[TextData[{ "A FSM is ", StyleBox["ambiguous", FontColor->RGBColor[0, 0, 1]], " if there is some word ", Cell[BoxData[ \(TraditionalForm\`x\)]], " and states ", Cell[BoxData[ \(TraditionalForm\`p\)]], " and ", Cell[BoxData[ \(TraditionalForm\`q\)]], " such that there are at least two computations from ", Cell[BoxData[ \(TraditionalForm\`p\)]], " to ", Cell[BoxData[ \(TraditionalForm\`q\)]], " labelled ", Cell[BoxData[ \(TraditionalForm\`x\)]], ". Clearly, a deterministic machine is always unambiguous. But \ nondeterministic machines may also be unambiguous. The following example will \ be analyzed more carefully in the section on cellular automata. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(m = SA[8, \(-2\), {{1, 2, 1}, {1, 2, 2}, {2, 1, 3}, {2, 2, 4}, {3, 1, 5}, {3, 1, 6}, {4, 2, 7}, {4, 1, 8}, {5, 2, 1}, {5, 2, 2}, {6, 2, 3}, {6, 2, 4}, {7, 1, 5}, {7, 1, 6}, {8, 1, 7}, {8, 1, 8}}];\)\)], "Input"], Cell[BoxData[ \(DegreesFA[m] // \ ColumnForm\)], "Input"], Cell[TextData[{ "In terms of the unfolding of the automaton ambiguity would translate into \ the existence of a diamond. More precisely, the automaton ", Cell[BoxData[ \(TraditionalForm\`M\)]], " is ambiguous if and only if there is some word ", Cell[BoxData[ \(TraditionalForm\`x\)]], " such that the unfolding ", Cell[BoxData[ \(TraditionalForm\`TD(M, x)\)]], " has two paths from some initial vertex to a terminal vertex. The \ following picture shows that ", Cell[BoxData[ \(TraditionalForm\`x\ = \ 001100\)]], " fails to produce a diamond." }], "Text"], Cell[BoxData[ \(\(PlotComputationFA[m, "\<001100\>", \[IndentingNewLine]\t PlotStyle \[Rule] { .015, .02}, LineStyle \[Rule] { .004, .006}];\)\)], "Input"], Cell["\<\ The method employed to determine definiteness can easily be adopted \ to ambiguity testing. This time, we have to verify that the SCC containing \ the diagonal (in the diagram of the square of the automaton) consists only of \ the diagonal itself.\ \>", "Text"], Cell[BoxData[ \(AmbiguousQFA[m]\)], "Input"], Cell[TextData[{ "The canonical nondeterministic automata that recognize all words with a \ certain symbol in position ", Cell[BoxData[ \(TraditionalForm\`\(-i\)\)]], " provide another example of unambiguous machines. " }], "Text"], Cell[BoxData[ \(IthSymbolFA[a, \(-3\)]\ // \ DeterministicQFA\)], "Input"], Cell[BoxData[ \(IthSymbolFA[a, \(-3\)]\ // \ AmbiguousQFA\)], "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Conversion Algorithms", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:14"], Cell[CellGroupData[{ Cell["Simple Type Conversions", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Conversion", "c:15"}], Cell[TextData[{ "There are algorithms to convert a finite state machine of some type into \ an equivalent machine of another type. The conversions from DFA to NFA to FA \ are trivial and amount to rewriting the data structure. Also, FAs without \ \[Epsilon]-moves are easily converted into NFAs and vice versa. Thus we are \ left with two interesting conversion problems: from an FA with \ \[Epsilon]-moves to an FA without \[Epsilon]-moves and from there to an DFA. \ The two corresponding algorithms are usually referred to as \ \[Epsilon]-elimination and deterministic simulation. In ", StyleBox["Automata", "MR"], ", the commands that perform type conversions are ", ButtonBox["EpsilonEliminationFA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["ToFA", ButtonStyle->"AddOnsLink"], ", ", ButtonBox["ToNFA", ButtonStyle->"AddOnsLink"], ", and ", ButtonBox["ToSA", ButtonStyle->"AddOnsLink"], ". We postpone the the discussion of deterministic simulation to the next \ section, see also ", ButtonBox["ToDFA", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["Here is an \[Epsilon]-free FA:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = IthSymbolFA[b, \(-3\), {a, b}]\), "\n", \(EpsilonFreeQ[m]\)}], "Input", AspectRatioFixed->True], Cell["\<\ The conversion of an \[Epsilon]-free FA to an NFA is quite \ straightforward and easily reversible.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m1 = ToNFA[m]\), "\n", \(m === ToFA[m1]\)}], "Input", AspectRatioFixed->True], Cell["DFAs are readily converted to NFAs or FAs. ", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = BuildDFA[aaa, bbb, {a, b}]\), "\n", \(ToNFA[m]\), "\n", \(ToDFA[%]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Unlike the other conversion operations, conversion to a semiautomaton with \ ", ButtonBox["ToSA", ButtonStyle->"AddOnsLink"], " usually changes the acceptance language since in an SA all states are \ considered initial as well as final. For example, the SA obtained from a \ suffix automaton accepts all factors. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = WordToFA[abcd, {a, b, c, d}, Type -> "\"]\), "\[IndentingNewLine]", \(mm\ = \ ToSA[m]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[mm, \(-6\)]\ // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(ToFA[mm]\)], "Input", AspectRatioFixed->True], Cell["\<\ Of course, we can reestablish the initial and final states if need \ be.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(SetInitialFinalFA[\ mm, \ Initial[m], \ Final[m]]\), "\[IndentingNewLine]", \(%\ === \ m\)}], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Epsilon Elimination", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Epsilon Elimination", "c:16"}], Cell[TextData[{ "Our first non-trivial conversion procedure translates an FA with \ epsilon-moves into and equivalent, epsilon-free machine. The algorithm \ basically computes the transitive, reflexive closure of the relation ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\_\[Epsilon]\)]], " and then replaces ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\)]], " by the product of ", Cell[BoxData[ \(TraditionalForm\`\[Tau]\)]], " and this relation. Note that this procedure does not affect the number of \ states, however, it will in general increase the number of transitions. \n\ First, we have to construct a machine with epsilon-moves. Epsilon elimination \ is performed automatically inside ", StyleBox["StarFA", FontFamily->"Courier"], " and ", StyleBox["ConcatenateFA", FontFamily->"Courier"], " (also in ", ButtonBox["RegularExpressionFA", ButtonStyle->"AddOnsLink"], ") described below. Option ", StyleBox["EpsElim->False", FontFamily->"Courier"], " will override this default. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m1 = StarFA[BuildDFA[aab, {a, b}], EpsElim \[Rule] False];\)\), "\n", \(\(m2 = StarFA[BuildDFA[bba, {a, b}], EpsElim \[Rule] False];\)\), "\n", \(m3 = ConcatenateFA[m1, m2, BuildDFA[bbb, {a, b}], EpsElim \[Rule] False]\)}], "Input"], Cell[BoxData[ \(m4 = EpsilonEliminationFA[m3]\)], "Input", AspectRatioFixed->True], Cell["\<\ Note that the number of initial states has increased. The total \ number of transitions in this example remains nearly the same.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(NumTransitions[m3]\), "\n", \(NumTransitions[m4]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["EpsilonEliminationFA", ButtonStyle->"AddOnsLink"], " has on option ", StyleBox["DoTrace", FontFamily->"Courier"], ", set ", StyleBox["False", "MR"], " by default, that causes the command to output a list \n", StyleBox["\t", FontFamily->"Courier"], Cell[BoxData[ \(TraditionalForm\`\(\({\ M, \ T\_\[Epsilon], \ T\_\(non - \[Epsilon]\), \ A}\)\(\ \)\)\)]], StyleBox[" \n", FontFamily->"Courier"], "where ", Cell[BoxData[ \(TraditionalForm\`M\)]], " is the machine after epsilon elimination, ", Cell[BoxData[ \(TraditionalForm\`T\_\[Epsilon]\)]], " and ", Cell[BoxData[ \(TraditionalForm\`T\_\(non - \[Epsilon]\)\)]], " are the epsilon transitions and non-epsilon transitions in the old \ machine, respectively. ", Cell[BoxData[ \(TraditionalForm\`\(\(A\)\(\ \ \)\)\)]], "is the adjacency list of the transitive closure graph induced on the state \ set by ", Cell[BoxData[ \(TraditionalForm\`T\_\(non - \[Epsilon]\)\)]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\({t1, t2, t3} = Rest@EpsilonEliminationFA[m3, DoTrace \[Rule] True, External \[Rule] False];\)\)], "Input"], Cell["\<\ MatrixForm[t1] MatrixForm[Thread@t2] ColumnForm[t3]\ \>", "Input", AspectRatioFixed->True] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["The Rabin-Scott Powerset Construction", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:14"], Cell[CellGroupData[{ Cell["Deterministic Simulation", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Conversion", "c:17"}], Cell[TextData[{ "The \[Epsilon] elimination algorithm from the last section returns a \ machine of essentially the same size as the input machine (i.e., the number \ of states remains constant, but the number of transitions may increase \ quadratically) and clearly has polynomial running time. Deterministic \ simulation, however, constructs a new machine whose state set is a subset of \ the power set of the input machine. As we will see, in some cases the full \ power set or at least a large part of it is encountered during the \ construction. As a result, the algorithm used in ", ButtonBox["ToDFA", ButtonStyle->"AddOnsLink"], " may have exponential running time and exponential space requirement as \ well.\nHere is an example. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = IthSymbolFA[b, \(-3\), {a, b}]\), "\n", \(mm = ToDFA[m]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Note that ", StyleBox["ToDFA", FontFamily->"Courier"], " constructs only the accessible part of the power set machine. Also, it \ automatically normalizes the output. We can override both defaults (together \ or independently). Note that it is necessary to use the internal algorithm \ here since the external one always generates only the accessible part. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(mmm = ToDFA[m, Full \[Rule] True, Normalize \[Rule] 1, External \[Rule] False];\)\), "\n", \(PrintFA[mmm, LongForm \[Rule] True, TransOnly \[Rule] True]\)}], "Input"], Cell[TextData[{ "The machine has now ", Cell[BoxData[ \(TraditionalForm\`2\^4 = 16\)]], " states. Its accessible part can be extracted using command ", StyleBox["AccessibleFA", FontFamily->"Courier"], " and is isomorphic to ", StyleBox["m2.", "MR"], " " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["AccessibleFA[ mmm ]", "Input", AspectRatioFixed->True], Cell[TextData[{ ButtonBox["AccessibleFA", ButtonStyle->"AddOnsLink"], " has option ", StyleBox["Normalize", FontFamily->"Courier"], ", which, when set to ", StyleBox["False", "MR"], ", will preserve the original state set." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(macc = AccessibleFA[mmm, Normalize \[Rule] 2]\)], "Input", AspectRatioFixed->True], Cell["\<\ It is now easy to see that exactly all those states p of mmm are \ accessible that contain (old) state 1.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(States[macc]\ // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The same states are obtained by setting the option ", StyleBox["Normalize->1", FontFamily->"Courier"], " in ", StyleBox["ToDFA", FontFamily->"Courier"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(States[ToDFA[m, Normalize \[Rule] 2]]\ \ // ColumnForm\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The accessible parts of ", StyleBox["mmm", "MR"], " and ", StyleBox["mm", "MR"], " are isomorphic." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(IsomorphicQDFA[macc, mm]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Another way to construct the power automaton is to think of the transition \ function of the nondeterministic machine as a map\n\t", Cell[BoxData[ \(TraditionalForm\`\[Delta]\ : \ \(\[ScriptCapitalP]( Q)\)\ \[Cross]\ \[CapitalSigma]\ \[LongRightArrow]\ \(\ \[ScriptCapitalP](Q)\)\)]], ",\nthat is, as a right-action of ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma]\^\(\(\ \)\(*\)\)\)]], " on ", Cell[BoxData[ \(TraditionalForm\`\[ScriptCapitalP](Q)\)]], ", and to construct the corresponding sub-semimodule generated by ", Cell[BoxData[ \(TraditionalForm\`Q\ \[Element] \ \[ScriptCapitalP](Q)\)]], " using the command ", ButtonBox["GenerateCSM", ButtonStyle->"AddOnsLink"], ". We obtain the carrier set of the sub-semimodule, a list of witnesses \ (which are not relevant here) and a trace of the computation which \ corresponds to the labeled edges in the right Cayley graph of the \ semimodule." }], "Text"], Cell[BoxData[ \(TransitionFunctionFA[m, \[Delta]]\)], "Input"], Cell[BoxData[ \({Q, W, tt}\ = \ GenerateCSM[\ Range[4], \[Delta], 2\ , \ Equations \[Rule] Full]\)], "Input"], Cell["From these pieces we can easily assemble the DFA:", "Text"], Cell[BoxData[ \(msm\ = \ DFA[\ 8, \ 2, \ TransitionsToMatrix[8, 2, tt, Type \[Rule] "\"], \ \[IndentingNewLine]PositionOne[ Q, {1}], \ PositionList[Q, Cases[Q, {___, 4}]]\ ]\)], "Input"], Cell[BoxData[ \(EquivalentQFA[m, msm]\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Exponential Blowup", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Exponential blow-up", "c:12"}], Cell[TextData[{ "The conversion process from a nondeterministic machine to the \ corresponding minimal automaton has a potentially exponential component: the \ size of a machine produced by deterministic simulation can be as large as ", Cell[BoxData[ \(TraditionalForm\`2\^\(\(\ \)\(n\)\)\)]], " where ", Cell[BoxData[ \(TraditionalForm\`n\)]], " is the size of the original nondeterministic machine. Here are a few \ examples." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[CellGroupData[{ Cell["Reset Counters", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:13"], Cell[TextData[{ "Consider the following family of count/reset machines ", StyleBox["CR[n]", "MR"], ". Machine ", StyleBox["CR[n]", "MR"], " counts symbols ", Cell[BoxData[ \(TraditionalForm\`a\)]], " modulo n, and ignores symbols ", Cell[BoxData[ \(TraditionalForm\`b\)]], ", or nondeterministically resets to the initial state upon reading a ", Cell[BoxData[ \(TraditionalForm\`b\)]], ". ", StyleBox["CR[n]", "MR"], " has ", Cell[BoxData[ \(TraditionalForm\`n\)]], " states but will produce a power automaton of ", Cell[BoxData[ \(TraditionalForm\`2\^n - 1\)]], " states. The deterministic machine turns out to be already minimal. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(CR[n_Integer] := FA[n, 2, Join[\(({#1, 1, #1 + 1} &)\) /@ Range[n - 1], {{n, 1, 1}}, \({#, 2, #} &\) /@ Range[n], \({#, 2, 1} &\) /@ Range[2, n]], {1}, {1}];\)\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(m = CR[4]\)], "Input", AspectRatioFixed->True], Cell["\<\ One can see the workings of the machine by plotting computations on \ some inputs.\ \>", "Text"], Cell[BoxData[ \(\(PlotComputationFA[m, "\", Full \[Rule] True];\)\)], "Input"], Cell["\<\ The corresponding power automaton has 15 states. Needless to say, \ this is the accessible part.\ \>", "Text"], Cell[BoxData[{ \(\(m1 = ToDFA[m, Normalize \[Rule] 1];\)\), "\n", \(Size[m1]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[m1, \(-5\)]\ \ // ColumnForm\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(Size[MinimizeFA[m1]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "To see the exponential blowup more clearly we compute a whole sequence of \ these machines, say, up to ", StyleBox["CR[10]", "MR"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(Size[MinimizeFA[CR[#]]] &\) /@ Range[10]\)], "Input", AspectRatioFixed->True], Cell["\<\ If you have the external code installed, you can speed things up by \ computing only the size of the power automaton, and sending only a single \ integer back over the link:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(If[\ \ $defaultexternal, \ \ \[IndentingNewLine]\(SendProgram["\", CR[#], "\<]\>"] &\)\ /@ Range[12]\ ]\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Circulant Machines", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:14"], Cell[TextData[{ "Here is another example for exponential blow-up during deterministic \ simulation. The underlying transition diagram is a circulant ", Cell[BoxData[ \(TraditionalForm\`C(n; 1, \(-1\))\)]], ", i.e., a bi-cycle. The labels are all ", StyleBox["a", FontSlant->"Italic"], " for clockwise edges and the first counterclockwise edge, and ", StyleBox["b", FontSlant->"Italic"], " for the remaining edges. All states are initial and final. Note that the \ machine is almost a permutation automaton: we only need to flip the one \ counterclockwise transition from ", StyleBox["a", FontSlant->"Italic"], " to ", StyleBox["b", FontSlant->"Italic"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(circ[n_Integer] := CirculantSA[n, {1, \(-1\)}, Join[Table[1, {n + 1}], Table[2, {n - 1}]], \(-2\)]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(circ[4]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(\(Size[MinimizeFA[circ[#]]] &\) /@ Range[10]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Again, a smaller range is appropriate if you have to use the ", StyleBox["Mathematica", FontSlant->"Italic"], " minimization procedure instead.\nThe same blow-up occurs for odd-sized \ machines when we restrict the initial states to ", Cell[BoxData[ \(TraditionalForm\`{1}\)]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m = SetInitialFA[circ[9], 1\ ]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(Size[MinimizeFA[m]]\)], "Input", AspectRatioFixed->True] }, Closed]] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Some Sample Machines", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Sample machines", "c:25"}], Cell[CellGroupData[{ Cell["Ranking DFAs", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:26"], Cell[TextData[{ "There are several natural enumerations of all DFAs on ", Cell[BoxData[ \(TraditionalForm\`n\)]], " states and an alphabet of size ", Cell[BoxData[ \(TraditionalForm\`k\)]], "; or ", Cell[BoxData[ \(TraditionalForm\`\((n, k)\)\)]], "-DFAs for short. This package contains a ranking and unranking function ", ButtonBox["RankToDFA", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["RankOfDFA", ButtonStyle->"AddOnsLink"], " based on one such enumeration. ", ButtonBox["NumberOfDFA", ButtonStyle->"AddOnsLink"], " counts the number of ", Cell[BoxData[ \(TraditionalForm\`\((n, k)\)\)]], "-DFAs. Note that no effort is made to identify isomorphic machines, so \ this is not particularly useful.\nFor one and two symbol alphabets the number \ of DFAs on ", Cell[BoxData[ \(TraditionalForm\`n\)]], " states, ", Cell[BoxData[ \(TraditionalForm\`n\ = \ 1, \(\(..\)\(,\)\(10\)\)\)]], ", is as follows:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Table[{NumberOfDFA[n, 1], NumberOfDFA[n, 2]}, {n, 10}]\ // TableForm\)], "Input", AspectRatioFixed->True], Cell["Here are the ranking and unranking functions.", "Text"], Cell["m = RankToDFA[12345,3,2]", "Input", AspectRatioFixed->True], Cell["RankOfDFA[m]", "Input", AspectRatioFixed->True], Cell["PrintFA[ m ]", "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[m, \(-4\)]\ // ColumnForm\)], "Input", AspectRatioFixed->True], Cell["\<\ We can use the ranking machinery to generate random automata. This \ is occasionally useful to test new functions on these machines. \ \>", "Text",\ Evaluatable->False, AspectRatioFixed->True], Cell["RankToDFA[ Random[Integer,NumberOfDFA[#1,#2]],#1,#2]&[8,3]", "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[%, \(-4\)]\ // ColumnForm\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["One-symbol Alphabets", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:27"], Cell[CellGroupData[{ Cell[" Lassos", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"41-minimal DFAs", "c:28"}], Cell[TextData[{ "In this section we consider the special case of a one-symbol alphabet, \ say, the alphabet ", Cell[BoxData[ \(TraditionalForm\`{a}\)]], ". A moments thought reveals that in this case all DFAs have the structure \ of a one-generated monoid: there is a linear transient part followed by a \ periodic part. Less formally: they look like a lasso. As an example, suppose \ we wish to construct the minimal DFA for the following language:\n\t", Cell[BoxData[ \(TraditionalForm\`L = {\ a\^\(\(\ \)\(i\)\) | i \[GreaterEqual] \ 4\ \ \[And] \ i = 0, 3 mod\ 4}\)]], ".\nSince ", Cell[BoxData[ \(TraditionalForm\`L\)]], " can be decomposed as\n\t", Cell[BoxData[ \(TraditionalForm\`L\ = \ {aaaa} \((\[Epsilon] + aaa)\) {\ a\^i | \ i = 0 mod 4}\)]], "\nwe can build an automaton for ", Cell[BoxData[ \(TraditionalForm\`\(\(\ \)\(L\)\(\ \ \)\)\)]], "as follows." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m1 = ConcatenateFA[\[IndentingNewLine]\t BuildDFA[{aaaaaaa, aaaa}, {a}], \[IndentingNewLine]\t CounterDFA[a, 0, {a}, \ Modulus \[Rule] 4]]\), "\n", \(m2 = MinimizeFA[m1]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Thus, the transient part has length 5 and the loop has length 4. \ Consequently, the acceptance language is ultimately periodic with period 4:\ \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[m2, \(-40\), SizeOnly \[Rule] True]\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[" (3,1)-DFAs", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"41-minimal DFAs", "c:28"}], Cell["\<\ Which minimal automata arise from (3,1) DFAs? We may safely assume \ that the initial state is 1.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(NumberOfDFA[3, 1]\), "\n", \(\(cand = Select[Range[NumberOfDFA[3, 1]], Mod[Quotient[#, 8], 3] \[Equal] 0 &];\)\), "\n", \(Length[cand]\)}], "Input", AspectRatioFixed->True], Cell["\<\ We can now generate the machines, minimize them and eliminate \ duplicates. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(auto31 = \(RankToDFA[#, 3, 1] &\) /@ cand;\)\), "\n", \(min31 = Union[MinimizeFA /@ auto31]\), "\n", \(Length[%]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The next step is to eliminate isomorphic machines. This can be done using \ the procedure ", ButtonBox["MakeIndex", ButtonStyle->"AddOnsLink"], ". ", StyleBox["MakeIndex", FontFamily->"Courier"], " takes as input a list and an equivalence relation and returns the \ canonical kernel function describing the equivalence classes of the list \ elements. It turns out that the first 18 machines are non-isomorphic." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \({ind, r} = MakeIndex[min31, IsomorphicQDFA]\)], "Input", AspectRatioFixed->True], Cell["\<\ The acceptance languages (or rather: the first few words) of these \ machines can be nicely displayed as a matrix. Notice the periodicity \ properties of the rows.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(lang = \(LanguageFA[#, \(-Length[min31]\), SizeOnly \[Rule] True] &\) /@ \ Take[min31, 18];\)\), "\n", \(\(PlotMatrix[Sort[lang], GridLines \[Rule] True];\)\)}], "Input", AspectRatioFixed->True], Cell["\<\ The rows here correspond to (initial segments of) the acceptance \ languages of the machines. The periodicity properties are clearly \ visible.\ \>", "Text"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["I-th Symbol from the End", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:31"], Cell[TextData[{ "There is a natural nondeterministic machine for languages of the form \n\t\ ", Cell[BoxData[ \(TraditionalForm\`L(b, \(-r\)) = \(\[CapitalSigma]\^*\) b\ \[CapitalSigma]\^\(r - 1\)\)]], ". \nThus every word in the language has a symbol '", Cell[BoxData[ \(TraditionalForm\`b\)]], "' in position ", Cell[BoxData[ \(TraditionalForm\`\(-r\)\)]], ". The machine has ", Cell[BoxData[ \(TraditionalForm\`r\)]], " states and all the nondeterministic transitions occur only at state 1. \ The command ", ButtonBox["IthSymbolFA", ButtonStyle->"AddOnsLink"], " generates the corresponding FA. We use alphabet ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma]\_\(\(3\)\(\ \)\) = \ {0, 1, 2}\)]], " throughout. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m1 = IthSymbolFA[b, \(-3\), 3];\)\), "\n", \(PrintFA[m1]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Almost all the states in ", StyleBox["m1", "MR"], " are deterministic, only state 1 has two transitions under input '", Cell[BoxData[ \(TraditionalForm\`b\)]], "':" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(DegreesFA[m1]\ // TableForm\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "It may be desirable to number the states starting at 0 rather than 1. To \ this end there is the option ", StyleBox["Normalize", "MR"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m1 = IthSymbolFA[b, \(-3\), 3, Normalize \[Rule] 1]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "There is also a natural DFA for the language ", Cell[BoxData[ \(TraditionalForm\`L(b, \(-3\))\)]], " that uses as set of states all words over the alphabet of length at most \ ", Cell[BoxData[ \(TraditionalForm\`r\)]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m2 = IthSymbolFA[b, \(-3\), 3, Normalize \[Rule] 1, \ Full \[Rule] True]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Thus the automaton has ", Cell[BoxData[ \(TraditionalForm\`\(k\^\(\(\ \)\(r + 1\)\) - \ 1\)\/\(k\ - \ 1\)\)]], " states where ", Cell[BoxData[ \(TraditionalForm\`k\ = \ \(\(|\)\(\(\[CapitalSigma]\)\(|\)\)\)\)]], ". Minimization with option ", StyleBox["Normalize->1", "MR"], " shows the equivalent states. We sort and rearrange the words so that the \ structure of the equivalence classes becomes more clear. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(mm2 = MinimizeFA[m2, Normalize \[Rule] 2];\)\), "\n", \(\(Q = Reverse /@ \(WordSort /@ States[mm2]\);\)\), "\n", \(ColumnForm[Q]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "It is a good exercise to determine which words/states are equivalent and \ why. What does ", StyleBox["mm2", "MR"], " look like in general? What is the size of the minimal automaton?\nYet \ another way to construct a FSM for ", Cell[BoxData[ \(TraditionalForm\`L(b, \(-3\))\)]], " uses the idea of a local-universal machine, see the discussion below. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(ini = #1 === "\" &;\)\), "\n", \(\(fin = StringMatchQ[#1, "\"] &;\)\), "\n", \(m3 = LocalUniversalFA[3, 3, IniLU \[Rule] ini, FinLU \[Rule] fin, Normalize \[Rule] 1]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \({EquivalentQFA[m1, m2], EquivalentQFA[m1, m3]}\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Note that deterministic simulation of the original machine ", StyleBox["m1", "MR"], " causes an exponential blowup in size. The resulting machine turns out to \ be minimal. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m11 = ToDFA[m1]\), "\n", \(Size[MinimizeFA[m2]]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Factors", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:32"], Cell[TextData[{ "There are natural machines for all factors (prefixes, suffixes) of a fixed \ word ", Cell[BoxData[ \(TraditionalForm\`w\)]], " based on a back-bone of transitions labeled by the letters of ", Cell[BoxData[ \(TraditionalForm\`w\)]], ". The proper choice of initial and final states produces the required \ machines." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(w\ = \ RandomWord[\ 5, {a, b}];\)\), "\[IndentingNewLine]", \(WordToFA[w]\), "\[IndentingNewLine]", \(WordToFA[w, Type \[Rule] "\"]\), "\[IndentingNewLine]", \(ms\ = \ WordToFA[w, Type \[Rule] "\"]\)}], "Input"], Cell[BoxData[{ \(WordSuffixes[w]\), "\[IndentingNewLine]", \(LanguageFA[\ ms, \ Full \[Rule] True\ ]\)}], "Input"], Cell[TextData[{ "Likewise, there are natural machines for languages of the form ", Cell[BoxData[ \(TraditionalForm\`w\ \ \(\[CapitalSigma]\^*\)\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\(\(\ \)\(\(\[CapitalSigma]\^*\)\ w\ \ \(\ \[CapitalSigma]\^*\)\)\)\)]], " and ", Cell[BoxData[ \(TraditionalForm\`\(\(\ \)\(\(\[CapitalSigma]\^*\)\ w\)\)\)]], " based on a similar back-bone plus some additional loops." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(w\ = \ RandomWord[\ 5, {a, b}];\)\), "\[IndentingNewLine]", \(WordToFA[w, Full \[Rule] True]\), "\[IndentingNewLine]", \(WordToFA[w, Full \[Rule] \(TruemType \[Rule] "\"\)]\), \ "\[IndentingNewLine]", \(ms\ = \ WordToFA[w, Full \[Rule] True, Type \[Rule] "\"]\)}], "Input"], Cell["\<\ The growth function of the language of, say, the suffix automaton \ behaves as expected.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[\ ms, \ \(-12\), SizeOnly \[Rule] True\ ]\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["String Searching and the KMP Algorithm", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:33"], Cell[TextData[{ "A task frequently encountered in many applications such as word processing \ is to determine all occurrences of a string w (the pattern) in another string \ t (the text). The pattern w is usually much shorter than the text. The brute \ force approach to the problem takes ", Cell[BoxData[ \(TraditionalForm\`O(nm)\)]], " steps where n is the length of the text and m is the length of the \ pattern. There are numerous algorithms that tackle the string searching \ problem and result in running times of ", Cell[BoxData[ \(TraditionalForm\`O(n + m)\)]], " or better, at least on average. One of these algorithms due to Knuth, \ Morris and Pratt can be described nicely in terms of finite state machines \ and is explained below. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[CellGroupData[{ Cell[" The Morris-Pratt Algorithm", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:34"], Cell[TextData[{ "A simplified version of the string searching problem is to determine \ whether some prefix of the text t belongs to the language\n\t", Cell[BoxData[ \(TraditionalForm\`L\ = \ \(\[CapitalSigma]\^*\)\ w\)]], "\nwhere w is the pattern. There are many ways to generate a \ nondeterministic finite state machine for all words ending in a fixed suffix \ ", Cell[BoxData[ \(TraditionalForm\`w\)]], ". For example, we can tinker with the BEFA for ", Cell[BoxData[ \(TraditionalForm\`w\)]], ":" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(w = ababbaab\), "\n", \(m0 = BuildBEFA[w]\), "\n", \(\(PrependTo[ m0\[LeftDoubleBracket]2\[RightDoubleBracket], {1, 1, 1}];\)\), "\n", \(\(PrependTo[ m0\[LeftDoubleBracket]2\[RightDoubleBracket], {1, 2, 1}];\)\), "\n", \(m0 = ToFA[m0, {a, b}]\), "\n", \(LanguageFA[m0, \(-10\)]\ // ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Minimizing this machine does not cause exponential blow-up, in fact the \ minimal automaton has the same size as ", StyleBox["m0.", "MR"] }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m1 = MinimizeFA[m0]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Why? We can construe the ", Cell[BoxData[ \(TraditionalForm\`\(\(|\)\(w\)\(|\)\(+1\)\)\)]], " states of the FA as the prefixes of ", Cell[BoxData[ \(TraditionalForm\`w\)]], ". Thus, the states of the deterministic simulation machine are sets of \ prefixes. To see which sets occur let us construct the power set machine with \ option ", StyleBox["Normalize->2", FontFamily->"Courier"], ". First, we have to insert the structured state set into ", StyleBox["m0", "MR"], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(P = WordPrefixes[w];\)\), "\n", \(\(P0 = Drop[P, 1];\)\), "\n", \(\(SetStates[\ m0, \ P];\)\), "\n", \(mm = ToDFA[m0, Normalize \[Rule] 2]\), "\n", \(States[mm]\ \ // ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "We can now trace a computation of ", StyleBox["mm", "MR"], " on some input to see how the machine works. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(AcceptQFA[mm, w, DoTrace \[Rule] True] // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell["Here is a better example. ", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(u = Concatenate[aabbababba, w]\), "\n", \(AcceptQFA[mm, u, DoTrace \[Rule] True] // \ ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(\(PlotComputationFA[mm, u];\)\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "With a little meditation one can see that these sets ", Cell[BoxData[ \(TraditionalForm\`S\)]], " consist of maximal suffixes of the input that are prefixes of ", Cell[BoxData[ \(TraditionalForm\`w\)]], ". More precisely, they all have the form\n", StyleBox["\t", FontFamily->"Courier"], Cell[BoxData[ \(TraditionalForm\`S = {\ \ \(f\^\(\(\ \)\(i\)\)\)(p)\ \ | \ i = 0, \[Ellipsis], s}\)]], StyleBox[".", FontFamily->"Courier"], "\nHere ", Cell[BoxData[ \(TraditionalForm\`p\)]], " is the longest word in ", Cell[BoxData[ \(TraditionalForm\`S\)]], " and the failure function ", Cell[BoxData[ \(TraditionalForm\`f\ : \ \(\(P\ \[LongRightArrow]\ P\)\(\ \)\)\)]], "is defined as follows: \n\t", Cell[BoxData[ \(TraditionalForm\`f(\[Epsilon])\ \ = \ \ \[Epsilon]\)]], ",\n\t", Cell[BoxData[ \(TraditionalForm\`f( x)\ \ = \ \ longest\ proper\ suffix\ u\ of\ x\ such\ that\ u\ \ \[Element] \ P\)]], "\t\t\t\nIt is straightforward to compute this failure function. Note, \ though, that the definition of fail given below hinges on the fact that the \ command ", StyleBox["Suffixes", "MR"], " orders its output in increasing length. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(Clear[assign, fail];\)\), "\n", \(\(assign[x_] := \[IndentingNewLine]Scan[ If[MemberQ[P, #1], fail[x] = #1] &, Drop[WordSuffixes[x], \(-1\)]];\)\), "\n", \(\(Scan[assign, P];\)\), "\n", \(\(fail[Eps | "\"] = "\";\)\), "\n", \(Information[fail]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "We need to iterate ", StyleBox["fail", "MR"], ". The following function traces repeated application of ", StyleBox["fail", FontFamily->"Courier"], ". Applying it to ", Cell[BoxData[ \(TraditionalForm\`\(\(P\)\(\ \)\)\)]], " we obtain the set of states of the power set machine." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(iterfail[x_] := Reverse[Drop[FixedPointList[fail, x], \(-1\)]];\)\), "\n", \(\(Q = iterfail /@ P;\)\), "\n", \(Q\ // \ TableForm\), "\n", \(Q === States[mm]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "We can now define the transition function of the minimal automaton in \ terms of the failure function. It is convenient to use the following function \ ", StyleBox["next", FontFamily->"Courier"], ":\n\t", Cell[BoxData[ \(TraditionalForm\`next[\(w\_1\) \[Ellipsis]w\_i] = w\_\(i + 1\)\)]], "\n(think of ", Cell[BoxData[ \(TraditionalForm\`next[w]\)]], " as some symbol not in ", Cell[BoxData[ \(TraditionalForm\`w\)]], ")." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(Clear[next, delta];\)\), "\n", \(\(next[ p_] := \(next[p] = \[IndentingNewLine]If[ WordLength[p] \[Equal] WordLength[w], \(-1\), {a, b}\[LeftDoubleBracket]\(ToIndex[w]\)\[LeftDoubleBracket] WordLength[p] + 1\[RightDoubleBracket]\[RightDoubleBracket]]\);\)\), "\n", \(\(delta[p_, s_] := \(delta[p, s] = \[IndentingNewLine]If[s === next[p], Concatenate[p, s], If[p === "\", "\", delta[fail[p], s]]]\);\)\)}], "Input", AspectRatioFixed->True], Cell["next /@ P", "Input", AspectRatioFixed->True], Cell["\<\ Applying this function to all state-symbol combinations we obtain \ the transition matrix of the deterministic machine. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(grid = CartesianProduct[P, {a, b}];\)\), "\n", \(B = Partition[\((delta[#1\[LeftDoubleBracket]1\[RightDoubleBracket], #1\ \[LeftDoubleBracket]2\[RightDoubleBracket]] &)\) /@ grid, 2]\), "\n", \(\(BB = B /. \[InvisibleSpace]RankingRules[P];\)\), "\n", \(mm = \ DFA[9, 2, \ Transpose[BB]\ , \ 1\ , \ {9}\ ]\)}], "Input", AspectRatioFixed->True], Cell["IsomorphicQDFA[mm,m1]", "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[" Knuth's Improvement", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:35"], Cell[TextData[{ "Note that for applications of the string matching algorithm the crucial \ point is to implement the finite state machine rapidly. There is no need to \ actually construct the minimal automaton (i.e., compute the transition table \ as we have just done), it is enough to be able to compute the next state on \ the fly using the ", StyleBox["fail", FontFamily->"Courier"], " function. Note that the table size of the full transition function is ", Cell[BoxData[ \(TraditionalForm\`\((\(|\)\(w\)\(|\)\(+1\))\) | \[CapitalSigma] | \ \)]], ", whereas the table for the failure function only has size ", Cell[BoxData[ \(TraditionalForm\`\(\(|\)\(w\)\(|\)\(+1\)\)\)]], ". \nAn improved version of the algorithm that speeds up this computation \ is due to Knuth. It uses a slightly modified failure function defined as \ follows: \t\n\t", Cell[BoxData[ \(TraditionalForm\`newfail[p]\ = \ longest\ proper\ suffix\ q\ of\ p\ in\ P\ such\ that\ \ next[ p]\ \[NotEqual] \ next[q]\)]], ".\nIf no such q exists set ", Cell[BoxData[ \(TraditionalForm\`newfail[p]\ = \ \[Epsilon]\)]], " (reset to initial state). We compare the two failure functions." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(newfail["\"] = "\";\)\), "\n", \(\(newfail[ p_] := \(newfail[p] = \[IndentingNewLine]If[ next[p] === next[fail[p]], newfail[fail[p]], fail[p]]\);\)\), "\n", \(\({Range[0, 8], P, fail /@ P, newfail /@ P}\ \ // Thread\) // TableForm\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Note that the modified failure function resets immediately from state 7 \ under input a to state 0. The old function would first go to state 1, find \ another mismatch there and then reset to 0 in the second step. \nBoth failure \ functions can be computed efficiently (in a suitable programming language \ like C) in ", Cell[BoxData[ \(TraditionalForm\`O(m)\)]], " steps. Note, though, that there are some subtle problems in getting a \ correct implementation." }], "Text", Evaluatable->False, AspectRatioFixed->True] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["n-Local Universal Automata", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Local universal", "c:37"}], Cell[TextData[{ "The ", StyleBox["n-local universal automaton", FontSlant->"Italic"], " over alphabet ", Cell[BoxData[ \(TraditionalForm\`\[CapitalSigma]\)]], " has states tuples ", Cell[BoxData[ \(TraditionalForm\`\((a\_1, \[Ellipsis], a\_n)\)\ \[Element] \ \[CapitalSigma]\^n\)]], " and transitions\n\t", Cell[BoxData[ \(TraditionalForm\`\((a\_1, \[Ellipsis], a\_n)\)\[CenterDot]\ b\ = \ \((a\_2, \[Ellipsis], a\_\(n - 1\), b)\)\)]], ".\nThus, the machine remembers the last ", Cell[BoxData[ \(TraditionalForm\`n\)]], " symbols of the input string. One may think of these machines as sliding a \ window of length ", Cell[BoxData[ \(TraditionalForm\`n + 1\)]], " across the input word. At every position the visible string is checked \ against some list of permissible patterns. A word is accepted if it passes \ all these local tests. \nOn the other hand, one can think of the ", Cell[BoxData[ \(TraditionalForm\`n\)]], "-local universal automaton as a labeled de Bruijn graph over the alphabet \ \[CapitalSigma]. De Bruijn graphs (or rather, their edge-lists) can be \ generated by the command ", ButtonBox["DeBruijnEdges", ButtonStyle->"AddOnsLink"], ". Option ", StyleBox["Normalize", FontFamily->"Courier"], " has default ", StyleBox["False", FontFamily->"Courier"], ", which causes the vertex structure to be preserved. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(DeBruijnEdges[3, 2]\ // ColumnForm\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Locally testable languages are closely related to local universal \ machines: by tracing a computation of an input word on such a machine we can \ solve the recognition problem for the language. For an algebraic \ characterization in terms of the corresponding variety of syntactic \ semigroups see the previous section. \nThe command ", ButtonBox["LocalUniversalFA", ButtonStyle->"AddOnsLink"], StyleBox["[n,K]", FontFamily->"Courier"], " constructs a n-local universal machine over alphabet K. It has options \ ", StyleBox["IniLU", FontFamily->"Courier"], ", ", StyleBox["FinLU", FontFamily->"Courier"], " and ", StyleBox["EdgeLU ", FontFamily->"Courier"], "that determine the initial and final states and the permissible \ transitions. You can replace ", StyleBox["EdgeLU", FontFamily->"Courier"], ", ", StyleBox["IniLU", FontFamily->"Courier"], " and ", StyleBox["FinLU", FontFamily->"Courier"], " by functions on words of length ", Cell[BoxData[ \(TraditionalForm\`n + 1\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\(\(n\)\(,\)\)\)]], " and ", Cell[BoxData[ \(TraditionalForm\`n\)]], ", respectively that return a Boolean result." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(\(LocalUniversalFA // Options\) // TableForm\)], "Input", AspectRatioFixed->True], Cell[CellGroupData[{ Cell["Example 1", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:38"], Cell[TextData[{ "As an example, we construct an automaton based on a 3-local universal \ machine that accepts: \n\t", Cell[BoxData[ \(TraditionalForm\`L\ = \ \(all\ strings\ over\ \[CapitalSigma]\ = \ \ {a, b}\ \ containing\ neither\ \ aaa\ \ nor\ \ bbb\)\)]], ".\nSince ", Cell[BoxData[ \(TraditionalForm\`L\ = \ \(\[CapitalSigma]\^*\)\ \ - \ \ \(\(\ \[CapitalSigma]\^*\)\(\ \)\({aaa, bbb}\) \(\[CapitalSigma]\^*\)\(\ \)\)\)]], " , this language must be locally testable. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(infix = #1 =!= "\" && #1 =!= "\" &;\)\), "\n", \(\(m = LocalUniversalFA[2, {a, b}, EdgeLU \[Rule] infix, Normalize \[Rule] 1];\)\), "\n", \(PrintFA[m, LongForm \[Rule] True]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Machine ", StyleBox["m", "MR"], " is deterministic but not complete:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(DegreesFA[m]\ // TableForm\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(m1 = MinimizeFA[m]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(L = LanguageFA[m1, \(-5\)];\)\), "\n", \(L // ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(Complement[Words[4], L\[LeftDoubleBracket]5\[RightDoubleBracket]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The syntactic homomorphism shows that ", Cell[BoxData[ FormBox[ StyleBox["aaa", FontSlant->"Italic"], TraditionalForm]]], " and ", Cell[BoxData[ FormBox[ StyleBox["bbb", FontSlant->"Italic"], TraditionalForm]]], " lead to the null element in the syntactic semigroup, see ", ButtonBox["SyntacticHomomorphism", ButtonStyle->"AddOnsLink"], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m1\)], "Input"], Cell[BoxData[ \(SyntacticHomomorphism[f, m1]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(f[a]\^Range[0, 3]\ // TableForm\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(f[b]\^Range[0, 3] // TableForm\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "We compute the syntactic semigroup ", Cell[BoxData[ \(TraditionalForm\`S\)]], " of ", Cell[BoxData[ \(TraditionalForm\`L\)]], " and verify that ", Cell[BoxData[ \(TraditionalForm\`S\)]], " is aperiodic. Since ", Cell[BoxData[ \(TraditionalForm\`L\)]], " is locally testable, ", Cell[BoxData[ \(TraditionalForm\`S\)]], " must be locally idempotent and locally commutative. We verify these \ properties using simple test routines defined above. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(S = SyntacticSG[m1]\)], "Input", AspectRatioFixed->True], Cell["\<\ S contains 11 idempotents and is duly locally idempotent, locally \ commutative and aperiodic:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(IdemSG[S]\ // Length\), "\n", \(LocallyIdempotentQSG[S]\), "\n", \(LocallyCommutativeQSG[S]\), "\n", \(AperiodicQSG[S]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Example 2", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:39"], Cell[TextData[{ "Here is a slightly more complicated example. Consider the language ", Cell[BoxData[ \(TraditionalForm\`L\)]], " of all strings over ", Cell[BoxData[ \(TraditionalForm\`{0, 1}\)]], " \n\t- containing no block of length 5 with more than three 1's, and\n\t- \ containing a block 111. \nAgain, ", Cell[BoxData[ \(TraditionalForm\`L\)]], " is locally testable. We first build a 4-local universal automaton that \ checks blocks of length 5. To test for the existence of a block '111' we make \ a second copy of the machine and perform a little surgery. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(goodblock = Plus @@ \(ToExpression /@ ToCharacters[#1]\) < 4 &;\)\), "\n", \(\(m0 = LocalUniversalFA[4, \(-2\), EdgeLU \[Rule] goodblock, Normalize \[Rule] 1];\)\), "\n", \(PrintFA[m0, Full \[Rule] True, TransOnly \[Rule] True]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Now for the surgery:\n\[Bullet] Let ", Cell[BoxData[ \(TraditionalForm\`m\_1\)]], " be the disjoint sum of ", Cell[BoxData[ \(TraditionalForm\`m\_0\)]], " with itself, say, with states of the form ", Cell[BoxData[ \(TraditionalForm\`{i, p}\)]], " where ", Cell[BoxData[ \(TraditionalForm\`i = 1, 2\)]], " and ", Cell[BoxData[ \(TraditionalForm\`p\)]], " is a state in ", Cell[BoxData[ \(TraditionalForm\`m\_0\)]], ". \n\[Bullet] Add a transition ", Cell[BoxData[ \(TraditionalForm\`\((\ {1, 0011}, \ 1, \ {2, 0111}\ )\)\)]], ". Make sure you understand why no other transitions are needed. \n\ \[Bullet] Lastly, set the initial state to ", Cell[BoxData[ \(TraditionalForm\`{1, 0000}\)]], " and select as final states all states of the form ", Cell[BoxData[ \(TraditionalForm\`{2, _}\)]], ". " }], "Text"], Cell[BoxData[ \(m1 = SumFA[m0, m0, Normalize \[Rule] 1]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(Q = States[m1];\)\), "\n", \(s0 = \(Position[Q, {1, "\<0000\>"}]\)\[LeftDoubleBracket]1, 1\[RightDoubleBracket]\), "\n", \(s1 = \(Position[Q, {1, "\<0011\>"}]\)\[LeftDoubleBracket]1, 1\[RightDoubleBracket]\), "\n", \(t = \(Position[Q, {2, "\<0111\>"}]\)\[LeftDoubleBracket]1, 1\[RightDoubleBracket]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(m2 = AddTransitionFA[m1, s1, 2, t]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(PositionList[Q, Cases[Q, {2, _}]]\)], "Input"], Cell["m = SetInitialFinalFA[ m2, {s0}, % ]", "Input", AspectRatioFixed->True], Cell["We minimize the automaton and check that it works:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(mm = MinimizeFA[m];\)\), "\n", \(Size[mm]\), "\n", \(\(L = LanguageFA[mm, 10];\)\), "\n", \(Length[L]\), "\n", \(L\)}], "Input", AspectRatioFixed->True], Cell["\<\ The syntactic semigroup has size 173 and has all the right \ properties.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(S = SyntacticSG[mm];\)\), "\n", \(Length[S]\), "\n", \(Length[IdemSG[S]]\), "\n", \(AperiodicQSG[S]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Testing local commutativity/idempotence will take a bit to \ verify,since there are lots of idempotents and the algorithm used is rather \ primitive.\ \>", "Text"], Cell["\<\ LocallyIdempotentQSG[S] LocallyCommutativeQSG[S]\ \>", "Input", AspectRatioFixed->True], Cell["\<\ Of course, we could also build a suitable automaton using some \ standard constructors and boolean operations. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(mgood = MinimizeFA[WordToFA["\<111\>", \(-2\), Full \[Rule] True]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(weight[w_] := Plus @@ \((ToIndex[w, \(-2\)] - 1)\)\), "\n", \(W = Select[Words[5, \(-2\)], weight[#1] > 3 &]\), "\n", \(mbad = ComplementFA[ MinimizeFA[ ConcatenateFA[AllDFA[\(-2\)], BuildDFA[W, \(-2\)], AllDFA[\(-2\)]]]]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(mmm = MinimizeFA[IntersectionFA[mgood, mbad]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(IsomorphicQDFA[mm, mmm]\)], "Input"], Cell[TextData[{ "Trouble! Something went wrong: machines ", StyleBox["mm", "MR"], " and ", StyleBox["mmm", "MR"], " should be isomorphic. Let's take a look at the languages to see which \ machine is correct (if any)." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(L1 = Flatten[LanguageFA[mm, \(-10\)]];\)\), "\n", \(L1\ // \ Length\), "\n", \(\(L2 = Flatten[LanguageFA[mmm, \(-10\)]];\)\), "\n", \(L2\ // \ Length\)}], "Input", AspectRatioFixed->True], Cell["It seems that the languages differ in only one word. ", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Complement[L2, L1]\)], "Input", AspectRatioFixed->True], Cell["\<\ We forgot word 1111 in the first machine! Let's add it on \ now.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(mmnew = MinimizeFA[UnionFA[mm, BuildDFA["\<1111\>", \(-2\)]]]\)], "Input", AspectRatioFixed->True], Cell["Now the machines should be isomorphic:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell["IsomorphicQDFA[mmnew,mmm]", "Input", AspectRatioFixed->True] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Ideals and their Bases", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:40"], Cell[TextData[{ "A language ", Cell[BoxData[ \(TraditionalForm\`L\ \[SubsetEqual] \ \(\[CapitalSigma]\^*\)\)]], " is a (two-sided) ", StyleBox["ideal", FontColor->RGBColor[0, 0, 1]], " if ", Cell[BoxData[ \(TraditionalForm\`\(\[CapitalSigma]\^*\) L\ \ \(\[CapitalSigma]\^*\) \[SubsetEqual] L\)]], ". If ", Cell[BoxData[ \(TraditionalForm\`L\)]], " is given by a finite state machine we can easily test whether ", Cell[BoxData[ \(TraditionalForm\`L\)]], " is an ideal (see the sections on closure properties and decision \ algorithms). " }], "Text"], Cell[BoxData[{ \(\(m = DFA[11, 2, {{2, 4, 5, 4, 4, 5, 9, 10, 9, 11, 4}, {3, 3, 3, 6, 7, 8, 3, 3, 9, 7, 9}}, 1, {9}];\)\), "\n", \(\(all = AllDFA[2];\)\), "\n", \(id = ConcatenateFA[all, m, all]\), "\n", \(SubsetQFA[id, m]\)}], "Input"], Cell[TextData[{ "More interesting is the question of identifying a ", StyleBox["base", FontColor->RGBColor[0, 0, 1]], " for the ideal. By base we mean a subset ", Cell[BoxData[ \(TraditionalForm\`L\_0 \[SubsetEqual] \ L\)]], " such that ", Cell[BoxData[ \(TraditionalForm\`\(\[CapitalSigma]\^*\) L\_0\ \ \(\[CapitalSigma]\^*\) = L\)]], " but no word in ", Cell[BoxData[ \(TraditionalForm\`L\_0\)]], " is a factor of any other words in ", Cell[BoxData[ \(TraditionalForm\`L\_0\)]], ". Note that a base always exists and is uniquely determined by ", Cell[BoxData[ \(TraditionalForm\`L\)]], ". Moreover, the base is regular whenever ", Cell[BoxData[ \(TraditionalForm\`L\)]], " is. \nHere is an attempt to construct the base by hand. " }], "Text"], Cell[BoxData[ \(LanguageFA[m, \(-6\)]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Perhaps ", Cell[BoxData[ FormBox[ RowBox[{\(L\_0\), "=", " ", RowBox[{"{", StyleBox["baba", FontSlant->"Italic"], "}"}]}], TraditionalForm]]], " will do." }], "Text"], Cell[BoxData[ \(m1 = MinimizeFA[ ComplementFA[m, WordToFA[baba, 2, Full \[Rule] True]]]\)], "Input"], Cell["Unfortunately, not. We need to add another word.", "Text"], Cell[BoxData[ \(LanguageFA[m1, \(-8\)]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Try ", Cell[BoxData[ FormBox[ RowBox[{\(L\_0\), "=", " ", RowBox[{"{", StyleBox[\(baba, aabbaab\), FontSlant->"Italic"], "}"}]}], TraditionalForm]]], " ." }], "Text"], Cell[BoxData[ \(m2 = MinimizeFA[ ComplementFA[m1, WordToFA[aabbaab, 2, Full \[Rule] True]]]\)], "Input"], Cell["\<\ This time we have a complete base. Note, though, that in general \ the base may well fail to be finite, and the process of adding yet another \ word will go on indefinitely. The language accepted by following machine \ (which is almost identical to our first example) is an ideal, but its base is \ infinite. \ \>", "Text"], Cell[BoxData[{ \(\(m = DFA[11, 2, {{2, 4, 5, 4, 4, 5, 9, 10, 9, 11, 4}, {3, 3, 3, 6, 7, 8, 6, 6, 9, 7, 9}}, 1, {9}];\)\), "\n", \(IdealQFA[m]\)}], "Input"], Cell["\<\ Nonetheless, we can construct a machine for it directly, without \ going to our approximation process.\ \>", "Text"], Cell[BoxData[ \(mm = IdealBaseFA[m]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "We verify that the machine produced by ", ButtonBox["IdealBaseFA", ButtonStyle->"AddOnsLink"], " works as advertised." }], "Text"], Cell[BoxData[ \(mmm = MinimizeFA[ConcatenateFA[AllDFA[2], mm, AllDFA[2]]]\)], "Input"], Cell[BoxData[ \(IsomorphicQDFA[mmm, m]\)], "Input"], Cell[BoxData[ \(m === mmm\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Frontier Automata", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:24"], Cell[TextData[{ "Let M be some accessible DFA over a k-symbol alphabet. We can unfold ", Cell[BoxData[ \(TraditionalForm\`M\)]], " into a k-ary tree whose nodes are sequences in ", Cell[BoxData[ \(TraditionalForm\`\([k]\)\)]], ". The nodes can be labeled by the states of ", Cell[BoxData[ \(TraditionalForm\`M\)]], ": node ", Cell[BoxData[ \(TraditionalForm\`x\)]], " is labeled ", Cell[BoxData[ \(TraditionalForm\`\[Delta](q\_0, x)\)]], " (we identify ", Cell[BoxData[ \(TraditionalForm\`x\)]], " with the corresponding sequence of symbols in the underlying alphabet). \ By truncating the tree at all nodes that are labeled by a state that already \ occurs at a previous node (with respect to the tree ordering defined above) \ we obtain a finite tree, the transition tree of ", Cell[BoxData[ \(TraditionalForm\`M\)]], ". \n", Cell[BoxData[ \(TraditionalForm\`M\)]], " can now be represented as follows: Let fr be the frontier of the \ transition tree and ", Cell[BoxData[ \(TraditionalForm\`I\)]], " its interior nodes (all prefixes of frontier nodes). Define a function \ ", Cell[BoxData[ \(TraditionalForm\`\[CapitalGamma]\ : \ fr\ \[LongRightArrow]\ Int\)]], " from the frontier to the interior of the tree that maps node ", Cell[BoxData[ \(TraditionalForm\`x\)]], " to the predecessor node ", Cell[BoxData[ \(TraditionalForm\`y\)]], " such that ", Cell[BoxData[ \(TraditionalForm\`\[Delta](q\_0, x) = \[Delta](q\_0, y)\)]], ". Then ", Cell[BoxData[ \(TraditionalForm\`\[CapitalGamma]\)]], " together with the nodes ", Cell[BoxData[ \(TraditionalForm\`F\)]], " corresponding to final states in ", Cell[BoxData[ \(TraditionalForm\`M\)]], " completely determine ", Cell[BoxData[ \(TraditionalForm\`M\)]], ". We refer to the pair ", Cell[BoxData[ \(TraditionalForm\`\((\[CapitalGamma], F)\)\)]], " as the ", StyleBox["frontier automaton", FontColor->RGBColor[0, 0, 1]], " associated to ", Cell[BoxData[ \(TraditionalForm\`M\)]], ". \nHere is an example. The command ", ButtonBox["ToFrontierDFA", ButtonStyle->"AddOnsLink"], StyleBox[" ", FontFamily->"Courier"], "returns the frontier automaton. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m = IthSymbolFA[b, \(-2\), {a, b}, Full \[Rule] True];\)\), "\n", \(\({\[CapitalGamma], F} = ToFrontierDFA[m];\)\), "\n", \(\[CapitalGamma]\ // PrintEquations\), "\n", \(F\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The frontier of the unfolding of ", Cell[BoxData[ \(TraditionalForm\`m\)]], " consists of all words of length 3: " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(front = First /@ \[CapitalGamma]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "One can also construct a frontier automaton where ", Cell[BoxData[ \(TraditionalForm\`\[CapitalGamma](x)\)]], " is always a prefix of ", Cell[BoxData[ \(TraditionalForm\`x\)]], ", so that the next state is either a node immediately above the current \ one or lies somewhere on the branch below the current node. Needless to say, \ this machine will in general be larger than the canonical frontier automaton. \ " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\({\[CapitalGamma], F} = ToFrontierDFA[m, Periodic \[Rule] True];\)\), "\n", \(\[CapitalGamma]\ \ // PrintEquations\), "\n", \(F\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Conversely we can convert a frontier automaton into a DFA. It is a good \ idea to verify first that the domain of the function ", Cell[BoxData[ \(TraditionalForm\`\[CapitalGamma]\)]], " is in fact a frontier. Below we concoct \[CapitalGamma] for a machine \ recognizing all strings with an even number of a's and b's. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(\[CapitalGamma] = {{aa, Eps}, {bb, Eps}, {baa, b}, {bab, a}, {aba, b}, {abb, a}};\)\), "\n", \(FrontierQ[First /@ \[CapitalGamma], {a, b}]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(m1 = FrontierToDFA[\[CapitalGamma], {Eps}]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[m1, \(-4\)]\ // ColumnForm\)], "Input", AspectRatioFixed->True], Cell["\<\ Seems to work. Our frontier automaton is somewhat clumsy. Here is a \ more elegant solution.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m2 = MinimizeFA[m1];\)\), "\n", \(\({G, F} = ToFrontierDFA[m2];\)\), "\n", \(\[CapitalGamma]\ // PrintEquations\), "\n", \(F\)}], "Input", AspectRatioFixed->True], Cell["\<\ Compare this to the defining equations of the syntactic \ monoid.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(eq = SimplifyEquations @@ SyntacticSG[m2, Equations \[Rule] True];\)\), "\n", \(PrintEquations[eq]\)}], "Input", AspectRatioFixed->True] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Regular Expressions", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->{"Regular expressions", "c:2"}], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Representation\ of\ Regular\ Expressions\)], \ "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:3"], Cell["\<\ Regular expressions are a notation system for regular languages: \ for every regular language there is a regular expression that denotes it (in \ fact, there are infinitely many). Unlike finites state machines, regular \ expressions are concise and can be easily written out by a human being. More \ importantly, they can also be typed on a commandline, and thus can be used \ easily as input to programs. Hence, regular expressions have become a \ standard tool to describe patterns of strings in such programs as editors or \ search algorithms. The next section describes regular expressions in \ automata. For applications, the most important feature of regular \ expressions is that there are fast algorithms to convert them to \ corresponding finite state machines. We will present two such algorithms. \ \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "Regular expressions describe languages composed of trivial basic \ components such as single characters using the operations of union, \ concatenation and Kleene (repetition). In automata, they are represented \ using special constructors:\n\t", ButtonBox["REP", ButtonStyle->"AddOnsLink"], "\t\tfor plus, union, \n\t", ButtonBox["RET", ButtonStyle->"AddOnsLink"], "\t\tfor times, concatenation, and\n\t", ButtonBox["RES", ButtonStyle->"AddOnsLink"], "\t\tfor Kleene star (repetition).\n", StyleBox["RES", "MR"], " is unary, ", StyleBox["REP", "MR"], " and ", StyleBox["RET", "MR"], " are polyadic. Also, ", StyleBox["Empty", "MR"], " stands for the empty set and ", StyleBox["Eps", "MR"], " for ", Cell[BoxData[ \(TraditionalForm\`{\[Epsilon]}\)]], ". Symbol ", Cell[BoxData[ \(TraditionalForm\`s\)]], " denotes the singleton language ", Cell[BoxData[ \(TraditionalForm\`{s}\)]], ". Thus, regular expressions are defined by the following context free \ grammar (cum grano salis):\n\t", Cell[BoxData[ \(TraditionalForm\`E\ \[Rule] \ Empty\ \ | \ \ Eps\ \ | \ \ symbol\)]], "\n\t", Cell[BoxData[ \(TraditionalForm\`E\ \[Rule] \ \ REP[\ E, \[Ellipsis], E]\ \ | \ \ RET[\ E, \[Ellipsis], E]\ \ \ | \ \ RES[E]\)]], ".\nThis notation is a bit pedantic, but easy to parse. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(re = REP[Eps, RET[RES[REP[a, b], b]]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "One of the major obstacles in dealing with regular expressions is the lack \ of a good normal form. For example, the next expression clearly could be \ simplified. A collection of simplification rules is available under the name \ ", ButtonBox["$regexrules", ButtonStyle->"AddOnsLink"], ". Since there is no finite basis for the equations of the corresponding \ closed semiring the collection is by necessity lacking. The user should feel \ free to augment it. \nHere are some simple examples where the simplification \ rules work properly." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \({\ REP[\ ab, \ Empty, \ ab\ ], REP[\ ab, \ Eps, \ ab\ ], RET[\ ab, \ Empty, \ ab\ ], RET[\ ab, \ Eps, \ ab\ ]\ } //. \[InvisibleSpace]$regexrules\)], "Input"], Cell[BoxData[ \(REP[\ \[Epsilon]\ , \ aa, \ RES[aa]]\ //. \[InvisibleSpace]$regexrules\)], "Input"], Cell[CellGroupData[{ Cell["Pseudo-Algebraic Notation", "Subsubsection"], Cell[TextData[{ "To facilitate the input of regular expressions, the user can write these \ expressions also in algebraic notation, very much like ordinary arithmetic. \ The symbols of the underlying alphabet are variables and operators are ", StyleBox["Plus", "MR"], ", ", StyleBox["NonCommutativeMultiply", "MR"], " and ", StyleBox["RES", "MR"], ". For example, we can write \n\t", StyleBox["a ** RES[a+b] ** bb", "MR"], "\t instead of\t", StyleBox["RET[a,RES[REP[a,b]],b,b]", "MR"], ". \nThe command ", ButtonBox["ToRegExp", ButtonStyle->"AddOnsLink"], " transforms such a term into a proper regular expression." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(re = Eps + RES[a + b] ** b\), "\n", \(ToRegExp[re]\)}], "Input", AspectRatioFixed->True], Cell["\<\ At present there are no facilities to parse a standard Unix style \ regular expression. Takers, anywhere?\ \>", "Text"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Conversion of Regular Expressions to FSMs", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:4"], Cell[TextData[{ "For the conversion of regular expressions to finite state machines it is \ best to use a special normal form finite state machine. The normal form \ should make it easy to perform the operations union, concatenation and star. \ There are two normal forms implemented in automata: Thompson style begin/exit \ automata and McNaughton-Yamada style normalized NFAs (or rather, their \ tails). We discuss both types below. \nA begin-exit FA (or BEFA) is a finite \ automaton that has exactly one initial and one final state. Also, the \ initial state has indegree zero and the final state has outdegree zero (in \ the transition diagram of the automaton). This makes it easy to compute \ union, concatenation and star of BEFAs. In this package, a BEFA is described \ by an expression of the form \t\n\t\t", StyleBox["BEFA[n,T]", "MR"], ".\nAlternatively one can use tails of normalized NFAs. A normalized NFA \ (NNFA) has exactly one initial state of indegree 0 and all transitions \ leading to the same state carry the same label. There are no epsilon \ transitions. It is easy to see that such a machine can be reconstructed from \ the following pieces: \n\t- ", Cell[BoxData[ \(TraditionalForm\`Q\ - \ {q\_0}\)]], ", the states other than the initial state,\n\t- the unlabeled edges of \ the transition diagram,\n\t- the labels associated with each vertex other \ than ", Cell[BoxData[ \(TraditionalForm\`q\_0\)]], ",\n\t- the states at distance 1 from ", Cell[BoxData[ \(TraditionalForm\`q\_0\)]], ",\n\t- the final states,\n\t- a bit indicating whether the machine \ accepts \[Epsilon]. \nThese six pieces are the tail of the automaton. Again, \ it is easy to compute union, concatenation and star of tails. In this package \ we use \n\t\t", StyleBox["NNFA[ n, E, L, I, F, e ]", "MR"], "\t\nto denote tails of NNFAs. \nBoth conversion procedures produce a \ finite state machine whose number of states is bounded by 2 times the length \ of the regular expression. The Thompson method produces a machine with \ epsilon moves in linear time. The McNaughton-Yamada algorithm directly \ produces an NFA, however, the number of transitions in the machine may not be \ linear in the length of the regular expression. Indeed, the implementation \ here is not optimized for speed, its main purpose is to show an alternative \ way of converting regular expressions. \nThe procedures ", ButtonBox["BuildBEFA", ButtonStyle->"AddOnsLink"], " constructs a BEFA for the language {w} directly from input w (the \ underlying alphabet is irrelevant here). Similarly, ", ButtonBox["BuildNNFA", ButtonStyle->"AddOnsLink"], " constructs a NNFA." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(BuildBEFA[Eps]\), "\n", \(BuildNNFA[Eps]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(BuildBEFA[abba]\), "\n", \(BuildNNFA[abba]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Note that since BEFAs have no separate field for the underlying \ alphabet, the transition list is given in full form. Also observe that \ conversion of the tail to an NFA to an FA adds one state, so the last two \ machines are really identical.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(ToFA[BuildBEFA[abba], {a, b}] === ToFA[BuildNNFA[abba], {a, b}]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "To convert a regular expression to a BEFA or an NNFA use the commands\t", ButtonBox["RegularExpressionToBEFA", ButtonStyle->"AddOnsLink"], " and ", ButtonBox["RegularExpressionToNNFA", ButtonStyle->"AddOnsLink"], ", respectively. To convert to an FA use ", ButtonBox["RegularExpressionToFA", ButtonStyle->"AddOnsLink"], ". The last command takes as input a regular expression as well as an \ alphabet. There are several options associated with ", ButtonBox["RegularExpressionToFA", ButtonStyle->"AddOnsLink"], " : " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Options[RegularExpressionToFA]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "To obtain a BEFA we have to set ", StyleBox["Thompson->True", "MR"], ", otherwise an NNFA will be produced. If we wish to prevent \ epsilon-elimination we have to set ", StyleBox["EpsElim->False", "MR"], ". The last option ", StyleBox["SizeOnly", "MR"], " causes the size of the resulting FA to be computed without actually \ constructing the machine. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(e = RES[aa + bb];\)\), "\n", \(m1 = RegularExpressionToFA[e, {a, b}]\), "\n", \(m2 = RegularExpressionToFA[e, {a, b}, Thompson \[Rule] True, EpsElim \[Rule] False]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Thus, the NNFA is bigger than the BEFA in this case. A few other \ examples comparing the size of the two alternative automata are given below. \ Of course, the machines are equivalent. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(EquivalentQFA[m1, m2]\)], "Input", AspectRatioFixed->True], Cell["\<\ The trace of EpsilonEliminationFA shows the the epsilon and \ non-epsilon transitions, and the transitive closure of the epsilon \ transitions in m2. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\({mm2, treps, trnoneps, transclos} = EpsilonEliminationFA[m2, DoTrace \[Rule] True];\)\), "\n", \(treps\), "\n", \(trnoneps\), "\n", \(EnumForm[transclos]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell["Simplification of Regular Expressions", "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:4"], Cell[CellGroupData[{ Cell["Rewrite Rules", "Subsubsection"], Cell[TextData[{ "The algebra of regular expressions is a bit complicated (Kleene algebra). \ Apart from obvious rules such as \n\t", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\ + \ \[Alpha]\ \[Rule] \ \[Alpha]\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\ + \ \[EmptySet]\ \[Rule] \ \[Alpha]\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\ \[CenterDot]\ \[EmptySet]\ \[Rule] \ \ \[EmptySet]\)]], ", ", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\ \[CenterDot]\ \[Epsilon]\ \[Rule] \ \ \[Alpha]\)]], "\nand such like there are more complicated laws that make simplification \ very difficult. For example, \n\t", Cell[BoxData[ \(TraditionalForm\`\(\((\[Alpha]\ + \ \[Beta])\)\^*\)\ = \ \(\((\(\ \[Alpha]\^*\) \[Beta]\^\(\(\ \)\(*\)\))\)\^*\)\)]], "\nso on occasion a ", Cell[BoxData[ \(TraditionalForm\`+\)]], " can be eliminated by introducing more ", Cell[BoxData[ \(TraditionalForm\`*\)]], " operators. There is a list of simple rewrite rules ", ButtonBox["$regexrules", ButtonStyle->"AddOnsLink"], " in the package that can be used to perform some modest simplifications of \ regular expressions." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(REP[a, a]\ /. \ $regexrules\)], "Input"], Cell[BoxData[ \(REP[a, Empty]\ /. \ $regexrules\)], "Input"], Cell[BoxData[ \(RET[a, Empty]\ /. \ $regexrules\)], "Input"], Cell[TextData[{ "Computing left quotients of regular expressions can produce very \ complicated expressions, even when the initial expression is quite \ straightforward. Here we remove a prefix ", Cell[BoxData[ FormBox[ StyleBox["abbab", FontSlant->"Italic"], TraditionalForm]]], " from any word over ", Cell[BoxData[ \(TraditionalForm\`{a, b}\)]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(REQuotient[\ abbab, \ RES[REP[a, b]]\ ]\)], "Input"], Cell[TextData[{ "It is not obvious from the expression, but it should be equivalent to ", Cell[BoxData[ \(TraditionalForm\`\(\((a + b)\)\^*\)\)]], ". In this case the simplification rules are strong enough to establish \ this fact." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(%\ // \ RESimplify\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Another Example", "Subsubsection"], Cell[TextData[{ "Here is a regular expression denoting all words of the form ", Cell[BoxData[ \(TraditionalForm\`\[Beta]\ = \ \(\((a + b)\)\^*\) a\ \((a + b)\) \((a + b)\)\)]], "." }], "Text"], Cell[BoxData[{ \(\(all\ = \ REP[a, b];\)\), "\n", \(\[Beta]\ = \ RET[\ RES[all], a, all, all]\)}], "Input"], Cell[TextData[{ "By taking a left quotient with ", Cell[BoxData[ \(TraditionalForm\`a\)]], " we should get ", Cell[BoxData[ \(TraditionalForm\`\[Beta]\ + \ \ \((a + b)\) \((a + b)\)\)]], "." }], "Text"], Cell[BoxData[ \(re\ = \ REQuotient[\ a, \ \[Beta]\ ]\)], "Input"], Cell["\<\ The expression can be simplified to exactly the expected form with \ our rules.\ \>", "Text"], Cell[BoxData[ \(re\ = \ re // \ RESimplify\)], "Input"], Cell["\<\ Here is the corresponding minimal automaton and its growth \ function.\ \>", "Text"], Cell[BoxData[ \(m\ = \ RegularExpressionToFA[re]\ \ // \ MinimizeFA\)], "Input"], Cell[BoxData[ \(LanguageFA[\ m, \ \(-10\), \ SizeOnly \[Rule] True\ \ ]\)], "Input"], Cell["The generating function is fairly simple in this case.", "Text"], Cell[BoxData[ \(GrowthSeriesDFA[m, x]\)], "Input"], Cell["\<\ We can verify that the few values from above describe the general \ pattern.\ \>", "Text"], Cell[BoxData[ \(% === Simplify[ 4\ x\^2 + \[Sum]\+\(i = 3\)\%\[Infinity] 2\^\(i - 1\)\ x\^i]\)], \ "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Examples\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:5"], Cell[CellGroupData[{ Cell["\<\ Example 1: Any two consecutive b's are separated by an even \ number of a's.\ \>", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:6"], Cell["\<\ There is a straightforward regular expression for this \ language:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell["exp = ToRegExp[ RES[a] ** RES[ b ** RES[aa] ] ** RES[a] ]", "Input"], Cell[BoxData[{ \(\(m1 = RegularExpressionToFA[exp, {a, b}];\)\), "\n", \(\(mm1 = MinimizeFA[m1];\)\), "\n", \(m1\), "\n", \(mm1\)}], "Input", AspectRatioFixed->True], Cell["\<\ It is interesting to look at the rewrite system for the syntactic \ semigroup of this language: any even number of a's is equivalent to none, any \ positive number of b's is equivalent to a single b, and certain bad patterns \ must not occur. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\({S, wit, eq} = SyntacticSG[mm1, Equations \[Rule] True];\)\), "\n", \(PrintEquations[eq]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The reductions given by the above equations transform words in L6 (and \ indeed in the whole language ", Cell[BoxData[ \(TraditionalForm\`L\ = \ \(\(\(a\^*\)( b\ \(\((a\[VeryThinSpace]a)\)\^*\))\)\^*\) \(a\^*\)\)]], " as follows (see the section on syntactic semigroups below for more \ details):" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(L6 = LanguageFA[mm1, 6]\), "\n", \(\($identitystring = "\";\)\), "\n", \(\(red = Union[\((WordReduce[#1, eq] &)\) /@ L6];\)\), "\n", \(WordSort[red]\)}], "Input", AspectRatioFixed->True], Cell["\<\ The equations, while correct, are not in the form one might expect. \ They can be rewritten as follows:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\($identitystring = "\<1\>";\)\), "\n", \(\(eqs = SimplifyEquations[S, wit, eq];\)\), "\n", \(PrintEquations[eqs]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "The one bad pattern which forces a string out of the language is ", StyleBox["bab", FontSlant->"Italic"], " (remember the other simplification rules). " }], "Text", Evaluatable->False, AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[" Example 2: Even number of a's and b's.", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:7"], Cell[TextData[{ "A regular expression for all strings with an even number of a's and b's is \ quite a bit harder to come up with than the corresponding DFA. Clearly, the \ expression will be a star. It helps to think of the expression as a \ describing a sequence of blocks in the string. The easy case is when the \ string starts with ", StyleBox["aa", FontSlant->"Italic"], " or ", StyleBox["bb", FontSlant->"Italic"], ". The other cases are handled as follows:" }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ e0 = aa + bb; e1 = ab + ba; exp = RES[ e0 + e1**RES[e0]**e1 ]\ \>", "Input"], Cell["\<\ We can first check how big the FA will be without actually \ constructing it:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(RegularExpressionToFA[exp, {a, b}, SizeOnly \[Rule] True]\)], "Input", AspectRatioFixed->True], Cell["No problem. Now we actually build the machine:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m1 = RegularExpressionToFA[exp, {a, b}]\)], "Input", AspectRatioFixed->True], Cell["\<\ Using the epsilon-transition based construction we get a slightly \ smaller machine:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(m2 = RegularExpressionToFA[exp, {a, b}, Thompson \[Rule] True];\)\), "\n", \(Size[m2]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Of course, it is much easier to get the same DFA from an \ intersection operation.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m3 = IntersectionFA[\ CounterDFA[a, 0, {a, b}, Modulus \[Rule] 2], CounterDFA[b, 0, {a, b}, Modulus \[Rule] 2]]\), "\n", \(EquivalentQFA[m2, m3]\)}], "Input", AspectRatioFixed->True], Cell["\<\ It is a very good exercise to construct an expression for the \ language with an odd number of a's and b's. Make sure to verify your \ expression by converting it to an FA and comparing the corresponding minimal \ DFA to the obvious one. We can exercise our simplification function again in conjunction with \ quotients. In this case, things work flawlessly.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(ee\ = \ ToRegExp[exp];\)\), "\[IndentingNewLine]", \(REQuotient[\ abba, ee\ ]\), "\[IndentingNewLine]", \(%\ // \ RESimplify\), "\[IndentingNewLine]", \(%\ === \ ee\)}], "Input"] }, Closed]], Cell[CellGroupData[{ Cell[" Example 3: L = a* b* + bab. ", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:8"], Cell["exp = RES[a]**RES[b] + bab", "Input"], Cell[BoxData[{ \(\(m = RegularExpressionToFA[exp, {a, b}];\)\), "\n", \(\(mm = MinimizeFA[m];\)\), "\n", \(PrintFA[mm]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Machine mm has a sink, but is not a sink automaton (there is a \ non-final state other than the trap state 6).\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(SinkQDFA[mm]\), "\n", \(TrapStatesFA[mm]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[mm, \(-6\)]\ // \ ColumnForm\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(\(ListPlot[LanguageFA[mm, \(-20\), SizeOnly \[Rule] True], PlotStyle \[Rule] {Blue, PointSize[0.02]}];\)\)], "Input"] }, Closed]], Cell[CellGroupData[{ Cell[" Example 4: \"no four consecutive a's\". ", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:9"], Cell["\<\ The hardest part here is to come up with the right regular \ expression. Of course, everything would be easy if we had extended regular \ expressions that have a complementation operation built in. Since we don't \ (good question: why not?), one has to be a little careful about decomposing \ strings into pieces. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell["exp = (Eps + a + aa + aaa ) ** RES[b + ba + baa + baaa]", "Input"], Cell[BoxData[ \(m0 = ToDFA[RegularExpressionToFA[exp, {a, b}]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(m1 = MinimizeFA[m0]\)], "Input", AspectRatioFixed->True], Cell["\<\ Verify that m1 works properly, first empirically and then by \ constructing the minimal automaton in a different way. The two machines turn \ out to be identical.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(Complement[Words[6, {a, b}], LanguageFA[m1, 6]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(AlgebraicForm /@ %\)], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(MinimizeFA[ ComplementFA[WordToFA[aaaa, {a, b}, Full \[Rule] True]]]\), "\n", \(m1 === %\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[" Example 5: \"integers in base 5\"", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:10"], Cell["\<\ It is a standard exercise to show that the set of numbers in some \ notation system forms a regular language. Here is a simple example: integers \ in base 5, without leading zeros. First we set up the alphabet--digits and a \ unary minus--and some abbreviations:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(alph = ToString /@ {0, 1, 2, 3, 4, "\<-\>"}\), "\n", \(digs0 = REP @@ Take[alph, 5]\), "\n", \(digs = Rest[digs0]\)}], "Input", AspectRatioFixed->True], Cell["\<\ Then one constructs a regular expression and the corresponding \ machines.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(reg = \(("\<-\>" + Eps)\) ** digs ** RES[digs0] + "\<0\>"\), "\n", \(m = RegularExpressionToFA[reg, alph]\), "\n", \(mm = MinimizeFA[m]\)}], "Input"], Cell["Lastly, we check the language:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(LanguageFA[mm, \(-3\)] // \ ColumnForm\)], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[" Example 6: Equivalence ", "Subsubsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:11"], Cell["\<\ Testing whether two regular expressions are equivalent is \ PSPACE-complete in general, so one should not try the following for large \ expressions. Here are two expressions for the same language:\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ e1 = RES[aa ** RES[ba]] e2 = a ** RES[aa+ab] ** a + Eps\ \>", "Input"], Cell["\<\ Our simplification rules are much too weak to recognize this \ fact.\ \>", "Text"], Cell[BoxData[{ \(\(e1\ // \ ToRegExp\)\ // \ RESimplify\), "\[IndentingNewLine]", \(\(e2\ // \ ToRegExp\)\ // \ RESimplify\)}], "Input"], Cell["But we can use brute force to establish equivalence.", "Text"], Cell[BoxData[{ \(\(m1 = RegularExpressionToFA[e1, {a, b}];\)\), "\n", \(\(m2 = RegularExpressionToFA[e2, {a, b}];\)\), "\n", \(EquivalentQFA[m1, m2]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "Here is another example, which actually represents one of the fundamental \ valid equation of regular expressions:\n\t", Cell[BoxData[ \(TraditionalForm\`\(\((ab)\)\^*\)\ = \ a\ \(\((b\[VeryThinSpace]a)\)\^*\) b\ + \ \[Epsilon]\)]], ".\nHere a and b could be arbitrary regular expressions, but it suffices to \ verify the equation for atomic symbols. " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ e1 = RES[ab] e2 = a**RES[ba]**b + Eps\ \>", "Input"], Cell[BoxData[{ \(\(m1 = RegularExpressionToFA[e1, {a, b}];\)\), "\n", \(\(m2 = RegularExpressionToFA[e2, {a, b}];\)\), "\n", \(EquivalentQFA[m1, m2]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "One more fundamental equation:\n\t", Cell[BoxData[ \(TraditionalForm\`\(\((a + b)\)\^*\)\ = \ \(\((\(a\^*\)\ \(b\^*\))\)\^*\)\)]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(e1 = RES[a + b]\), "\n", \(e2 = RES[\ RES[a]\ ** \ RES[b]\ ]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[{ \(\(m1 = RegularExpressionToFA[e1, {a, b}];\)\), "\n", \(\(m2 = RegularExpressionToFA[e2, {a, b}];\)\), "\n", \(EquivalentQFA[m1, m2]\)}], "Input", AspectRatioFixed->True] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Formatting\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:5"], Cell[TextData[{ "At present, there are no good tools in ", StyleBox["Automata", "MR"], " to format a regular expression. Some experimental formatting modes are \ available in ", StyleBox["formatre.m", "MR"], ". The code there uses the Notation package and may cause problems with \ the style sheet (", StyleBox["TextDemoMod.nb", "MR"], ") in this notebook. You may have to copy this style sheet into the ", StyleBox["SystemFiles/FrontEnd/StyleSheets", "MR"], " directory. Alternatively, copy the following segment into a notebook \ with default style, then everything should work. \nA regular expression." }], "Text"], Cell[BoxData[{ \(\(e0 = REP[aa, bb];\)\), "\n", \(\(e1 = REP[ab, ba];\)\), "\n", \(exp = RES[REP[e0, RET[e1, RES[e0], e1]]]\)}], "Input"], Cell["\<\ Load the formatting code. This will pop up a pesky Notation \ Palette, which you can safely remove.\ \>", "Text"], Cell[BoxData[ \(\(<< Automata`formatre`;\)\)], "Input"], Cell["Turn on formatting and redisplay the expression.", "Text"], Cell[BoxData[{ \(FormatRE[True]\), "\[IndentingNewLine]", \(exp\)}], "Input"], Cell["A different mode.", "Text"], Cell[BoxData[{ \(FormatRE[Some]\), "\[IndentingNewLine]", \(exp\)}], "Input"], Cell["Turn formatting off.", "Text"], Cell[BoxData[{ \(FormatRE[None]\), "\[IndentingNewLine]", \(exp\)}], "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Equations of Regular Expressions", "Section", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:12"], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Conversion\ to\ Regular\ Expressions\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:13"], Cell["\<\ There is a theorem by Kleene according to which every regular \ language can be denoted by some regular expression. The proof shows how to \ construct the expression from a given machine for the language and is mostly \ of academic interest: in applications one usually has the regular expression \ and wants to construct a corresponding machine. One of the problems with the \ algorithm is that the resulting expressions are usually huge (see the \ discussion about simplification of regular expressions above). Therefore, one \ should not use the command ToRegularExpressionFA on machines with more than a \ few states. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m = IntersectionFA[CounterDFA[a, 0, 2, Modulus \[Rule] 2], CounterDFA[b, 0, 2, Modulus \[Rule] 2]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(exp = ToRegularExpressionFA[m]\)], "Input", AspectRatioFixed->True], Cell["\<\ Since the expression is quite clumsy, the corresponding machine \ obtained by converting back to an FA will be fairly large. However, it is \ equivalent to the original DFA.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(mm = RegularExpressionToFA[exp, {a, b}]\)], "Input", AspectRatioFixed->True], Cell["\<\ This FA is trim, but the corresponding DFA has only 29 states. \ \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(Size[TrimFA[mm]]\), "\n", \(ToDFA[mm]\), "\n", \(EquivalentQFA[m, mm]\)}], "Input", AspectRatioFixed->True], Cell[TextData[{ "As a second example, construct a machine for all words not containing an \ infix ", Cell[BoxData[ FormBox[ StyleBox["aba", FontSlant->"Italic"], TraditionalForm]]], ". " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(m = MinimizeFA[ ComplementFA[WordToFA[aba, 2, Full \[Rule] True]]]\)], "Input", AspectRatioFixed->True], Cell["A horrendous rational expression for this language:", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(re = ToRegularExpressionFA[m]\)], "Input", AspectRatioFixed->True], Cell["\<\ To make sure this is right, convert back and minimize. Note that \ the intermediate NFA has 54 states! In the end, the minimal DFA mm is \ isomorphic to m, so the expression is correct.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(nfa = RegularExpressionToFA[re];\)\), "\n", \(Size[nfa]\), "\n", \(dfa = ToDFA[nfa]\), "\n", \(mm = MinimizeFA[dfa]\), "\n", \(IsomorphicQDFA[m, mm]\)}], "Input", AspectRatioFixed->True] }, Closed]], Cell[CellGroupData[{ Cell[BoxData[ \(TraditionalForm\`Machines\ as\ Systems\ of\ Equations\)], "Subsection", Evaluatable->False, AspectRatioFixed->True, CellTags->"c:14"], Cell["\<\ One may view a FSM as a linear system of equations over the \ semiring of all languages over some alphabet. We have a command \ DFAToEquations that converts a DFA to the corresponding system of equations. \ The system can the be solved using Arden's lemma. As an example we show how \ to get a regular expression for the language of all strings with an even \ number of a's and b's. As already pointed out on several occasions, \ simplification of regular expressions is difficult (an understatement) Hence \ this approach will only be useful for very small machines at best. In other \ words: use only for carefully chosen examples and adjust the simplification \ rules whenever necessary. \ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[ \(FormatX[True]\)], "Input"], Cell[BoxData[{ \(\(m = IntersectionFA[CounterDFA[a, 0, 2, Modulus \[Rule] 2], CounterDFA[b, 0, 2, Modulus \[Rule] 2]];\)\), "\n", \(\({e1, e2, e3, e4} = ToEquationsDFA[m];\)\), "\n", \(ColumnForm[{e1, e2, e3, e4}]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e11 = SubstituteRE[e1, e2, e3]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e44 = SubstituteRE[e4, e2, e3]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e5 = ArdenSolve[e44]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e6 = SubstituteRE[e11, e5]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(sol = ArdenSolve[e6]\)], "Input", AspectRatioFixed->True], Cell["\<\ The last expression could be simplified by rewriting the four \ middle terms (but our simplification rules are not powerful enough to do \ this). At any rate, we can verify that the expression is correct by \ converting it back to a DFA.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(\(exp = sol\[LeftDoubleBracket]2\[RightDoubleBracket];\)\), "\n", \(ToList[exp\[LeftDoubleBracket]1\[RightDoubleBracket]]\ // \ ColumnForm\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(mm = MinimizeFA[RegularExpressionToFA[exp, {a, b}]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(IsomorphicQDFA[m, mm]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Another example: all words containing the factor ", Cell[BoxData[ FormBox[ StyleBox["aba", FontSlant->"Italic"], TraditionalForm]]], "." }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(m = MinimizeFA[WordToFA[aba, 2, Full \[Rule] True]]\), "\n", \(\({e1, e2, e3, e4} = ToEquationsDFA[m];\)\), "\n", \(ColumnForm[{e1, e2, e3, e4}]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e44 = ArdenSolve[e4]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e33 = SubstituteRE[e3, e44]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e21 = SubstituteRE[e2, e33]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e22 = ArdenSolve[e21]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e11 = SubstituteRE[e1, e22]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(sol = ArdenSolve[e11]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(MinimizeFA[ RegularExpressionToFA[ sol\[LeftDoubleBracket]2\[RightDoubleBracket]]]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(IsomorphicQDFA[%, m]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "Of course, there is a much simpler rational expression for this language \ and we can find it without having to convert any machines:\n\t", Cell[BoxData[ FormBox[ RowBox[{\(\((a + b)\)\^*\), StyleBox["aba", FontSlant->"Italic"], StyleBox[" ", FontSlant->"Italic"], \(\((a + b)\)\^*\)}], TraditionalForm]]], "\nIt is much harder to produce an expression for the complement of this \ language. However, the same sequence of substitution and applications of \ Arden's lemma will generate a suitable expression when applied to the \ complement of the DFA from the last example: " }], "Text", Evaluatable->False, AspectRatioFixed->True], Cell[BoxData[{ \(mm = ComplementFA[m]\), "\n", \(\({e1, e2, e3, e4} = ToEquationsDFA[mm];\)\), "\n", \(ColumnForm[{e1, e2, e3, e4}]\)}], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e44 = ArdenSolve[e4]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e33 = SubstituteRE[e3, e44]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e21 = SubstituteRE[e2, e33]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e22 = ArdenSolve[e21]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(e11 = SubstituteRE[e1, e22]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(sol = ArdenSolve[e11]\)], "Input", AspectRatioFixed->True], Cell[BoxData[ \(MinimizeFA[ RegularExpressionToFA[ sol\[LeftDoubleBracket]2\[RightDoubleBracket]]]\)], "Input", AspectRatioFixed->True], Cell[TextData[{ "The expression can be rewritten as \n\t", Cell[BoxData[ \(TraditionalForm\`\(\((\((\[Epsilon]\ + \ a\[VeryThinSpace]\(a\^*\) b)\) b)\)\^*\) \(a\^*\)\ \((\[Epsilon]\ + \ a\[VeryThinSpace]b)\)\)]], "\nOf course, our simplification rules are not powerful enough to do this. \ " }], "Text", Evaluatable->False, AspectRatioFixed->True] }, Closed]] }, Closed]] }, FrontEndVersion->"5.0 for X", ScreenRectangle->{{0, 1280}, {0, 1024}}, AutoGeneratedPackage->None, WindowToolbars->{}, CellGrouping->Automatic, WindowSize->{1009, 884}, WindowMargins->{{Automatic, 108}, {0, Automatic}}, Visible->True, PrintingStartingPageNumber->1, PrivateNotebookOptions->{"ColorPalette"->{RGBColor, 128}}, ShowSelection->True, ShowCellLabel->False, CellLabelAutoDelete->True, ShowCellTags->False, InputAliases->{"intt"->RowBox[ {"\[Integral]", RowBox[ {"\[SelectionPlaceholder]", RowBox[ {"\[DifferentialD]", "\[Placeholder]"}]}]}], "dintt"->RowBox[ { SubsuperscriptBox[ "\[Integral]", "\[SelectionPlaceholder]", "\[Placeholder]"], RowBox[ {"\[Placeholder]", RowBox[ {"\[DifferentialD]", "\[Placeholder]"}]}]}], "sumt"->RowBox[ { UnderoverscriptBox[ "\[Sum]", RowBox[ {"\[SelectionPlaceholder]", "=", "\[Placeholder]"}], "\[Placeholder]"], "\[Placeholder]"}], "prodt"->RowBox[ { UnderoverscriptBox[ "\[Product]", RowBox[ {"\[SelectionPlaceholder]", "=", "\[Placeholder]"}], "\[Placeholder]"], "\[Placeholder]"}], "dt"->RowBox[ { SubscriptBox[ "\[PartialD]", "\[Placeholder]"], " ", "\[SelectionPlaceholder]"}], "notation"->RowBox[ {"Notation", "[", RowBox[ { TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"], " ", "\[DoubleLongLeftRightArrow]", " ", TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"]}], "]"}], "notation>"->RowBox[ {"Notation", "[", RowBox[ { TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"], " ", "\[DoubleLongRightArrow]", " ", TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"]}], "]"}], "notation<"->RowBox[ {"Notation", "[", RowBox[ { TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"], " ", "\[DoubleLongLeftArrow]", " ", TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"]}], "]"}], "symb"->RowBox[ {"Symbolize", "[", TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"], "]"}], "infixnotation"->RowBox[ {"InfixNotation", "[", RowBox[ { TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"], ",", "\[Placeholder]"}], "]"}], "addia"->RowBox[ {"AddInputAlias", "[", RowBox[ {"\"\[Placeholder]\"", "\[Rule]", TagBox[ "\[Placeholder]", NotationBoxTag, TagStyle -> "NotationTemplateStyle"]}], "]"}], "pattwraper"->TagBox[ "\[Placeholder]", NotationPatternTag, TagStyle -> "NotationPatternWrapperStyle"], "madeboxeswraper"->TagBox[ "\[Placeholder]", NotationMadeBoxesTag, TagStyle -> "NotationMadeBoxesWrapperStyle"]}, RenderingOptions->{"ObjectDithering"->True, "RasterDithering"->False}, CharacterEncoding->Automatic, Magnification->1.5, StyleDefinitions -> Notebook[{ Cell[CellGroupData[{ Cell["Style Definitions", "Subtitle"], Cell["\<\ Modify the definitions below to change the default appearance of \ all cells in a given style. Make modifications to any definition using \ commands in the Format menu.\ \>", "Text"], Cell[CellGroupData[{ Cell["Style Environment Names", "Section"], Cell[StyleData[All, "Working"], PageWidth->WindowWidth, ScriptMinSize->9], Cell[StyleData[All, "Presentation"], PageWidth->WindowWidth, ScriptMinSize->9], Cell[StyleData[All, "SlideShow"], PageWidth->WindowWidth, ScrollingOptions->{"PagewiseDisplay"->True, "VerticalScrollRange"->Fit}, ShowCellBracket->False, ScriptMinSize->9], Cell[StyleData[All, "Printout"], PageWidth->PaperWidth, ScriptMinSize->7, FontSize->10, PrivateFontOptions->{"FontType"->"Outline"}] }, Closed]], Cell[CellGroupData[{ Cell["Notebook Options", "Section"], Cell["\<\ The options defined for the style below will be used at the \ Notebook level.\ \>", "Text"], Cell[StyleData["Notebook"], PageHeaders->{{Cell[ TextData[ { CounterBox[ "Page"]}], "PageNumber"], None, Cell[ TextData[ { ValueBox[ "FileName"]}], "Header"]}, {Cell[ TextData[ { ValueBox[ "FileName"]}], "Header"], None, Cell[ TextData[ { CounterBox[ "Page"]}], "PageNumber"]}}, PrintingOptions->{"FirstPageHeader"->False, "FirstPageFace"->Right}, StyleMenuListing->None, Background->RGBColor[0.900008, 0.863996, 0.809995]] }, Open ]], Cell[CellGroupData[{ Cell["Styles for Headings", "Section"], Cell[CellGroupData[{ Cell[StyleData["Title"], ShowCellBracket->False, CellMargins->{{0, 0}, {0, 0}}, PageBreakBelow->False, InputAutoReplacements->{"TeX"->StyleBox[ RowBox[ {"T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "LaTeX"->StyleBox[ RowBox[ {"L", StyleBox[ AdjustmentBox[ "A", BoxMargins -> {{-0.35999999999999999, \ -0.10000000000000001}, {0, 0}}, BoxBaselineShift -> -0.20000000000000001], FontSize -> Smaller], "T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "mma"->"Mathematica", "Mma"->"Mathematica", "MMA"->"Mathematica", "gridMathematica"->FormBox[ RowBox[ {"grid", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], "webMathematica"->FormBox[ RowBox[ {"web", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], Inherited}, LineSpacing->{1, 13}, CounterAssignments->{{"Section", 0}, {"Equation", 0}, {"Figure", 0}}, FontFamily->"Helvetica", FontSize->34, FontWeight->"Bold", FontColor->GrayLevel[1], Background->GrayLevel[0]], Cell[StyleData["Title", "Presentation"], CellFrameMargins->{{14, 10}, {15, 15}}, FontSize->51], Cell[StyleData["Title", "Printout"], CellMargins->{{0, 0}, {0, 0}}, FontSize->24, Background->GrayLevel[0]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Subtitle"], ShowCellBracket->False, CellMargins->{{0, 0}, {0, 0}}, PageBreakBelow->False, InputAutoReplacements->{"TeX"->StyleBox[ RowBox[ {"T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "LaTeX"->StyleBox[ RowBox[ {"L", StyleBox[ AdjustmentBox[ "A", BoxMargins -> {{-0.35999999999999999, \ -0.10000000000000001}, {0, 0}}, BoxBaselineShift -> -0.20000000000000001], FontSize -> Smaller], "T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "mma"->"Mathematica", "Mma"->"Mathematica", "MMA"->"Mathematica", "gridMathematica"->FormBox[ RowBox[ {"grid", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], "webMathematica"->FormBox[ RowBox[ {"web", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], Inherited}, LineSpacing->{1, 3}, ParagraphIndent->-96, CounterAssignments->{{"Section", 0}, {"Equation", 0}, {"Figure", 0}}, FontFamily->"Helvetica", FontSize->18, FontColor->GrayLevel[1], Background->RGBColor[0.2, 0.700008, 0.700008]], Cell[StyleData["Subtitle", "Presentation"], CellFrameMargins->{{14, 10}, {14, 14}}, FontSize->27], Cell[StyleData["Subtitle", "Printout"], CellMargins->{{0, 0}, {0, 0}}, ParagraphIndent->-85, FontSize->16, Background->GrayLevel[0.6]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Subsubtitle"], ShowCellBracket->False, CellMargins->{{10, 4}, {30, 10}}, PageBreakBelow->False, InputAutoReplacements->{"TeX"->StyleBox[ RowBox[ {"T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "LaTeX"->StyleBox[ RowBox[ {"L", StyleBox[ AdjustmentBox[ "A", BoxMargins -> {{-0.35999999999999999, \ -0.10000000000000001}, {0, 0}}, BoxBaselineShift -> -0.20000000000000001], FontSize -> Smaller], "T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "mma"->"Mathematica", "Mma"->"Mathematica", "MMA"->"Mathematica", "gridMathematica"->FormBox[ RowBox[ {"grid", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], "webMathematica"->FormBox[ RowBox[ {"web", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], Inherited}, CounterAssignments->{{"Section", 0}, {"Equation", 0}, {"Figure", 0}}, FontFamily->"Helvetica", FontSize->14, FontSlant->"Italic"], Cell[StyleData["Subsubtitle", "Presentation"], CellMargins->{{14, 4}, {55, 14}}, FontSize->21], Cell[StyleData["Subsubtitle", "Printout"], CellMargins->{{9, 10}, {50, 10}}, FontSize->14] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Section"], CellFrame->{{0, 0}, {0, 1}}, CellDingbat->None, CellMargins->{{12, Inherited}, {4, 24}}, CellGroupingRules->{"SectionGrouping", 30}, PageBreakBelow->False, CellFrameMargins->{{0, 4}, {6, 2}}, CellFrameLabelMargins->2, CounterIncrements->"Section", CounterAssignments->{{"Subsection", 0}, {"Subsubsection", 0}}, FontFamily->"Helvetica", FontSize->18, FontWeight->"Bold", FontColor->GrayLevel[0]], Cell[StyleData["Section", "Presentation"], CellFrame->{{0, 0}, {0, 2}}, CellMargins->{{14, 10}, {6, 24}}, FontSize->27], Cell[StyleData["Section", "Printout"], CellMargins->{{9, 0}, {2, 50}}, FontSize->14, FontTracking->"Plain", FontColor->GrayLevel[0]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Subsection"], CellDingbat->"\[GraySquare]", CellMargins->{{12, 10}, {10, 10}}, CellGroupingRules->{"SectionGrouping", 40}, LineSpacing->{1, 3}, ParagraphSpacing->{0, 12}, FontFamily->"Helvetica", FontSize->16], Cell[StyleData["Subsection", "Presentation"], CellMargins->{{14, 10}, {45, 4}}, FontSize->18], Cell[StyleData["Subsection", "Printout"], CellMargins->{{9, 0}, {4, 40}}, FontSize->12] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Subsubsection"], CellFrame->{{0, 0}, {0, 2}}, CellMargins->{{12, 10}, {5, 20}}, CellGroupingRules->{"SectionGrouping", 50}, CellFrameMargins->{{0, 0}, {0, 2}}, CellFrameColor->GrayLevel[1], LineSpacing->{1, 0}, ParagraphSpacing->{0, 12}, FontFamily->"Helvetica", FontSize->12, FontWeight->"Bold", FontSlant->"Italic", FontColor->RGBColor[0.4, 0, 0.6]], Cell[StyleData["Subsubsection", "Presentation"], CellMargins->{{14, 10}, {8, 20}}, CellFrameMargins->{{0, 0}, {0, 4}}, FontSize->18], Cell[StyleData["Subsubsection", "Printout"], CellMargins->{{19, 0}, {4, 20}}, FontSize->11] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Styles for Body Text", "Section"], Cell[CellGroupData[{ Cell[StyleData["Text"], CellMargins->{{12, 10}, {5, 5}}, InputAutoReplacements->{"TeX"->StyleBox[ RowBox[ {"T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "LaTeX"->StyleBox[ RowBox[ {"L", StyleBox[ AdjustmentBox[ "A", BoxMargins -> {{-0.35999999999999999, \ -0.10000000000000001}, {0, 0}}, BoxBaselineShift -> -0.20000000000000001], FontSize -> Smaller], "T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "mma"->"Mathematica", "Mma"->"Mathematica", "MMA"->"Mathematica", "gridMathematica"->FormBox[ RowBox[ {"grid", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], "webMathematica"->FormBox[ RowBox[ {"web", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], Inherited}, LineSpacing->{1, 3}, ParagraphSpacing->{0, 12}, FontFamily->"Helvetica"], Cell[StyleData["Text", "Presentation"], CellMargins->{{14, 10}, {8, 10}}, FontSize->18], Cell[StyleData["Text", "Printout"], CellMargins->{{9, 0}, {4, 4}}, Hyphenation->True, ParagraphSpacing->{0, 6}, FontSize->10] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Commentary"], CellMargins->{{52, 10}, {0, 10}}, PageBreakBelow->False, CellFrameMargins->{{0, 0}, {0, 2}}, CellFrameColor->GrayLevel[1], LineSpacing->{1, 0}, ParagraphSpacing->{0, 12}, FontFamily->"Helvetica", FontSize->10, FontWeight->"Plain", FontSlant->"Plain"], Cell[StyleData["Commentary", "Presentation"], CellMargins->{{72, 10}, {4, 14}}, FontSize->15], Cell[StyleData["Commentary", "Printout"], CellMargins->{{9, 0}, {4, 4}}, Hyphenation->True, ParagraphSpacing->{0, 6}, FontSize->10] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Styles for Input/Output", "Section"], Cell["\<\ The cells in this section define styles used for input and output \ to the kernel. Be careful when modifying, renaming, or removing these \ styles, because the front end associates special meanings with these style \ names.\ \>", "Text"], Cell[CellGroupData[{ Cell[StyleData["Input"], CellFrame->{{2, 2}, {0, 2}}, CellMargins->{{52, 10}, {0, 2}}, Evaluatable->True, CellGroupingRules->"InputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], DefaultFormatType->DefaultInputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, LanguageCategory->"Formula", FormatType->InputForm, ShowStringCharacters->True, NumberMarks->True, LinebreakAdjustments->{0.85, 2, 10, 0, 1}, FontWeight->"Bold", Background->GrayLevel[1]], Cell[StyleData["Input", "Presentation"], CellFrame->{{6, 6}, {0, 6}}, CellMargins->{{72, 10}, {0, 2}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["Input", "Printout"], CellMargins->{{37, 0}, {6, 6}}, LinebreakAdjustments->{0.85, 2, 10, 1, 1}, Background->GrayLevel[0.8]] }, Open ]], Cell[CellGroupData[{ Cell[StyleData["InlineInput"], Evaluatable->True, CellGroupingRules->"InputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, DefaultFormatType->DefaultInputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, AutoItalicWords->{}, FormatType->InputForm, ShowStringCharacters->True, NumberMarks->True, CounterIncrements->"Input", FontWeight->"Bold"], Cell[StyleData["InlineInput", "Presentation"], CellMargins->{{10, 10}, {4, 4}}, FontSize->18] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Output"], CellFrame->{{2, 2}, {2, 0}}, CellMargins->{{52, 10}, {12, 0}}, CellEditDuplicate->True, CellGroupingRules->"OutputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], DefaultFormatType->DefaultOutputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, LanguageCategory->"Formula", FormatType->InputForm, Background->GrayLevel[1]], Cell[StyleData["Output", "Presentation"], CellFrame->{{6, 6}, {6, 0}}, CellMargins->{{72, 10}, {20, 2}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["Output", "Printout"], CellMargins->{{37, 0}, {6, 2}}, Background->GrayLevel[0.900008]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["InputOnly"], CellFrame->4, CellMargins->{{52, 10}, {4, 2}}, Evaluatable->True, CellGroupingRules->"NormalGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], DefaultFormatType->DefaultInputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, LanguageCategory->"Formula", FormatType->InputForm, ShowStringCharacters->True, NumberMarks->True, LinebreakAdjustments->{0.85, 2, 10, 0, 1}, FontWeight->"Bold", Background->GrayLevel[1]], Cell[StyleData["InputOnly", "Presentation"], CellFrame->6, CellMargins->{{72, 10}, {5, 2}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["InputOnly", "Printout"], LinebreakAdjustments->{0.85, 2, 10, 1, 1}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["OutputOnly"], CellFrame->4, CellMargins->{{52, 10}, {4, 2}}, CellEditDuplicate->True, CellGroupingRules->"OutputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], DefaultFormatType->DefaultOutputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, LanguageCategory->"Formula", FormatType->InputForm, Background->GrayLevel[1]], Cell[StyleData["OutputOnly", "Presentation"], CellFrame->6, CellMargins->{{72, 10}, {4, 4}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["OutputOnly", "Printout"]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["SymbolicExpression"], CellFrame->1, CellMargins->{{52, 10}, {4, 2}}, CellEditDuplicate->True, CellGroupingRules->"OutputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, CellFrameColor->GrayLevel[0], DefaultFormatType->DefaultOutputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, FormatType->InputForm, FontFamily->"Courier", FontWeight->"Plain", FontSlant->"Plain", FontTracking->"Plain", Background->GrayLevel[1], FontVariations->{"Underline"->False, "Outline"->False, "Shadow"->False}], Cell[StyleData["SymbolicExpression", "Presentation"], CellFrame->2, CellMargins->{{72, 10}, {4, 4}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["SymbolicExpression", "Printout"]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Message"], CellMargins->{{52, Inherited}, {Inherited, Inherited}}, CellGroupingRules->"OutputGrouping", PageBreakWithin->False, GroupPageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, ShowCellLabel->False, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, DefaultFormatType->DefaultOutputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, AutoStyleOptions->{"UnmatchedBracketStyle"->None}, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, FormatType->InputForm, StyleMenuListing->None, FontColor->RGBColor[1, 0, 0]], Cell[StyleData["Message", "Presentation"], CellMargins->{{72, 10}, {6, 6}}, FontSize->18], Cell[StyleData["Message", "Printout"], CellMargins->{{30, Inherited}, {Inherited, Inherited}}, FontColor->GrayLevel[0]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Print"], CellMargins->{{52, Inherited}, {Inherited, Inherited}}, CellGroupingRules->"OutputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, ShowCellLabel->False, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, DefaultFormatType->DefaultOutputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, FormatType->InputForm, StyleMenuListing->None], Cell[StyleData["Print", "Presentation"], CellMargins->{{72, 10}, {6, 6}}, FontSize->18], Cell[StyleData["Print", "Printout"], CellMargins->{{30, Inherited}, {Inherited, Inherited}}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Info"], CellMargins->{{52, Inherited}, {Inherited, Inherited}}, CellGroupingRules->"OutputGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GroupPageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, ShowCellLabel->False, CellLabelMargins->{{21, Inherited}, {Inherited, Inherited}}, DefaultFormatType->DefaultOutputFormatType, "TwoByteSyntaxCharacterAutoReplacement"->True, HyphenationOptions->{"HyphenationCharacter"->"\[Continuation]"}, FormatType->InputForm, StyleMenuListing->None], Cell[StyleData["Info", "Presentation"], CellMargins->{{72, 10}, {6, 6}}, FontSize->18], Cell[StyleData["Info", "Printout"], CellMargins->{{30, Inherited}, {Inherited, Inherited}}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Graphics"], CellFrame->{{4, 4}, {0, 0}}, CellMargins->{{52, 10}, {0, 0}}, CellGroupingRules->"GraphicsGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GeneratedCell->True, CellAutoOverwrite->True, ShowCellLabel->False, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], DefaultFormatType->DefaultOutputFormatType, FormatType->InputForm, ImageMargins->{{43, Inherited}, {Inherited, 0}}, StyleMenuListing->None, Background->GrayLevel[1]], Cell[StyleData["Graphics", "Presentation"], CellFrame->{{6, 6}, {0, 0}}, CellMargins->{{72, 10}, {0, 0}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["Graphics", "Printout"], ImageSize->{250, 250}, ImageMargins->{{28, Inherited}, {Inherited, 0}}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["ImportPict"], CellMargins->{{52, 10}, {0, 0}}, CellGroupingRules->"GraphicsGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, GeneratedCell->True, DefaultFormatType->DefaultOutputFormatType, FormatType->InputForm, StyleMenuListing->"ImportPict", Background->None], Cell[StyleData["ImportPict", "Presentation"], CellMargins->{{72, 10}, {0, 0}}, FontSize->18], Cell[StyleData["ImportPict", "Printout"]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["CellLabel"], StyleMenuListing->None, FontFamily->"Helvetica", FontSize->10, FontWeight->"Plain", FontSlant->"Italic", FontColor->RGBColor[0.4, 0.4, 1]], Cell[StyleData["CellLabel", "Presentation"], FontSize->15], Cell[StyleData["CellLabel", "Printout"], FontFamily->"Courier", FontSize->8, FontSlant->"Italic", FontColor->GrayLevel[0]] }, Closed]] }, Open ]], Cell[CellGroupData[{ Cell["Styles for Unique Items", "Section"], Cell[CellGroupData[{ Cell[StyleData["PullQuote"], CellFrame->{{0, 0}, {0, 3}}, CellMargins->{{0, 250}, {15, 5}}, CellFrameMargins->{{20, 4}, {8, 6}}, LineSpacing->{1, 1}, ParagraphSpacing->{0, 12}, FontFamily->"Helvetica", FontSize->12, FontWeight->"Bold", FontColor->GrayLevel[1], Background->RGBColor[0.6, 0, 0.8]], Cell[StyleData["PullQuote", "Presentation"], CellFrame->{{0, 0}, {0, 5}}, CellMargins->{{0, 250}, {25, 8}}, CellFrameMargins->{{30, 10}, {10, 10}}, FontSize->18], Cell[StyleData["PullQuote", "Printout"], CellMargins->{{9, 0}, {4, 4}}, ParagraphSpacing->{0, 6}, FontSize->10] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["GrayBox"], CellFrame->{{0, 0}, {0, 3}}, CellMargins->{{62, 36}, {10, 5}}, CellFrameMargins->{{8, 4}, {8, 4}}, LineSpacing->{1, 3}, ParagraphSpacing->{0, 12}, FontFamily->"Helvetica", FontSize->10, FontWeight->"Plain", FontColor->GrayLevel[0], Background->RGBColor[0.8, 0.700008, 0.6]], Cell[StyleData["GrayBox", "Presentation"], CellFrame->{{0, 0}, {0, 5}}, CellMargins->{{90, 55}, {16, 5}}, CellFrameMargins->{{10, 10}, {12, 6}}, FontSize->15], Cell[StyleData["GrayBox", "Printout"], CellMargins->{{62, 36}, {10, 5}}, Background->GrayLevel[0.8]] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["Picture"], CellFrame->4, CellMargins->{{52, 10}, {0, 0}}, CellGroupingRules->"GraphicsGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], DefaultFormatType->DefaultOutputFormatType, FormatType->InputForm, StyleMenuListing->None, Background->GrayLevel[1]], Cell[StyleData["Picture", "Presentation"], CellFrame->6, CellMargins->{{72, 10}, {0, 6}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["Picture", "Printout"], ImageSize->{250, 250}, ImageMargins->{{28, Inherited}, {Inherited, 0}}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["PictureGroup"], CellFrame->{{4, 4}, {0, 0}}, CellMargins->{{52, Inherited}, {0, 0}}, CellGroupingRules->"GraphicsGrouping", CellHorizontalScrolling->True, PageBreakWithin->False, ShowCellLabel->False, CellFrameColor->RGBColor[0.8, 0.700008, 0.6], ImageMargins->{{43, Inherited}, {Inherited, 0}}, StyleMenuListing->None, Background->GrayLevel[1]], Cell[StyleData["PictureGroup", "Presentation"], CellFrame->{{6, 6}, {0, 0}}, CellMargins->{{72, 10}, {0, 0}}, CellFrameMargins->12, FontSize->18], Cell[StyleData["PictureGroup", "Printout"], ImageSize->{250, 250}, ImageMargins->{{28, Inherited}, {Inherited, 0}}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["LineSpace"], CellMargins->{{0, 0}, {0, 0}}, CellElementSpacings->{"CellMinHeight"->2}, FontSize->9], Cell[StyleData["LineSpace", "Presentation"], CellMargins->{{0, 4}, {0, 0}}, FontSize->14] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Hyperlink Styles", "Section"], Cell["\<\ The cells below define styles useful for making hypertext \ ButtonBoxes. The \"Hyperlink\" style is for links within the same Notebook, \ or between Notebooks.\ \>", "Text"], Cell[CellGroupData[{ Cell[StyleData["Hyperlink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`NotebookLocate[ #2]}]&), Active->True, ButtonNote->ButtonData}], Cell[StyleData["Hyperlink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell["\<\ The following styles are for linking automatically to the on-line \ help system.\ \>", "Text"], Cell[CellGroupData[{ Cell[StyleData["MainBookLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "MainBook", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["MainBookLink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["AddOnsLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontFamily->"Courier", FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "AddOns", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["AddOnsLink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["RefGuideLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontFamily->"Courier", FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "RefGuide", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["RefGuideLink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["GettingStartedLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "GettingStarted", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["GettingStartedLink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["OtherInformationLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "OtherInformation", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["OtherInformationLink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["DemosLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "Demos", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["DemosLink", "Printout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}], Cell[StyleData["DemosLink", "EnhancedPrintout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}], Cell[StyleData["DemosLink", "EnhancedPrintoutNonGray"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["TourLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "Tour", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["TourLink", "Printout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}], Cell[StyleData["TourLink", "EnhancedPrintout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}], Cell[StyleData["TourLink", "EnhancedPrintoutNonGray"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["MasterIndexLink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontColor->RGBColor[0, 0, 1], FontVariations->{"Underline"->True}, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`HelpBrowserLookup[ "MasterIndex", #]}]&), Active->True, ButtonFrame->"None"}], Cell[StyleData["MasterIndexLink", "Printout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}], Cell[StyleData["MasterIndexLink", "EnhancedPrintout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}], Cell[StyleData["MasterIndexLink", "EnhancedPrintoutNonGray"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Palette Styles", "Section"], Cell["\<\ The cells below define styles that define standard \ ButtonFunctions, for use in palette buttons.\ \>", "Text"], Cell[StyleData["Paste"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`NotebookApply[ FrontEnd`InputNotebook[ ], #, After]}]&)}], Cell[StyleData["Evaluate"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`NotebookApply[ FrontEnd`InputNotebook[ ], #, All], SelectionEvaluate[ FrontEnd`InputNotebook[ ], All]}]&)}], Cell[StyleData["EvaluateCell"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`NotebookApply[ FrontEnd`InputNotebook[ ], #, All], FrontEnd`SelectionMove[ FrontEnd`InputNotebook[ ], All, Cell, 1], FrontEnd`SelectionEvaluateCreateCell[ FrontEnd`InputNotebook[ ], All]}]&)}], Cell[StyleData["CopyEvaluate"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`SelectionCreateCell[ FrontEnd`InputNotebook[ ], All], FrontEnd`NotebookApply[ FrontEnd`InputNotebook[ ], #, All], FrontEnd`SelectionEvaluate[ FrontEnd`InputNotebook[ ], All]}]&)}], Cell[StyleData["CopyEvaluateCell"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`SelectionCreateCell[ FrontEnd`InputNotebook[ ], All], FrontEnd`NotebookApply[ FrontEnd`InputNotebook[ ], #, All], FrontEnd`SelectionEvaluateCreateCell[ FrontEnd`InputNotebook[ ], All]}]&)}] }, Closed]], Cell[CellGroupData[{ Cell["Slide Show Styles", "Section"], Cell[CellGroupData[{ Cell[StyleData["SlideShowNavigationBar"], Editable->False, CellFrame->True, CellMargins->{{0, 0}, {3, 3}}, CellElementSpacings->{"CellMinHeight"->0.8125}, CellGroupingRules->{"SectionGrouping", 30}, CellFrameMargins->False, CellFrameColor->GrayLevel[1], CellFrameLabelMargins->False, TextAlignment->Center, CounterIncrements->"SlideShowNavigationBar", StyleMenuListing->None, FontSize->10, Background->GrayLevel[0.8], Magnification->1, GridBoxOptions->{GridBaseline->Center, RowSpacings->0, ColumnSpacings->0, ColumnWidths->{3.5, 3.5, 3.5, 3.5, 13, 5, 4}, RowAlignments->Baseline, ColumnAlignments->{ Center, Center, Center, Center, Center, Center, Right, Center}}], Cell[StyleData["SlideShowNavigationBar", "SlideShow"], Deletable->False, ShowCellBracket->False, CellMargins->{{-1, -1}, {-1, -1}}, PageBreakAbove->True, CellFrameMargins->{{1, 1}, {0, 0}}], Cell[StyleData["SlideShowNavigationBar", "Printout"], CellMargins->{{18, 4}, {4, 4}}, LineSpacing->{1, 3}, FontSize->10] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["SlideShowSection"], CellFrame->{{0, 0}, {0, 0.5}}, CellMargins->{{0, 0}, {10, 0}}, CellGroupingRules->{"SectionGrouping", 40}, PageBreakBelow->False, CellFrameMargins->{{12, 4}, {6, 12}}, InputAutoReplacements->{"TeX"->StyleBox[ RowBox[ {"T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "LaTeX"->StyleBox[ RowBox[ {"L", StyleBox[ AdjustmentBox[ "A", BoxMargins -> {{-0.35999999999999999, \ -0.10000000000000001}, {0, 0}}, BoxBaselineShift -> -0.20000000000000001], FontSize -> Smaller], "T", AdjustmentBox[ "E", BoxMargins -> {{-0.074999999999999997, \ -0.085000000000000006}, {0, 0}}, BoxBaselineShift -> 0.5], "X"}]], "mma"->"Mathematica", "Mma"->"Mathematica", "MMA"->"Mathematica", "gridMathematica"->FormBox[ RowBox[ {"grid", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], "webMathematica"->FormBox[ RowBox[ {"web", AdjustmentBox[ StyleBox[ "Mathematica", FontSlant -> "Italic"], BoxMargins -> {{-0.17499999999999999, 0}, {0, 0}}]}], TextForm], Inherited}, CounterIncrements->"Section", CounterAssignments->{{"Subsection", 0}, {"Subsubsection", 0}}, StyleMenuListing->None, FontFamily->"Helvetica", FontSize->18, FontWeight->"Plain", FontColor->GrayLevel[1], Background->RGBColor[0.408011, 0.440726, 0.8]], Cell[StyleData["SlideShowSection", "Presentation"], CellFrameMargins->{{18, 10}, {10, 18}}, FontSize->27], Cell[StyleData["SlideShowSection", "SlideShow"], ShowCellBracket->False, PageBreakAbove->True], Cell[StyleData["SlideShowSection", "Printout"], CellMargins->{{18, 30}, {0, 30}}, CellFrameMargins->5, FontSize->14] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["SlideHyperlink"], StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontSize->26, FontColor->GrayLevel[0.400015], ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`NotebookLocate[ #2]}]&), Active->True, ButtonMinHeight->0.85, ButtonMargins->0.5, ButtonNote->None}], Cell[StyleData["SlideHyperlink", "Presentation"], CellMargins->{{10, 10}, {8, 12}}, FontSize->36], Cell[StyleData["SlideHyperlink", "SlideShow"]], Cell[StyleData["SlideHyperlink", "Printout"], FontSize->10, FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["SlideTOCLink"], CellMargins->{{24, Inherited}, {Inherited, Inherited}}, StyleMenuListing->None, ButtonStyleMenuListing->Automatic, FontFamily->"Helvetica", ButtonBoxOptions->{ButtonFunction:>(FrontEndExecute[ { FrontEnd`NotebookLocate[ #2]}]&), Active->True, ButtonMargins->1.5, ButtonNote->ButtonData}], Cell[StyleData["SlideTOCLink", "Presentation"], CellMargins->{{35, 10}, {6, 4}}, FontSize->18], Cell[StyleData["SlideTOCLink", "SlideShow"]], Cell[StyleData["SlideTOCLink", "Printout"], FontColor->GrayLevel[0], FontVariations->{"Underline"->False}] }, Closed]], Cell[CellGroupData[{ Cell[StyleData["SlideTOC"], CellDingbat->"\[Bullet]", CellMargins->{{18, Inherited}, {Inherited, Inherited}}, StyleMenuListing->None, FontFamily->"Helvetica"], Cell[StyleData["SlideTOC", "Presentation"], CellMargins->{{25, 10}, {6, 6}}, FontSize->18], Cell[StyleData["SlideTOC", "SlideShow"], FontSize->14], Cell[StyleData["SlideTOC", "Printout"], FontSize->10, FontColor->GrayLevel[0]] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Styles for Headers and Footers", "Section"], Cell[StyleData["Header"], CellMargins->{{0, 0}, {4, 1}}, StyleMenuListing->None, FontFamily->"Helvetica", FontSize->9, FontSlant->"Italic"], Cell[StyleData["Footer"], CellMargins->{{0, 0}, {0, 4}}, StyleMenuListing->None, FontFamily->"Helvetica", FontSize->6], Cell[StyleData["PageNumber"], CellMargins->{{0, 0}, {4, 1}}, StyleMenuListing->None, FontFamily->"Helvetica", FontSize->9, FontWeight->"Bold"] }, Closed]], Cell[CellGroupData[{ Cell["FormatType Styles", "Section"], Cell["\<\ The cells below define styles that are mixed in with the styles \ of most cells. If a cell's FormatType matches the name of one of the styles \ defined below, then that style is applied between the cell's style and its \ own options.\ \>", "Text"], Cell[StyleData["CellExpression"], CellFrame->1, CellMargins->{{52, 10}, {4, 2}}, ShowCellLabel->False, CellLabelMargins->{{23, Inherited}, {Inherited, Inherited}}, ShowSpecialCharacters->False, AllowInlineCells->False, StyleMenuListing->None, FontFamily->"Courier", FontSize->10, FontColor->GrayLevel[0], Background->GrayLevel[1]] }, Closed]] }, Open ]], Cell[CellGroupData[{ Cell["Notation Package Styles", "Section", CellTags->"NotationPackage"], Cell["\<\ The cells below define certain styles needed by the Notation \ package. These styles serve to make visible otherwise invisible \ tagboxes.\ \>", "Text", CellTags->"NotationPackage"], Cell[StyleData["NotationTemplateStyle"], StyleMenuListing->None, Background->RGBColor[1, 1, 0.850004], TagBoxOptions->{SyntaxForm->"symbol"}, CellTags->"NotationPackage"], Cell[StyleData["NotationPatternWrapperStyle"], StyleMenuListing->None, Background->RGBColor[1, 0.900008, 0.979995], TagBoxOptions->{SyntaxForm->"symbol"}, CellTags->"NotationPackage"], Cell[StyleData["NotationMadeBoxesWrapperStyle"], StyleMenuListing->None, Background->RGBColor[0.900008, 0.889998, 1], TagBoxOptions->{SyntaxForm->"symbol"}, CellTags->"NotationPackage"] }, Closed]] }] ] (******************************************************************* Cached data follows. If you edit this Notebook file directly, not using Mathematica, you must remove the line containing CacheID at the top of the file. The cache data will then be recreated when you save this file from within Mathematica. *******************************************************************) (*CellTagsOutline CellTagsIndex->{ "c:1"->{ Cell[1806, 53, 147, 4, 107, "Title", Evaluatable->False, CellTags->"c:1"]}, "c:5"->{ Cell[1978, 61, 105, 3, 77, "Section", Evaluatable->False, CellTags->"c:5"], Cell[187534, 6281, 130, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:5"], Cell[198614, 6677, 132, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:5"]}, "c:6"->{ Cell[2108, 68, 96, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:6"], Cell[187689, 6289, 179, 6, 64, "Subsubsection", Evaluatable->False, CellTags->"c:6"]}, "c:7"->{ Cell[20108, 728, 115, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:7"], Cell[190038, 6371, 132, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:7"]}, "c:8"->{ Cell[25317, 905, 121, 3, 45, "Section", Evaluatable->False, CellTags->"c:8"], Cell[192709, 6465, 122, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:8"]}, "c:9"->{ Cell[25463, 912, 156, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:9"], Cell[53572, 1846, 95, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:9"], Cell[63116, 2193, 131, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:9"], Cell[193634, 6501, 134, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:9"]}, "c:10"->{ Cell[34247, 1205, 88, 2, 67, "Subsubsection", CellTags->"c:10"], Cell[64791, 2244, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:10"], Cell[195048, 6551, 128, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:10"]}, "c:11"->{ Cell[36176, 1267, 134, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:11"], Cell[68522, 2355, 132, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Boolean Operations", "c:11"}], Cell[196266, 6594, 118, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:11"]}, "c:12"->{ Cell[41600, 1440, 132, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:12"], Cell[74021, 2535, 143, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Concatenation Star", "c:12"}], Cell[122795, 4111, 133, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Exponential blow-up", "c:12"}], Cell[200187, 6733, 119, 3, 45, "Section", Evaluatable->False, CellTags->"c:12"]}, "c:13"->{ Cell[43964, 1527, 143, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:13"], Cell[76243, 2617, 118, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Shuffle", "c:13"}], Cell[123466, 4133, 107, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:13"], Cell[200331, 6740, 159, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:13"]}, "c:14"->{ Cell[49199, 1699, 134, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:14"], Cell[110930, 3704, 108, 3, 45, "Section", Evaluatable->False, CellTags->"c:14"], Cell[117569, 3936, 124, 3, 45, "Section", Evaluatable->False, CellTags->"c:14"], Cell[126148, 4235, 111, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:14"], Cell[203252, 6840, 159, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:14"]}, "c:15"->{ Cell[50865, 1751, 140, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:15"], Cell[111063, 3711, 129, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Conversion", "c:15"}]}, "c:17"->{ Cell[51592, 1772, 99, 3, 52, "Subsection", Evaluatable->False, CellTags->"c:17"], Cell[117718, 3943, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Conversion", "c:17"}]}, "c:16"->{ Cell[53441, 1839, 106, 3, 45, "Section", Evaluatable->False, CellTags->"c:16"], Cell[114189, 3820, 134, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Epsilon Elimination", "c:16"}]}, "Boolean Operations"->{ Cell[68522, 2355, 132, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Boolean Operations", "c:11"}]}, "Concatenation Star"->{ Cell[74021, 2535, 143, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Concatenation Star", "c:12"}]}, "Shuffle"->{ Cell[76243, 2617, 118, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Shuffle", "c:13"}]}, "S5.37.1"->{ Cell[91955, 3085, 614, 12, 189, "Input", CellTags->"S5.37.1"], Cell[94111, 3158, 828, 17, 235, "Input", CellTags->"S5.37.1"]}, "Graphs"->{ Cell[95000, 3182, 121, 3, 45, "Section", Evaluatable->False, CellTags->{"Graphs", "c:19"}]}, "c:19"->{ Cell[95000, 3182, 121, 3, 45, "Section", Evaluatable->False, CellTags->{"Graphs", "c:19"}]}, "c:20"->{ Cell[95146, 3189, 122, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:20"]}, "c:21"->{ Cell[97788, 3270, 117, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:21"]}, "c:22"->{ Cell[101634, 3405, 107, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:22"]}, "c:23"->{ Cell[108106, 3609, 108, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:23"]}, "Conversion"->{ Cell[111063, 3711, 129, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Conversion", "c:15"}], Cell[117718, 3943, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Conversion", "c:17"}]}, "Epsilon Elimination"->{ Cell[114189, 3820, 134, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Epsilon Elimination", "c:16"}]}, "Exponential blow-up"->{ Cell[122795, 4111, 133, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Exponential blow-up", "c:12"}]}, "Sample machines"->{ Cell[127991, 4304, 128, 3, 45, "Section", Evaluatable->False, CellTags->{"Sample machines", "c:25"}]}, "c:25"->{ Cell[127991, 4304, 128, 3, 45, "Section", Evaluatable->False, CellTags->{"Sample machines", "c:25"}]}, "c:26"->{ Cell[128144, 4311, 102, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:26"]}, "c:27"->{ Cell[130242, 4389, 110, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:27"]}, "41-minimal DFAs"->{ Cell[130377, 4396, 121, 3, 64, "Subsubsection", Evaluatable->False, CellTags->{"41-minimal DFAs", "c:28"}], Cell[132146, 4452, 126, 3, 64, "Subsubsection", Evaluatable->False, CellTags->{"41-minimal DFAs", "c:28"}]}, "c:28"->{ Cell[130377, 4396, 121, 3, 64, "Subsubsection", Evaluatable->False, CellTags->{"41-minimal DFAs", "c:28"}], Cell[132146, 4452, 126, 3, 64, "Subsubsection", Evaluatable->False, CellTags->{"41-minimal DFAs", "c:28"}]}, "c:31"->{ Cell[134325, 4528, 114, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:31"]}, "c:32"->{ Cell[138542, 4675, 97, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:32"]}, "c:33"->{ Cell[140594, 4742, 128, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:33"]}, "c:34"->{ Cell[141580, 4768, 120, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:34"]}, "c:35"->{ Cell[148749, 5000, 113, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:35"]}, "Local universal"->{ Cell[151119, 5063, 137, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Local universal", "c:37"}]}, "c:37"->{ Cell[151119, 5063, 137, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Local universal", "c:37"}]}, "c:38"->{ Cell[154311, 5165, 102, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:38"]}, "c:39"->{ Cell[157705, 5296, 102, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:39"]}, "c:40"->{ Cell[163431, 5500, 112, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:40"]}, "c:24"->{ Cell[167376, 5644, 107, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:24"]}, "Regular expressions"->{ Cell[172745, 5825, 130, 3, 45, "Section", Evaluatable->False, CellTags->{"Regular expressions", "c:2"}]}, "c:2"->{ Cell[172745, 5825, 130, 3, 45, "Section", Evaluatable->False, CellTags->{"Regular expressions", "c:2"}]}, "c:3"->{ Cell[172900, 5832, 164, 5, 60, "Subsection", Evaluatable->False, CellTags->"c:3"]}, "c:4"->{ Cell[177571, 5970, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:4"], Cell[183419, 6127, 126, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:4"]} } *) (*CellTagsIndex CellTagsIndex->{ {"c:1", 253750, 8474}, {"c:5", 253853, 8478}, {"c:6", 254155, 8488}, {"c:7", 254363, 8495}, {"c:8", 254574, 8502}, {"c:9", 254782, 8509}, {"c:10", 255189, 8522}, {"c:11", 255479, 8531}, {"c:12", 255817, 8541}, {"c:13", 256274, 8554}, {"c:14", 256701, 8567}, {"c:15", 257210, 8583}, {"c:17", 257438, 8590}, {"c:16", 257665, 8597}, {"Boolean Operations", 257913, 8604}, {"Concatenation Star", 258063, 8608}, {"Shuffle", 258202, 8612}, {"S5.37.1", 258330, 8616}, {"Graphs", 258491, 8621}, {"c:19", 258612, 8625}, {"c:20", 258733, 8629}, {"c:21", 258845, 8633}, {"c:22", 258957, 8637}, {"c:23", 259070, 8641}, {"Conversion", 259189, 8645}, {"Epsilon Elimination", 259449, 8652}, {"Exponential blow-up", 259602, 8656}, {"Sample machines", 259751, 8660}, {"c:25", 259882, 8664}, {"c:26", 260013, 8668}, {"c:27", 260126, 8672}, {"41-minimal DFAs", 260250, 8676}, {"c:28", 260511, 8683}, {"c:31", 260772, 8690}, {"c:32", 260885, 8694}, {"c:33", 260997, 8698}, {"c:34", 261110, 8702}, {"c:35", 261226, 8706}, {"Local universal", 261353, 8710}, {"c:37", 261487, 8714}, {"c:38", 261621, 8718}, {"c:39", 261737, 8722}, {"c:40", 261853, 8726}, {"c:24", 261966, 8730}, {"Regular expressions", 262094, 8734}, {"c:2", 262227, 8738}, {"c:3", 262360, 8742}, {"c:4", 262471, 8746} } *) (*NotebookFileOutline Notebook[{ Cell[1754, 51, 49, 0, 41, "SmallText"], Cell[1806, 53, 147, 4, 107, "Title", Evaluatable->False, CellTags->"c:1"], Cell[CellGroupData[{ Cell[1978, 61, 105, 3, 77, "Section", Evaluatable->False, CellTags->"c:5"], Cell[CellGroupData[{ Cell[2108, 68, 96, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:6"], Cell[2207, 73, 343, 9, 69, "Text", Evaluatable->False], Cell[2553, 84, 223, 4, 120, "Input"], Cell[2779, 90, 768, 17, 150, "Text", Evaluatable->False], Cell[3550, 109, 72, 1, 66, "InputOnly"], Cell[3625, 112, 27, 0, 42, "Text"], Cell[3655, 114, 87, 1, 66, "InputOnly"], Cell[3745, 117, 977, 25, 177, "Text", Evaluatable->False], Cell[4725, 144, 102, 3, 74, "Input"], Cell[4830, 149, 100, 2, 51, "Input"], Cell[4933, 153, 299, 12, 42, "Text", Evaluatable->False], Cell[5235, 167, 153, 3, 51, "Input"], Cell[5391, 172, 181, 7, 42, "Text", Evaluatable->False], Cell[5575, 181, 142, 3, 51, "Input"], Cell[5720, 186, 160, 6, 42, "Text", Evaluatable->False], Cell[5883, 194, 145, 3, 51, "Input"], Cell[6031, 199, 430, 14, 69, "Text", Evaluatable->False], Cell[6464, 215, 235, 5, 120, "Input"], Cell[6702, 222, 106, 3, 42, "Text"], Cell[6811, 227, 94, 2, 51, "Input"], Cell[6908, 231, 287, 8, 69, "Text"], Cell[7198, 241, 121, 2, 74, "Input"], Cell[7322, 245, 70, 1, 51, "Input"], Cell[7395, 248, 555, 21, 69, "Text", Evaluatable->False], Cell[7953, 271, 115, 3, 74, "Input"], Cell[8071, 276, 245, 8, 42, "Text", Evaluatable->False], Cell[8319, 286, 68, 2, 51, "Input"], Cell[8390, 290, 209, 7, 42, "Text"], Cell[8602, 299, 141, 3, 74, "Input"], Cell[8746, 304, 164, 6, 42, "Text", Evaluatable->False], Cell[8913, 312, 158, 4, 97, "Input"], Cell[9074, 318, 260, 8, 69, "Text", Evaluatable->False], Cell[9337, 328, 113, 3, 74, "Input"], Cell[9453, 333, 378, 14, 69, "Text", Evaluatable->False], Cell[9834, 349, 50, 1, 51, "Input"], Cell[9887, 352, 385, 14, 69, "Text", Evaluatable->False], Cell[10275, 368, 175, 3, 74, "Input"], Cell[10453, 373, 323, 12, 42, "Text", Evaluatable->False], Cell[10779, 387, 94, 2, 51, "Input"], Cell[10876, 391, 275, 8, 69, "Text", Evaluatable->False], Cell[11154, 401, 58, 1, 51, "Input"], Cell[11215, 404, 100, 3, 42, "Text"], Cell[11318, 409, 149, 3, 74, "Input"], Cell[11470, 414, 392, 12, 69, "Text", Evaluatable->False], Cell[11865, 428, 112, 2, 74, "Input"], Cell[11980, 432, 504, 19, 69, "Text", Evaluatable->False], Cell[12487, 453, 129, 3, 74, "Input"], Cell[12619, 458, 111, 3, 74, "Input"], Cell[12733, 463, 98, 2, 51, "Input"], Cell[12834, 467, 764, 27, 120, "Text", Evaluatable->False], Cell[13601, 496, 277, 6, 121, "Input"], Cell[13881, 504, 70, 2, 51, "Input"], Cell[13954, 508, 612, 17, 147, "Text", Evaluatable->False], Cell[14569, 527, 102, 2, 51, "Input"], Cell[14674, 531, 42, 0, 42, "Text"], Cell[14719, 533, 82, 1, 51, "Input"], Cell[14804, 536, 108, 2, 42, "Text", Evaluatable->False], Cell[14915, 540, 117, 2, 51, "Input"], Cell[15035, 544, 248, 7, 69, "Text"], Cell[15286, 553, 61, 1, 51, "Input"], Cell[15350, 556, 118, 2, 42, "Text", Evaluatable->False], Cell[15471, 560, 198, 3, 74, "Input"], Cell[15672, 565, 205, 7, 42, "Text", Evaluatable->False], Cell[15880, 574, 82, 2, 51, "Input"], Cell[15965, 578, 242, 6, 69, "Text", Evaluatable->False], Cell[16210, 586, 81, 2, 51, "Input"], Cell[16294, 590, 87, 2, 51, "Input"], Cell[16384, 594, 940, 29, 123, "Text", Evaluatable->False], Cell[17327, 625, 129, 3, 51, "Input"], Cell[17459, 630, 87, 2, 51, "Input"], Cell[17549, 634, 335, 11, 69, "Text", Evaluatable->False], Cell[17887, 647, 132, 3, 51, "Input"], Cell[18022, 652, 135, 3, 74, "Input"], Cell[18160, 657, 119, 2, 42, "Text", Evaluatable->False], Cell[18282, 661, 73, 2, 51, "Input"], Cell[18358, 665, 333, 10, 69, "Text", Evaluatable->False], Cell[18694, 677, 98, 2, 51, "Input"], Cell[18795, 681, 103, 2, 51, "Input"], Cell[18901, 685, 108, 2, 42, "Text", Evaluatable->False], Cell[19012, 689, 109, 2, 51, "Input"], Cell[19124, 693, 423, 14, 69, "Text", Evaluatable->False], Cell[19550, 709, 75, 1, 51, "Input"], Cell[19628, 712, 235, 6, 69, "Text", Evaluatable->False], Cell[19866, 720, 205, 3, 97, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[20108, 728, 115, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:7"], Cell[20226, 733, 288, 8, 69, "Text", Evaluatable->False], Cell[20517, 743, 164, 4, 74, "Input"], Cell[20684, 749, 319, 10, 69, "Text", Evaluatable->False], Cell[21006, 761, 332, 6, 120, "Input"], Cell[21341, 769, 131, 2, 74, "Input"], Cell[21475, 773, 97, 2, 51, "Input"], Cell[21575, 777, 202, 4, 74, "Input"], Cell[21780, 783, 178, 5, 42, "Text", Evaluatable->False], Cell[21961, 790, 119, 3, 74, "Input"], Cell[22083, 795, 157, 5, 42, "Text"], Cell[22243, 802, 70, 2, 51, "Input"], Cell[22316, 806, 116, 2, 51, "Input"], Cell[22435, 810, 1456, 44, 316, "Text", Evaluatable->False], Cell[23894, 856, 442, 10, 239, "Input"], Cell[24339, 868, 377, 15, 42, "Text", Evaluatable->False], Cell[24719, 885, 194, 4, 97, "Input"], Cell[24916, 891, 117, 3, 42, "Text"], Cell[25036, 896, 232, 3, 97, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[25317, 905, 121, 3, 45, "Section", Evaluatable->False, CellTags->"c:8"], Cell[CellGroupData[{ Cell[25463, 912, 156, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:9"], Cell[25622, 918, 2554, 72, 504, "Text", Evaluatable->False], Cell[28179, 992, 1137, 35, 177, "Text", Evaluatable->False], Cell[29319, 1029, 3878, 130, 657, "Text", Evaluatable->False], Cell[33200, 1161, 73, 2, 51, "Input"], Cell[33276, 1165, 93, 2, 51, "Input"], Cell[33372, 1169, 67, 2, 51, "Input"], Cell[33442, 1173, 85, 2, 51, "Input"], Cell[33530, 1177, 66, 2, 51, "Input"], Cell[33599, 1181, 465, 15, 69, "Text", Evaluatable->False], Cell[34067, 1198, 155, 3, 74, "Input"], Cell[CellGroupData[{ Cell[34247, 1205, 88, 2, 67, "Subsubsection", CellTags->"c:10"], Cell[34338, 1209, 358, 7, 96, "Text", Evaluatable->False], Cell[34699, 1218, 116, 3, 74, "Input"], Cell[34818, 1223, 893, 20, 189, "Text", Evaluatable->False], Cell[35714, 1245, 76, 1, 51, "Input"], Cell[35793, 1248, 236, 9, 42, "Text", Evaluatable->False], Cell[36032, 1259, 95, 2, 74, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[36176, 1267, 134, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:11"], Cell[36313, 1272, 1717, 40, 297, "Text", Evaluatable->False], Cell[38033, 1314, 199, 5, 120, "Input"], Cell[38235, 1321, 175, 8, 42, "Text", Evaluatable->False], Cell[38413, 1331, 121, 3, 74, "Input"], Cell[38537, 1336, 244, 6, 69, "Text", Evaluatable->False], Cell[38784, 1344, 125, 3, 74, "Input"], Cell[38912, 1349, 272, 6, 69, "Text", Evaluatable->False], Cell[39187, 1357, 127, 3, 74, "Input"], Cell[39317, 1362, 937, 31, 252, "Text", Evaluatable->False], Cell[40257, 1395, 367, 8, 108, "Text", Evaluatable->False], Cell[40627, 1405, 175, 5, 74, "Input"], Cell[40805, 1412, 154, 3, 74, "Input"], Cell[40962, 1417, 157, 5, 42, "Text", Evaluatable->False], Cell[41122, 1424, 161, 3, 51, "Input"], Cell[41286, 1429, 277, 6, 69, "Text", Evaluatable->False] }, Closed]], Cell[CellGroupData[{ Cell[41600, 1440, 132, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:12"], Cell[41735, 1446, 611, 15, 123, "Text", Evaluatable->False], Cell[42349, 1463, 202, 6, 143, "Input"], Cell[42554, 1471, 170, 6, 42, "Text", Evaluatable->False], Cell[42727, 1479, 165, 4, 97, "Input"], Cell[42895, 1485, 494, 16, 69, "Text", Evaluatable->False], Cell[43392, 1503, 75, 2, 51, "Input"], Cell[43470, 1507, 384, 11, 69, "Text", Evaluatable->False], Cell[43857, 1520, 70, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[43964, 1527, 143, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:13"], Cell[44110, 1533, 3254, 111, 399, "Text", Evaluatable->False], Cell[47367, 1646, 150, 4, 97, "Input"], Cell[47520, 1652, 1084, 21, 345, "Text", Evaluatable->False], Cell[48607, 1675, 167, 4, 74, "Input"], Cell[48777, 1681, 299, 9, 69, "Text", Evaluatable->False], Cell[49079, 1692, 83, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[49199, 1699, 134, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:14"], Cell[49336, 1705, 1345, 35, 270, "Text", Evaluatable->False], Cell[50684, 1742, 144, 4, 97, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[50865, 1751, 140, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:15"], Cell[51008, 1757, 547, 10, 162, "Text", Evaluatable->False] }, Closed]], Cell[CellGroupData[{ Cell[51592, 1772, 99, 3, 52, "Subsection", Evaluatable->False, CellTags->"c:17"], Cell[51694, 1777, 561, 16, 96, "Text", Evaluatable->False], Cell[52258, 1795, 153, 5, 120, "Input"], Cell[52414, 1802, 648, 18, 96, "Text", Evaluatable->False], Cell[53065, 1822, 136, 4, 97, "Input"], Cell[53204, 1828, 188, 5, 42, "Text", Evaluatable->False] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[53441, 1839, 106, 3, 45, "Section", Evaluatable->False, CellTags->"c:16"], Cell[CellGroupData[{ Cell[53572, 1846, 95, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:9"], Cell[53670, 1851, 797, 17, 177, "Text", Evaluatable->False], Cell[CellGroupData[{ Cell[54492, 1872, 41, 0, 64, "Subsubsection"], Cell[54536, 1874, 461, 12, 96, "Text", Evaluatable->False], Cell[55000, 1888, 106, 2, 51, "Input"], Cell[55109, 1892, 116, 3, 74, "Input"], Cell[55228, 1897, 73, 2, 51, "Input"], Cell[55304, 1901, 81, 2, 51, "Input"], Cell[55388, 1905, 164, 5, 42, "Text", Evaluatable->False], Cell[55555, 1912, 174, 4, 97, "Input"], Cell[55732, 1918, 172, 6, 42, "Text", Evaluatable->False], Cell[55907, 1926, 151, 3, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[56095, 1934, 44, 0, 64, "Subsubsection"], Cell[56142, 1936, 303, 10, 42, "Text", Evaluatable->False], Cell[56448, 1948, 85, 2, 51, "Input"], Cell[56536, 1952, 466, 14, 81, "Text", Evaluatable->False], Cell[57005, 1968, 168, 4, 97, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[57210, 1977, 33, 0, 64, "Subsubsection"], Cell[57246, 1979, 215, 7, 42, "Text", Evaluatable->False], Cell[57464, 1988, 84, 2, 51, "Input"], Cell[57551, 1992, 80, 2, 51, "Input"], Cell[57634, 1996, 117, 2, 42, "Text", Evaluatable->False], Cell[57754, 2000, 108, 2, 51, "Input"], Cell[57865, 2004, 108, 2, 51, "Input"], Cell[57976, 2008, 129, 3, 51, "Input"], Cell[58108, 2013, 418, 11, 96, "Text", Evaluatable->False], Cell[58529, 2026, 134, 3, 74, "Input"], Cell[58666, 2031, 221, 8, 42, "Text", Evaluatable->False], Cell[58890, 2041, 119, 3, 74, "Input"], Cell[59012, 2046, 256, 8, 69, "Text", Evaluatable->False], Cell[59271, 2056, 105, 2, 51, "Input"], Cell[59379, 2060, 80, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[59496, 2067, 32, 0, 64, "Subsubsection"], Cell[59531, 2069, 468, 12, 96, "Text", Evaluatable->False], Cell[60002, 2083, 342, 8, 120, "Input"], Cell[60347, 2093, 135, 5, 42, "Text", Evaluatable->False], Cell[60485, 2100, 121, 3, 51, "Input"], Cell[60609, 2105, 786, 20, 150, "Text", Evaluatable->False], Cell[61398, 2127, 82, 2, 51, "Input"], Cell[61483, 2131, 222, 6, 97, "Input"], Cell[61708, 2139, 270, 8, 42, "Text", Evaluatable->False], Cell[61981, 2149, 100, 2, 51, "Input"], Cell[62084, 2153, 79, 2, 42, "Text", Evaluatable->False], Cell[62166, 2157, 73, 1, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[62276, 2163, 39, 0, 64, "Subsubsection"], Cell[62318, 2165, 423, 14, 69, "Text", Evaluatable->False], Cell[62744, 2181, 323, 6, 143, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[63116, 2193, 131, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:9"], Cell[63250, 2198, 1069, 22, 282, "Text", Evaluatable->False], Cell[64322, 2222, 87, 2, 51, "Input"], Cell[64412, 2226, 136, 4, 97, "Input"], Cell[64551, 2232, 125, 3, 74, "Input"], Cell[64679, 2237, 75, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[64791, 2244, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:10"], Cell[64924, 2249, 480, 11, 123, "Text", Evaluatable->False], Cell[65407, 2262, 121, 3, 51, "Input"], Cell[65531, 2267, 121, 3, 51, "Input"], Cell[65655, 2272, 93, 2, 51, "Input"], Cell[65751, 2276, 974, 28, 186, "Text", Evaluatable->False], Cell[66728, 2306, 130, 3, 74, "Input"], Cell[66861, 2311, 1036, 19, 309, "Text", Evaluatable->False], Cell[67900, 2332, 347, 8, 143, "Input"], Cell[68250, 2342, 175, 5, 42, "Text", Evaluatable->False], Cell[68428, 2349, 57, 1, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[68522, 2355, 132, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Boolean Operations", "c:11"}], Cell[68657, 2360, 1151, 24, 270, "Text", Evaluatable->False], Cell[69811, 2386, 215, 5, 120, "Input"], Cell[70029, 2393, 171, 6, 42, "Text", Evaluatable->False], Cell[70203, 2401, 138, 3, 74, "Input"], Cell[70344, 2406, 81, 2, 51, "Input"], Cell[70428, 2410, 451, 14, 69, "Text", Evaluatable->False], Cell[70882, 2426, 96, 2, 51, "Input"], Cell[70981, 2430, 477, 12, 96, "Text", Evaluatable->False], Cell[71461, 2444, 409, 9, 120, "Input"], Cell[71873, 2455, 286, 7, 69, "Text", Evaluatable->False], Cell[72162, 2464, 127, 3, 74, "Input"], Cell[72292, 2469, 220, 7, 42, "Text", Evaluatable->False], Cell[72515, 2478, 91, 2, 51, "Input"], Cell[72609, 2482, 49, 1, 51, "Input"], Cell[72661, 2485, 271, 6, 69, "Text", Evaluatable->False], Cell[72935, 2493, 152, 4, 97, "Input"], Cell[73090, 2499, 163, 5, 42, "Text", Evaluatable->False], Cell[73256, 2506, 82, 2, 51, "Input"], Cell[73341, 2510, 131, 3, 74, "Input"], Cell[73475, 2515, 136, 3, 51, "Input"], Cell[73614, 2520, 117, 2, 42, "Text", Evaluatable->False], Cell[73734, 2524, 250, 6, 143, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[74021, 2535, 143, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Concatenation Star", "c:12"}], Cell[74167, 2540, 278, 7, 69, "Text", Evaluatable->False], Cell[74448, 2549, 254, 5, 120, "Input"], Cell[74705, 2556, 375, 11, 69, "Text", Evaluatable->False], Cell[75083, 2569, 117, 2, 51, "Input"], Cell[75203, 2573, 90, 2, 51, "Input"], Cell[75296, 2577, 94, 2, 42, "Text", Evaluatable->False], Cell[75393, 2581, 100, 2, 51, "Input"], Cell[75496, 2585, 297, 10, 69, "Text", Evaluatable->False], Cell[75796, 2597, 106, 2, 51, "Input"], Cell[75905, 2601, 212, 8, 42, "Text", Evaluatable->False], Cell[76120, 2611, 86, 1, 50, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[76243, 2617, 118, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Shuffle", "c:13"}], Cell[76364, 2622, 223, 7, 42, "Text", Evaluatable->False], Cell[76590, 2631, 65, 1, 50, "Input"], Cell[76658, 2634, 74, 1, 50, "Input"], Cell[76735, 2637, 544, 14, 135, "Text", Evaluatable->False], Cell[77282, 2653, 123, 4, 70, "Input"], Cell[77408, 2659, 104, 2, 42, "Text", Evaluatable->False], Cell[77515, 2663, 137, 3, 74, "Input"], Cell[77655, 2668, 386, 11, 69, "Text", Evaluatable->False], Cell[78044, 2681, 186, 4, 74, "Input"], Cell[78233, 2687, 137, 5, 42, "Text", Evaluatable->False], Cell[78373, 2694, 87, 1, 50, "Input"], Cell[78463, 2697, 145, 3, 51, "Input"], Cell[78611, 2702, 778, 21, 96, "Text", Evaluatable->False], Cell[79392, 2725, 72, 1, 50, "Input"], Cell[79467, 2728, 87, 1, 50, "Input"], Cell[79557, 2731, 64, 1, 50, "Input"], Cell[79624, 2734, 594, 18, 69, "Text", Evaluatable->False], Cell[80221, 2754, 70, 2, 51, "Input"], Cell[80294, 2758, 237, 6, 69, "Text", Evaluatable->False], Cell[80534, 2766, 120, 3, 74, "Input"], Cell[80657, 2771, 133, 3, 74, "Input"], Cell[80793, 2776, 115, 2, 51, "Input"], Cell[80911, 2780, 70, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[81018, 2787, 89, 2, 63, "Subsection", Evaluatable->False], Cell[CellGroupData[{ Cell[81132, 2793, 57, 0, 64, "Subsubsection"], Cell[81192, 2795, 1053, 20, 231, "Text"], Cell[82248, 2817, 1624, 31, 603, "Input"], Cell[83875, 2850, 206, 5, 69, "Text"], Cell[84084, 2857, 117, 2, 74, "Input"], Cell[84204, 2861, 53, 1, 51, "Input"], Cell[84260, 2864, 189, 3, 74, "Input"], Cell[84452, 2869, 157, 3, 69, "Text"], Cell[84612, 2874, 49, 1, 51, "Input"], Cell[84664, 2877, 52, 0, 42, "Text"], Cell[84719, 2879, 156, 3, 74, "Input"], Cell[84878, 2884, 176, 4, 74, "Input"], Cell[85057, 2890, 195, 4, 74, "Input"], Cell[85255, 2896, 1670, 44, 333, "Text"], Cell[86928, 2942, 861, 14, 281, "Input"], Cell[87792, 2958, 184, 4, 69, "Text"], Cell[87979, 2964, 1184, 19, 350, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[89200, 2988, 36, 0, 64, "Subsubsection"], Cell[89239, 2990, 309, 10, 69, "Text"], Cell[89551, 3002, 209, 4, 74, "Input"], Cell[89763, 3008, 51, 1, 51, "Input"], Cell[89817, 3011, 203, 4, 74, "Input"], Cell[90023, 3017, 62, 0, 42, "Text"], Cell[90088, 3019, 119, 2, 74, "Input"], Cell[90210, 3023, 166, 4, 42, "Text"], Cell[90379, 3029, 210, 4, 97, "Input"], Cell[90592, 3035, 156, 3, 69, "Text"], Cell[90751, 3040, 75, 1, 51, "Input"], Cell[90829, 3043, 158, 5, 42, "Text"], Cell[90990, 3050, 51, 1, 51, "Input"], Cell[91044, 3053, 36, 0, 42, "Text"], Cell[91083, 3055, 73, 1, 51, "Input"], Cell[91159, 3058, 63, 0, 42, "Text"], Cell[91225, 3060, 109, 2, 51, "Input"], Cell[91337, 3064, 140, 3, 69, "Text"], Cell[91480, 3069, 132, 2, 51, "Input"], Cell[91615, 3073, 337, 10, 69, "Text"], Cell[91955, 3085, 614, 12, 189, "Input", CellTags->"S5.37.1"] }, Closed]], Cell[CellGroupData[{ Cell[92606, 3102, 40, 0, 64, "Subsubsection"], Cell[92649, 3104, 594, 17, 69, "Text"], Cell[93246, 3123, 70, 1, 51, "Input"], Cell[93319, 3126, 45, 0, 42, "Text"], Cell[93367, 3128, 49, 1, 51, "Input"], Cell[93419, 3131, 66, 0, 42, "Text"], Cell[93488, 3133, 73, 1, 51, "Input"], Cell[93564, 3136, 36, 0, 42, "Text"], Cell[93603, 3138, 70, 1, 51, "Input"], Cell[93676, 3141, 432, 15, 42, "Text"], Cell[94111, 3158, 828, 17, 235, "Input", CellTags->"S5.37.1"] }, Closed]] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[95000, 3182, 121, 3, 45, "Section", Evaluatable->False, CellTags->{"Graphs", "c:19"}], Cell[CellGroupData[{ Cell[95146, 3189, 122, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:20"], Cell[95271, 3194, 740, 14, 177, "Text", Evaluatable->False], Cell[96014, 3210, 576, 12, 123, "Text", Evaluatable->False], Cell[96593, 3224, 212, 4, 97, "Input"], Cell[96808, 3230, 114, 3, 42, "Text"], Cell[96925, 3235, 291, 5, 120, "Input"], Cell[97219, 3242, 58, 0, 42, "Text"], Cell[97280, 3244, 79, 2, 51, "Input"], Cell[97362, 3248, 138, 5, 42, "Text"], Cell[97503, 3255, 69, 2, 51, "Input"], Cell[97575, 3259, 79, 2, 51, "Input"], Cell[97657, 3263, 94, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[97788, 3270, 117, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:21"], Cell[97908, 3275, 474, 9, 123, "Text", Evaluatable->False], Cell[98385, 3286, 101, 2, 51, "Input"], Cell[98489, 3290, 131, 3, 74, "Input"], Cell[98623, 3295, 141, 5, 42, "Text", Evaluatable->False], Cell[98767, 3302, 89, 2, 51, "Input"], Cell[98859, 3306, 115, 2, 42, "Text", Evaluatable->False], Cell[98977, 3310, 148, 3, 74, "Input"], Cell[99128, 3315, 104, 2, 42, "Text", Evaluatable->False], Cell[99235, 3319, 73, 2, 51, "Input"], Cell[99311, 3323, 552, 13, 96, "Text", Evaluatable->False], Cell[99866, 3338, 187, 5, 74, "Input"], Cell[100056, 3345, 77, 2, 51, "Input"], Cell[100136, 3349, 200, 6, 42, "Text", Evaluatable->False], Cell[100339, 3357, 115, 2, 51, "Input"], Cell[100457, 3361, 75, 2, 51, "Input"], Cell[100535, 3365, 74, 2, 51, "Input"], Cell[100612, 3369, 488, 13, 96, "Text", Evaluatable->False], Cell[101103, 3384, 140, 3, 74, "Input"], Cell[101246, 3389, 207, 6, 69, "Text", Evaluatable->False], Cell[101456, 3397, 141, 3, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[101634, 3405, 107, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:22"], Cell[101744, 3410, 749, 22, 162, "Text", Evaluatable->False], Cell[102496, 3434, 484, 7, 143, "Input"], Cell[102983, 3443, 63, 1, 51, "Input"], Cell[103049, 3446, 105, 3, 42, "Text"], Cell[103157, 3451, 111, 2, 74, "Input"], Cell[103271, 3455, 39, 0, 42, "Text"], Cell[103313, 3457, 71, 1, 51, "Input"], Cell[103387, 3460, 148, 3, 69, "Text"], Cell[103538, 3465, 126, 2, 74, "Input"], Cell[103667, 3469, 122, 3, 51, "Input"], Cell[103792, 3474, 66, 1, 51, "Input"], Cell[103861, 3477, 102, 3, 42, "Text"], Cell[103966, 3482, 76, 1, 51, "Input"], Cell[104045, 3485, 1168, 35, 189, "Text", Evaluatable->False], Cell[105216, 3522, 145, 3, 74, "Input"], Cell[105364, 3527, 272, 9, 69, "Text"], Cell[105639, 3538, 66, 1, 51, "Input"], Cell[105708, 3541, 886, 17, 189, "Text"], Cell[106597, 3560, 199, 4, 97, "Input"], Cell[106799, 3566, 194, 5, 69, "Text", Evaluatable->False], Cell[106996, 3573, 210, 4, 120, "Input"], Cell[107209, 3579, 303, 9, 42, "Text", Evaluatable->False], Cell[107515, 3590, 269, 4, 120, "Input"], Cell[107787, 3596, 178, 4, 69, "Text"], Cell[107968, 3602, 101, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[108106, 3609, 108, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:23"], Cell[108217, 3614, 796, 27, 123, "Text", Evaluatable->False], Cell[109016, 3643, 287, 5, 97, "Input"], Cell[109306, 3650, 61, 1, 51, "Input"], Cell[109370, 3653, 600, 16, 123, "Text"], Cell[109973, 3671, 178, 3, 74, "Input"], Cell[110154, 3676, 271, 5, 96, "Text"], Cell[110428, 3683, 48, 1, 51, "Input"], Cell[110479, 3686, 242, 6, 69, "Text"], Cell[110724, 3694, 79, 1, 51, "Input"], Cell[110806, 3697, 75, 1, 51, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[110930, 3704, 108, 3, 45, "Section", Evaluatable->False, CellTags->"c:14"], Cell[CellGroupData[{ Cell[111063, 3711, 129, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Conversion", "c:15"}], Cell[111195, 3716, 1148, 29, 204, "Text", Evaluatable->False], Cell[112346, 3747, 94, 2, 42, "Text", Evaluatable->False], Cell[112443, 3751, 127, 3, 74, "Input"], Cell[112573, 3756, 171, 5, 42, "Text", Evaluatable->False], Cell[112747, 3763, 105, 3, 74, "Input"], Cell[112855, 3768, 107, 2, 42, "Text", Evaluatable->False], Cell[112965, 3772, 141, 4, 97, "Input"], Cell[113109, 3778, 401, 10, 96, "Text", Evaluatable->False], Cell[113513, 3790, 181, 5, 74, "Input"], Cell[113697, 3797, 99, 2, 51, "Input"], Cell[113799, 3801, 67, 2, 51, "Input"], Cell[113869, 3805, 144, 5, 42, "Text", Evaluatable->False], Cell[114016, 3812, 136, 3, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[114189, 3820, 134, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Epsilon Elimination", "c:16"}], Cell[114326, 3825, 1108, 30, 216, "Text", Evaluatable->False], Cell[115437, 3857, 299, 7, 97, "Input"], Cell[115739, 3866, 88, 2, 51, "Input"], Cell[115830, 3870, 200, 5, 69, "Text", Evaluatable->False], Cell[116033, 3877, 114, 3, 74, "Input"], Cell[116150, 3882, 1112, 36, 198, "Text", Evaluatable->False], Cell[117265, 3920, 150, 3, 51, "Input"], Cell[117418, 3925, 102, 5, 90, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[117569, 3936, 124, 3, 45, "Section", Evaluatable->False, CellTags->"c:14"], Cell[CellGroupData[{ Cell[117718, 3943, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Conversion", "c:17"}], Cell[117851, 3948, 809, 15, 216, "Text", Evaluatable->False], Cell[118663, 3965, 125, 3, 74, "Input"], Cell[118791, 3970, 446, 10, 96, "Text", Evaluatable->False], Cell[119240, 3982, 214, 4, 74, "Input"], Cell[119457, 3988, 340, 12, 69, "Text", Evaluatable->False], Cell[119800, 4002, 62, 1, 50, "Input"], Cell[119865, 4005, 303, 11, 42, "Text", Evaluatable->False], Cell[120171, 4018, 104, 2, 51, "Input"], Cell[120278, 4022, 177, 5, 42, "Text", Evaluatable->False], Cell[120458, 4029, 89, 2, 51, "Input"], Cell[120550, 4033, 252, 10, 42, "Text", Evaluatable->False], Cell[120805, 4045, 114, 2, 51, "Input"], Cell[120922, 4049, 186, 8, 42, "Text", Evaluatable->False], Cell[121111, 4059, 83, 2, 51, "Input"], Cell[121197, 4063, 997, 23, 228, "Text"], Cell[122197, 4088, 66, 1, 51, "Input"], Cell[122266, 4091, 130, 3, 51, "Input"], Cell[122399, 4096, 65, 0, 42, "Text"], Cell[122467, 4098, 234, 5, 74, "Input"], Cell[122704, 4105, 54, 1, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[122795, 4111, 133, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Exponential blow-up", "c:12"}], Cell[122931, 4116, 510, 13, 96, "Text", Evaluatable->False], Cell[CellGroupData[{ Cell[123466, 4133, 107, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:13"], Cell[123576, 4138, 761, 25, 96, "Text", Evaluatable->False], Cell[124340, 4165, 285, 7, 97, "Input"], Cell[124628, 4174, 68, 2, 51, "Input"], Cell[124699, 4178, 106, 3, 42, "Text"], Cell[124808, 4183, 106, 2, 51, "Input"], Cell[124917, 4187, 121, 3, 42, "Text"], Cell[125041, 4192, 125, 3, 74, "Input"], Cell[125169, 4197, 99, 2, 51, "Input"], Cell[125271, 4201, 79, 2, 51, "Input"], Cell[125353, 4205, 218, 7, 69, "Text", Evaluatable->False], Cell[125574, 4214, 101, 2, 51, "Input"], Cell[125678, 4218, 245, 6, 69, "Text", Evaluatable->False], Cell[125926, 4226, 185, 4, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[126148, 4235, 111, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:14"], Cell[126262, 4240, 763, 22, 123, "Text", Evaluatable->False], Cell[127028, 4264, 173, 4, 74, "Input"], Cell[127204, 4270, 66, 2, 51, "Input"], Cell[127273, 4274, 103, 2, 51, "Input"], Cell[127379, 4278, 378, 11, 81, "Text", Evaluatable->False], Cell[127760, 4291, 89, 2, 51, "Input"], Cell[127852, 4295, 78, 2, 51, "Input"] }, Closed]] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[127991, 4304, 128, 3, 45, "Section", Evaluatable->False, CellTags->{"Sample machines", "c:25"}], Cell[CellGroupData[{ Cell[128144, 4311, 102, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:26"], Cell[128249, 4316, 1056, 33, 162, "Text", Evaluatable->False], Cell[129308, 4351, 135, 3, 51, "Input"], Cell[129446, 4356, 61, 0, 42, "Text"], Cell[129510, 4358, 67, 1, 50, "Input"], Cell[129580, 4361, 55, 1, 50, "Input"], Cell[129638, 4364, 55, 1, 50, "Input"], Cell[129696, 4367, 96, 2, 51, "Input"], Cell[129795, 4371, 207, 6, 69, "Text", Evaluatable->False], Cell[130005, 4379, 101, 1, 50, "Input"], Cell[130109, 4382, 96, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[130242, 4389, 110, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:27"], Cell[CellGroupData[{ Cell[130377, 4396, 121, 3, 64, "Subsubsection", Evaluatable->False, CellTags->{"41-minimal DFAs", "c:28"}], Cell[130501, 4401, 1020, 26, 279, "Text", Evaluatable->False], Cell[131524, 4429, 258, 6, 120, "Input"], Cell[131785, 4437, 216, 6, 69, "Text", Evaluatable->False], Cell[132004, 4445, 105, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[132146, 4452, 126, 3, 64, "Subsubsection", Evaluatable->False, CellTags->{"41-minimal DFAs", "c:28"}], Cell[132275, 4457, 170, 5, 42, "Text", Evaluatable->False], Cell[132448, 4464, 225, 6, 97, "Input"], Cell[132676, 4472, 148, 5, 42, "Text", Evaluatable->False], Cell[132827, 4479, 185, 4, 97, "Input"], Cell[133015, 4485, 506, 13, 96, "Text", Evaluatable->False], Cell[133524, 4500, 102, 2, 51, "Input"], Cell[133629, 4504, 235, 6, 69, "Text", Evaluatable->False], Cell[133867, 4512, 239, 4, 74, "Input"], Cell[134109, 4518, 167, 4, 69, "Text"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[134325, 4528, 114, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:31"], Cell[134442, 4533, 850, 25, 174, "Text", Evaluatable->False], Cell[135295, 4560, 124, 3, 74, "Input"], Cell[135422, 4565, 257, 9, 42, "Text", Evaluatable->False], Cell[135682, 4576, 87, 2, 51, "Input"], Cell[135772, 4580, 222, 7, 42, "Text", Evaluatable->False], Cell[135997, 4589, 110, 2, 51, "Input"], Cell[136110, 4593, 321, 11, 69, "Text", Evaluatable->False], Cell[136434, 4606, 147, 4, 51, "Input"], Cell[136584, 4612, 517, 13, 106, "Text", Evaluatable->False], Cell[137104, 4627, 201, 4, 97, "Input"], Cell[137308, 4633, 445, 11, 135, "Text", Evaluatable->False], Cell[137756, 4646, 265, 6, 97, "Input"], Cell[138024, 4654, 105, 2, 51, "Input"], Cell[138132, 4658, 257, 7, 69, "Text", Evaluatable->False], Cell[138392, 4667, 113, 3, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[138542, 4675, 97, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:32"], Cell[138642, 4680, 414, 12, 96, "Text", Evaluatable->False], Cell[139059, 4694, 269, 4, 120, "Input"], Cell[139331, 4700, 123, 2, 74, "Input"], Cell[139457, 4704, 501, 14, 69, "Text", Evaluatable->False], Cell[139961, 4720, 345, 7, 120, "Input"], Cell[140309, 4729, 160, 5, 42, "Text", Evaluatable->False], Cell[140472, 4736, 85, 1, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[140594, 4742, 128, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:33"], Cell[140725, 4747, 830, 17, 177, "Text", Evaluatable->False], Cell[CellGroupData[{ Cell[141580, 4768, 120, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:34"], Cell[141703, 4773, 595, 16, 174, "Text", Evaluatable->False], Cell[142301, 4791, 395, 9, 166, "Input"], Cell[142699, 4802, 218, 6, 66, "Text", Evaluatable->False], Cell[142920, 4810, 78, 2, 51, "Input"], Cell[143001, 4814, 585, 17, 96, "Text", Evaluatable->False], Cell[143589, 4833, 261, 6, 143, "Input"], Cell[143853, 4841, 190, 6, 42, "Text", Evaluatable->False], Cell[144046, 4849, 113, 2, 51, "Input"], Cell[144162, 4853, 90, 2, 42, "Text", Evaluatable->False], Cell[144255, 4857, 162, 3, 74, "Input"], Cell[144420, 4862, 88, 2, 51, "Input"], Cell[144511, 4866, 1329, 39, 288, "Text", Evaluatable->False], Cell[145843, 4907, 359, 8, 166, "Input"], Cell[146205, 4917, 379, 12, 69, "Text", Evaluatable->False], Cell[146587, 4931, 244, 6, 120, "Input"], Cell[146834, 4939, 539, 18, 147, "Text", Evaluatable->False], Cell[147376, 4959, 627, 14, 189, "Input"], Cell[148006, 4975, 52, 1, 50, "Input"], Cell[148061, 4978, 192, 5, 69, "Text", Evaluatable->False], Cell[148256, 4985, 389, 7, 120, "Input"], Cell[148648, 4994, 64, 1, 50, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[148749, 5000, 113, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:35"], Cell[148865, 5005, 1290, 28, 294, "Text", Evaluatable->False], Cell[150158, 5035, 358, 8, 120, "Input"], Cell[150519, 5045, 551, 12, 135, "Text", Evaluatable->False] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[151119, 5063, 137, 3, 63, "Subsection", Evaluatable->False, CellTags->{"Local universal", "c:37"}], Cell[151259, 5068, 1511, 41, 267, "Text", Evaluatable->False], Cell[152773, 5111, 94, 2, 51, "Input"], Cell[152870, 5115, 1310, 42, 216, "Text", Evaluatable->False], Cell[154183, 5159, 103, 2, 51, "Input"], Cell[CellGroupData[{ Cell[154311, 5165, 102, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:38"], Cell[154416, 5170, 562, 13, 120, "Text", Evaluatable->False], Cell[154981, 5185, 278, 6, 97, "Input"], Cell[155262, 5193, 152, 6, 42, "Text", Evaluatable->False], Cell[155417, 5201, 86, 2, 51, "Input"], Cell[155506, 5205, 77, 2, 51, "Input"], Cell[155586, 5209, 124, 3, 74, "Input"], Cell[155713, 5214, 131, 3, 51, "Input"], Cell[155847, 5219, 483, 17, 69, "Text", Evaluatable->False], Cell[156333, 5238, 35, 1, 51, "Input"], Cell[156371, 5241, 87, 2, 51, "Input"], Cell[156461, 5245, 91, 2, 56, "Input"], Cell[156555, 5249, 89, 2, 56, "Input"], Cell[156647, 5253, 573, 20, 96, "Text", Evaluatable->False], Cell[157223, 5275, 78, 2, 51, "Input"], Cell[157304, 5279, 166, 5, 42, "Text", Evaluatable->False], Cell[157473, 5286, 195, 5, 120, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[157705, 5296, 102, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:39"], Cell[157810, 5301, 657, 16, 186, "Text", Evaluatable->False], Cell[158470, 5319, 329, 7, 97, "Input"], Cell[158802, 5328, 917, 30, 186, "Text"], Cell[159722, 5360, 98, 2, 51, "Input"], Cell[159823, 5364, 403, 8, 120, "Input"], Cell[160229, 5374, 93, 2, 51, "Input"], Cell[160325, 5378, 66, 1, 51, "Input"], Cell[160394, 5381, 79, 1, 50, "Input"], Cell[160476, 5384, 114, 2, 42, "Text", Evaluatable->False], Cell[160593, 5388, 197, 6, 143, "Input"], Cell[160793, 5396, 144, 5, 42, "Text", Evaluatable->False], Cell[160940, 5403, 177, 5, 120, "Input"], Cell[161120, 5410, 173, 4, 69, "Text"], Cell[161296, 5416, 99, 4, 70, "Input"], Cell[161398, 5422, 183, 5, 42, "Text", Evaluatable->False], Cell[161584, 5429, 132, 3, 51, "Input"], Cell[161719, 5434, 330, 8, 143, "Input"], Cell[162052, 5444, 104, 2, 51, "Input"], Cell[162159, 5448, 56, 1, 51, "Input"], Cell[162218, 5451, 287, 9, 69, "Text", Evaluatable->False], Cell[162508, 5462, 229, 5, 120, "Input"], Cell[162740, 5469, 117, 2, 42, "Text", Evaluatable->False], Cell[162860, 5473, 77, 2, 51, "Input"], Cell[162940, 5477, 136, 5, 42, "Text", Evaluatable->False], Cell[163079, 5484, 127, 3, 51, "Input"], Cell[163209, 5489, 102, 2, 42, "Text", Evaluatable->False], Cell[163314, 5493, 68, 1, 50, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[163431, 5500, 112, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:40"], Cell[163546, 5505, 613, 19, 69, "Text"], Cell[164162, 5526, 278, 6, 143, "Input"], Cell[164443, 5534, 830, 24, 135, "Text"], Cell[165276, 5560, 80, 2, 51, "Input"], Cell[165359, 5564, 242, 9, 42, "Text"], Cell[165604, 5575, 119, 3, 51, "Input"], Cell[165726, 5580, 64, 0, 42, "Text"], Cell[165793, 5582, 81, 2, 51, "Input"], Cell[165877, 5586, 242, 9, 42, "Text"], Cell[166122, 5597, 123, 3, 51, "Input"], Cell[166248, 5602, 334, 6, 96, "Text"], Cell[166585, 5610, 188, 4, 97, "Input"], Cell[166776, 5616, 126, 3, 42, "Text"], Cell[166905, 5621, 78, 2, 51, "Input"], Cell[166986, 5625, 157, 5, 42, "Text"], Cell[167146, 5632, 90, 1, 51, "Input"], Cell[167239, 5635, 55, 1, 51, "Input"], Cell[167297, 5638, 42, 1, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[167376, 5644, 107, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:24"], Cell[167486, 5649, 2389, 75, 333, "Text", Evaluatable->False], Cell[169878, 5726, 250, 5, 120, "Input"], Cell[170131, 5733, 203, 7, 42, "Text", Evaluatable->False], Cell[170337, 5742, 91, 2, 51, "Input"], Cell[170431, 5746, 513, 13, 96, "Text", Evaluatable->False], Cell[170947, 5761, 209, 5, 97, "Input"], Cell[171159, 5768, 409, 9, 96, "Text", Evaluatable->False], Cell[171571, 5779, 219, 4, 74, "Input"], Cell[171793, 5785, 101, 2, 51, "Input"], Cell[171897, 5789, 97, 2, 51, "Input"], Cell[171997, 5793, 164, 5, 42, "Text", Evaluatable->False], Cell[172164, 5800, 203, 5, 120, "Input"], Cell[172370, 5807, 137, 5, 42, "Text", Evaluatable->False], Cell[172510, 5814, 186, 5, 74, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[172745, 5825, 130, 3, 45, "Section", Evaluatable->False, CellTags->{"Regular expressions", "c:2"}], Cell[CellGroupData[{ Cell[172900, 5832, 164, 5, 60, "Subsection", Evaluatable->False, CellTags->"c:3"], Cell[173067, 5839, 885, 15, 231, "Text", Evaluatable->False], Cell[173955, 5856, 1477, 44, 421, "Text", Evaluatable->False], Cell[175435, 5902, 96, 2, 51, "Input"], Cell[175534, 5906, 628, 13, 162, "Text", Evaluatable->False], Cell[176165, 5921, 207, 4, 74, "Input"], Cell[176375, 5927, 113, 2, 51, "Input"], Cell[CellGroupData[{ Cell[176513, 5933, 50, 0, 64, "Subsubsection"], Cell[176566, 5935, 705, 19, 174, "Text", Evaluatable->False], Cell[177274, 5956, 116, 3, 74, "Input"], Cell[177393, 5961, 129, 3, 42, "Text"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[177571, 5970, 130, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:4"], Cell[177704, 5975, 2768, 50, 966, "Text", Evaluatable->False], Cell[180475, 6027, 106, 3, 74, "Input"], Cell[180584, 6032, 108, 3, 74, "Input"], Cell[180695, 6037, 317, 7, 96, "Text", Evaluatable->False], Cell[181015, 6046, 129, 3, 51, "Input"], Cell[181147, 6051, 626, 17, 123, "Text", Evaluatable->False], Cell[181776, 6070, 89, 2, 51, "Input"], Cell[181868, 6074, 447, 12, 96, "Text", Evaluatable->False], Cell[182318, 6088, 252, 6, 97, "Input"], Cell[182573, 6096, 258, 6, 69, "Text", Evaluatable->False], Cell[182834, 6104, 80, 2, 51, "Input"], Cell[182917, 6108, 222, 6, 69, "Text", Evaluatable->False], Cell[183142, 6116, 240, 6, 120, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[183419, 6127, 126, 3, 63, "Subsection", Evaluatable->False, CellTags->"c:4"], Cell[CellGroupData[{ Cell[183570, 6134, 38, 0, 64, "Subsubsection"], Cell[183611, 6136, 1259, 34, 225, "Text", Evaluatable->False], Cell[184873, 6172, 61, 1, 51, "Input"], Cell[184937, 6175, 65, 1, 51, "Input"], Cell[185005, 6178, 65, 1, 51, "Input"], Cell[185073, 6181, 453, 14, 69, "Text", Evaluatable->False], Cell[185529, 6197, 72, 1, 51, "Input"], Cell[185604, 6200, 305, 8, 69, "Text", Evaluatable->False], Cell[185912, 6210, 52, 1, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[186001, 6216, 40, 0, 64, "Subsubsection"], Cell[186044, 6218, 217, 6, 42, "Text"], Cell[186264, 6226, 118, 2, 74, "Input"], Cell[186385, 6230, 226, 8, 42, "Text"], Cell[186614, 6240, 70, 1, 51, "Input"], Cell[186687, 6243, 103, 3, 42, "Text"], Cell[186793, 6248, 60, 1, 51, "Input"], Cell[186856, 6251, 94, 3, 42, "Text"], Cell[186953, 6256, 86, 1, 51, "Input"], Cell[187042, 6259, 88, 1, 51, "Input"], Cell[187133, 6262, 70, 0, 42, "Text"], Cell[187206, 6264, 54, 1, 51, "Input"], Cell[187263, 6267, 100, 3, 42, "Text"], Cell[187366, 6272, 119, 3, 88, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[187534, 6281, 130, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:5"], Cell[CellGroupData[{ Cell[187689, 6289, 179, 6, 64, "Subsubsection", Evaluatable->False, CellTags->"c:6"], Cell[187871, 6297, 138, 5, 42, "Text", Evaluatable->False], Cell[188012, 6304, 74, 0, 50, "Input"], Cell[188089, 6306, 186, 5, 120, "Input"], Cell[188278, 6313, 316, 7, 96, "Text", Evaluatable->False], Cell[188597, 6322, 156, 3, 74, "Input"], Cell[188756, 6327, 405, 10, 69, "Text", Evaluatable->False], Cell[189164, 6339, 230, 5, 120, "Input"], Cell[189397, 6346, 175, 5, 42, "Text", Evaluatable->False], Cell[189575, 6353, 184, 4, 97, "Input"], Cell[189762, 6359, 239, 7, 42, "Text", Evaluatable->False] }, Closed]], Cell[CellGroupData[{ Cell[190038, 6371, 132, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:7"], Cell[190173, 6376, 546, 14, 123, "Text", Evaluatable->False], Cell[190722, 6392, 86, 4, 90, "Input"], Cell[190811, 6398, 149, 5, 42, "Text", Evaluatable->False], Cell[190963, 6405, 116, 2, 51, "Input"], Cell[191082, 6409, 110, 2, 42, "Text", Evaluatable->False], Cell[191195, 6413, 98, 2, 51, "Input"], Cell[191296, 6417, 156, 5, 42, "Text", Evaluatable->False], Cell[191455, 6424, 173, 5, 74, "Input"], Cell[191631, 6431, 154, 5, 42, "Text", Evaluatable->False], Cell[191788, 6438, 226, 5, 97, "Input"], Cell[192017, 6445, 433, 9, 162, "Text", Evaluatable->False], Cell[192453, 6456, 219, 4, 120, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[192709, 6465, 122, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:8"], Cell[192834, 6470, 43, 0, 50, "Input"], Cell[192880, 6472, 172, 4, 97, "Input"], Cell[193055, 6478, 182, 5, 42, "Text", Evaluatable->False], Cell[193240, 6485, 106, 3, 74, "Input"], Cell[193349, 6490, 99, 2, 51, "Input"], Cell[193451, 6494, 146, 2, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[193634, 6501, 134, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:9"], Cell[193771, 6506, 387, 8, 96, "Text", Evaluatable->False], Cell[194161, 6516, 72, 0, 50, "Input"], Cell[194236, 6518, 105, 2, 51, "Input"], Cell[194344, 6522, 78, 2, 51, "Input"], Cell[194425, 6526, 234, 6, 69, "Text", Evaluatable->False], Cell[194662, 6534, 106, 2, 51, "Input"], Cell[194771, 6538, 77, 2, 51, "Input"], Cell[194851, 6542, 160, 4, 74, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[195048, 6551, 128, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:10"], Cell[195179, 6556, 334, 7, 96, "Text", Evaluatable->False], Cell[195516, 6565, 184, 4, 97, "Input"], Cell[195703, 6571, 146, 5, 42, "Text", Evaluatable->False], Cell[195852, 6578, 180, 3, 97, "Input"], Cell[196035, 6583, 94, 2, 42, "Text", Evaluatable->False], Cell[196132, 6587, 97, 2, 51, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[196266, 6594, 118, 3, 64, "Subsubsection", Evaluatable->False, CellTags->"c:11"], Cell[196387, 6599, 268, 6, 69, "Text", Evaluatable->False], Cell[196658, 6607, 80, 3, 70, "Input"], Cell[196741, 6612, 92, 3, 42, "Text"], Cell[196836, 6617, 149, 2, 74, "Input"], Cell[196988, 6621, 68, 0, 42, "Text"], Cell[197059, 6623, 202, 4, 97, "Input"], Cell[197264, 6629, 452, 10, 147, "Text", Evaluatable->False], Cell[197719, 6641, 62, 3, 70, "Input"], Cell[197784, 6646, 202, 4, 97, "Input"], Cell[197989, 6652, 241, 8, 81, "Text", Evaluatable->False], Cell[198233, 6662, 127, 3, 74, "Input"], Cell[198363, 6667, 202, 4, 97, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[198614, 6677, 132, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:5"], Cell[198749, 6683, 638, 13, 189, "Text"], Cell[199390, 6698, 151, 3, 97, "Input"], Cell[199544, 6703, 123, 3, 42, "Text"], Cell[199670, 6708, 59, 1, 51, "Input"], Cell[199732, 6711, 64, 0, 42, "Text"], Cell[199799, 6713, 86, 2, 74, "Input"], Cell[199888, 6717, 33, 0, 42, "Text"], Cell[199924, 6719, 86, 2, 74, "Input"], Cell[200013, 6723, 36, 0, 42, "Text"], Cell[200052, 6725, 86, 2, 74, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[200187, 6733, 119, 3, 45, "Section", Evaluatable->False, CellTags->"c:12"], Cell[CellGroupData[{ Cell[200331, 6740, 159, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:13"], Cell[200493, 6746, 694, 12, 177, "Text", Evaluatable->False], Cell[201190, 6760, 173, 4, 74, "Input"], Cell[201366, 6766, 89, 2, 51, "Input"], Cell[201458, 6770, 245, 6, 69, "Text", Evaluatable->False], Cell[201706, 6778, 98, 2, 51, "Input"], Cell[201807, 6782, 137, 5, 42, "Text", Evaluatable->False], Cell[201947, 6789, 140, 4, 97, "Input"], Cell[202090, 6795, 277, 10, 42, "Text", Evaluatable->False], Cell[202370, 6807, 140, 4, 51, "Input"], Cell[202513, 6813, 115, 2, 42, "Text", Evaluatable->False], Cell[202631, 6817, 88, 2, 51, "Input"], Cell[202722, 6821, 259, 6, 69, "Text", Evaluatable->False], Cell[202984, 6829, 231, 6, 143, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[203252, 6840, 159, 4, 60, "Subsection", Evaluatable->False, CellTags->"c:14"], Cell[203414, 6846, 764, 13, 204, "Text", Evaluatable->False], Cell[204181, 6861, 46, 1, 51, "Input"], Cell[204230, 6864, 287, 6, 120, "Input"], Cell[204520, 6872, 89, 2, 51, "Input"], Cell[204612, 6876, 89, 2, 51, "Input"], Cell[204704, 6880, 79, 2, 51, "Input"], Cell[204786, 6884, 85, 2, 51, "Input"], Cell[204874, 6888, 79, 2, 51, "Input"], Cell[204956, 6892, 309, 7, 96, "Text", Evaluatable->False], Cell[205268, 6901, 212, 4, 74, "Input"], Cell[205483, 6907, 110, 2, 51, "Input"], Cell[205596, 6911, 80, 2, 51, "Input"], Cell[205679, 6915, 243, 9, 42, "Text", Evaluatable->False], Cell[205925, 6926, 215, 4, 97, "Input"], Cell[206143, 6932, 79, 2, 51, "Input"], Cell[206225, 6936, 86, 2, 51, "Input"], Cell[206314, 6940, 86, 2, 51, "Input"], Cell[206403, 6944, 80, 2, 51, "Input"], Cell[206486, 6948, 86, 2, 51, "Input"], Cell[206575, 6952, 80, 2, 51, "Input"], Cell[206658, 6956, 155, 4, 51, "Input"], Cell[206816, 6962, 79, 2, 51, "Input"], Cell[206898, 6966, 719, 16, 201, "Text", Evaluatable->False], Cell[207620, 6984, 185, 4, 97, "Input"], Cell[207808, 6990, 79, 2, 51, "Input"], Cell[207890, 6994, 86, 2, 51, "Input"], Cell[207979, 6998, 86, 2, 51, "Input"], Cell[208068, 7002, 80, 2, 51, "Input"], Cell[208151, 7006, 86, 2, 51, "Input"], Cell[208240, 7010, 80, 2, 51, "Input"], Cell[208323, 7014, 155, 4, 51, "Input"], Cell[208481, 7020, 416, 11, 120, "Text", Evaluatable->False] }, Closed]] }, Closed]] } ] *) (******************************************************************* End of Mathematica Notebook file. *******************************************************************)