public (string, string) ConvertNFAToRegEx() { RegexAutomata regexAutomata = NFAtoRegEx.ConvertNFAToRegEx(automata); CreateAutomatePicture(NFAtoRegEx.CreateRegexAutomataDotString(regexAutomata)); return(regexAutomata.Nodes[0].Connections[0].Expression, regexAutomata.Nodes[0].Connections[0].PreExpr); }
public void RerouteTransitions(RegexNode toNode, RegexAutomata automata) { (List <RegexConnection>, string, string)splitTransitions = SplitSelfLoopingTransition(toNode); List <RegexConnection> toTransitionList = splitTransitions.Item1; string betweenTransition = splitTransitions.Item2; string betweenPreTransition = splitTransitions.Item3; foreach (RegexNode node in automata.Nodes) { //can assume this is only once since we union all double transitions RegexConnection pruneConnection = null; List <RegexConnection> addList = new List <RegexConnection>(); if (node != toNode) { foreach (RegexConnection trans in node.Connections) { if (trans.ToNode == toNode) { pruneConnection = trans; foreach (RegexConnection toTransition in toTransitionList) { string newExpression = CreateNewExpressionString(trans.Expression, betweenTransition, toTransition.Expression); string newPreExpr = CreateNewPreExpressionString(trans.PreExpr, betweenPreTransition, toTransition.PreExpr); addList.Add(new RegexConnection(newExpression, newPreExpr, toTransition.ToNode)); } } } } node.Connections.Remove(pruneConnection); node.Connections.AddRange(addList); } automata.Nodes.Remove(toNode); }
public string CreateRegexAutomataDotString(RegexAutomata automata) { string dotString = ""; dotString += "digraph myAutomaton { \nrankdir=LR; \n\"\" [shape=none] \n"; foreach (RegexNode node in automata.Nodes) { string shape = "circle"; if (node.Final) { shape = "doublecircle"; } dotString += $"\"{node.Name}\" [shape={shape}] \n"; } dotString += "\n"; dotString += $"\"\" -> \"{automata.Nodes[0].Name}\" \n"; foreach (RegexNode node in automata.Nodes) { foreach (RegexConnection conn in node.Connections) { string expres = conn.Expression.Replace("∪", "|"); dotString += $"\"{node.Name}\" -> \"{conn.ToNode.Name}\" [label=\"{expres}\"] \n"; } } dotString += "}"; return(dotString); }
public RegexAutomata ConvertNFAToRegEx(Automata automata) { RegexAutomata regexAutomata = new RegexAutomata(automata); UnionMultipleTransitions(regexAutomata); regexAutomata = PruneNodes(regexAutomata); return(regexAutomata); }
public RegexAutomata PruneNodes(RegexAutomata automata) { int nodeCount = automata.Nodes.Count - 2; if (nodeCount - 2 < 5) { RegexAutomata smalllestRegexGnfa = null; IEnumerable <IEnumerable <int> > allPermutations = GetPermutations(Enumerable.Range(1, nodeCount), nodeCount); foreach (IEnumerable <int> permutation in allPermutations) { RegexAutomata automataCopy = automata.DeepClone(); List <RegexNode> nodeOrder = new List <RegexNode>(); foreach (int nodeIndex in permutation) { nodeOrder.Add(automataCopy.Nodes[nodeIndex]); } foreach (RegexNode currentNode in nodeOrder) { RerouteTransitions(currentNode, automataCopy); UnionMultipleTransitions(automataCopy); } Console.WriteLine($"Permutation {{{PermutationString(permutation)}}}: {automataCopy.Nodes[0].Connections[0].PreExpr}"); if (smalllestRegexGnfa == null || smalllestRegexGnfa.Nodes[0].Connections[0].PreExpr.Length > automataCopy.Nodes[0].Connections[0].PreExpr.Length) { smalllestRegexGnfa = automataCopy; } } return(smalllestRegexGnfa); } else { while (automata.Nodes.Count > 2) { RegexNode currentNode = automata.Nodes[1]; RerouteTransitions(currentNode, automata); UnionMultipleTransitions(automata); } return(automata); } }
public void UnionMultipleTransitions(RegexAutomata automata) { foreach (RegexNode node in automata.Nodes) { Dictionary <RegexNode, List <RegexConnection> > transitionsPerNode = new Dictionary <RegexNode, List <RegexConnection> >(); foreach (RegexConnection trans in node.Connections) { if (transitionsPerNode.ContainsKey(trans.ToNode)) { transitionsPerNode[trans.ToNode].Add(trans); } else { transitionsPerNode.Add(trans.ToNode, new List <RegexConnection>() { trans }); } } if (transitionsPerNode.Count != node.Connections.Count) { List <RegexConnection> newTransitions = new List <RegexConnection>(); foreach (KeyValuePair <RegexNode, List <RegexConnection> > valuePair in transitionsPerNode) { HashSet <string> uniqueExprs = new HashSet <string>(); HashSet <string> uniquePreExprs = new HashSet <string>(); foreach (RegexConnection connection in valuePair.Value) { uniqueExprs.Add(connection.Expression); uniquePreExprs.Add(connection.PreExpr); } //infix expr string newExpr = ""; foreach (string expr in uniqueExprs) { if (expr.Length == 1 || (expr.Substring(0, 1).Equals("(") && expr.Substring(expr.Length - 1, 1).Equals(")"))) { newExpr += $"{expr}∪"; } else { newExpr += $"({expr})∪"; } } string newPreExpr = ""; //prefix expr bool firstPreExpr = false; foreach (string preExpr in uniquePreExprs) { if (!firstPreExpr) { firstPreExpr = true; newPreExpr = preExpr; } else { newPreExpr = $"|({newPreExpr},{preExpr})"; } } newTransitions.Add(new RegexConnection(newExpr.Substring(0, newExpr.Length - 1), newPreExpr, valuePair.Key)); } node.Connections = newTransitions; } } }