public NondeterministicFiniteAutomaton(States q, Alphabet a, NondeterministicTransitionFunction d, State q0, AcceptingStates f) : base(q, a, d, q0, f) { Transitions = d; }
private async Task <bool> Run(char[] x, State p, int i) { for (; i < x.Length; i++) { if (!Alphabet.Contains(x[i])) { return(false); } if (x[i] == Alphabet.EmptyString) { continue; } // get possible transitions var q = Transitions[p, x[i]]; if (q.Length == 0) // nothing to do, stop { return(false); } if (q.Length == 1) { p = q[0].Q; // switch states if (q[0].A == Alphabet.EmptyString) { i--; // Don't increment on null transition! } } else // we have a choice { var tasks = new Task <bool> [q.Length]; // check each path asynchronously for (var j = 0; j < q.Length; j++) { tasks[j] = Run(x, q[j].Q, q[j].A == Alphabet.EmptyString ? i : i + 1); } var result = false; // check the result foreach (var t in tasks) { result = result || await t; } return(result); // if one of them is successful, this branch accepts } } // No more moves! if (p.Accepting) { return(true); } // check for lambda transitions var r = Transitions[p, Alphabet.EmptyString]; var lambdas = new Task <bool> [r.Length]; for (var k = 0; k < r.Length; k++) { lambdas[k] = Run(x, r[k].Q, i); } var accept = false; foreach (var t in lambdas) { accept = accept || await t; } return(accept); }
private async Task <bool> Run(char[] x, State p, int i, Stack <char> stack) { for (; i < x.Length; i++) { if (!Alphabet.Contains(x[i])) { return(false); } if (x[i] == Alphabet.EmptyString) { continue; } // Get possible transitions var q = Transitions[p, x[i], stack.Peek()]; if (q.Length == 0) // nothing to do, stop { return(false); } if (q.Length == 1) { // try to update the stack. if we are out of bounds, reject try { stack = updateStack(stack, q[0].Top, q[0].Replace); } catch (Exception) { return(false); } p = q[0].Q; if (q[0].A == Alphabet.EmptyString) { i--; // Don't increment on null transition! } } else { var tasks = new Task <bool> [q.Length]; // check each path asynchronously for (var j = 0; j < q.Length; j++) { var s = new Stack <char>(stack); try { s = updateStack(s, q[j].Top, q[j].Replace); } catch (Exception) { continue; } tasks[j] = Run(x, q[j].Q, q[j].A == Alphabet.EmptyString ? i : i + 1, s); } var result = false; foreach (var t in tasks) { result = result || (t != null && await t); } return(result); } } // No more moves! if (p.Accepting) { return(true); } // check for lambda transitions var r = Transitions[p, Alphabet.EmptyString, stack.Peek()]; var lambdas = new Task <bool> [r.Length]; for (var k = 0; k < r.Length; k++) { var s = new Stack <char>(stack); try { s = updateStack(s, r[k].Top, r[k].Replace); } catch (Exception) { continue; } lambdas[k] = Run(x, r[k].Q, i, s); } var accept = false; foreach (var t in lambdas) { accept = accept || (t != null && await t); } return(accept); }