internal static PDA <char, char> ParsePDAFromXmlPDA(XElement xmlPDA) { var properties = xmlPDA.Elements().Where(el => el.Name.LocalName == XmlNames.Properties).First(); var deterministic = bool.Parse(properties.Elements().Where(el => el.Name.LocalName == XmlNames.Determinism).First().Value); var acceptanceCondition = AcceptanceCondition.GetAcceptanceConditionById(properties.Elements().Where(el => el.Name.LocalName == XmlNames.AcceptanceCondition).First().Value); var allStackSymbolsAsStrings = properties.Elements().Where(el => el.Name.LocalName == XmlNames.StackAlphabet).First().Elements().Select(s => s.Value).ToList(); Assertion.Assert(allStackSymbolsAsStrings.All(s => s.Length == 1), "stack symbols must be chars"); var allStackSymbols = allStackSymbolsAsStrings.Select(s => s.First()); var firstStackSymbol = allStackSymbols.First(); //FIXME: what if all keys are used as stack symbols?? var initialState = xmlPDA.Elements().Where(el => el.Name.LocalName == XmlNames.Nodes).First().Elements().Where(el => el.Name.LocalName == XmlNames.InitialState).First(); Assertion.Assert(int.Parse(initialState.Attribute(XmlAttr.Id).Value) == PDA <char, char> .initialStateId, "the initial state has to have id " + PDA <char, char> .initialStateId); var initialStateIsFinal = bool.Parse(initialState.Attribute(XmlAttr.IsFinal).Value); var pda = new PDA <char, char>(acceptanceCondition, deterministic, firstStackSymbol, initialStateIsFinal, allStackSymbols, allStackAlphabetSymbols.First(k => !allStackSymbols.Contains(k))); AddStatesToPda(pda, xmlPDA); AddTransitionsToPda(pda, xmlPDA); return(pda); }
private static void AddInitialTransition(PDA <A, S> pda, PDA <A, S> newPDA, Func <int, int> transformer) { newPDA.AddTransition().From(newPDA.InitialState.Id).To(transformer(pda.InitialState.Id)).Read().Pop(newPDA.FirstStackSymbol).Push(new List <S>() { pda.FirstStackSymbol, newPDA.FirstStackSymbol }); }
private static void AddEmptyingTransitions(PDA <A, S> newPDA, int newStateId) { foreach (var stackSymbol in newPDA.AllStackSymbols) { newPDA.AddTransition().From(newStateId).To(newStateId).Read().Pop(stackSymbol).Push(); } }
private static void AddStatesToPda(PDA <char, char> pda, XElement xmlPDA) { foreach (var node in xmlPDA.Elements().Where(el => el.Name.LocalName == XmlNames.Nodes).First().Elements().Where(el => el.Name.LocalName == XmlNames.InnerState)) { pda.AddState(int.Parse(node.Attribute(XmlAttr.Id).Value), Boolean.Parse(node.Attribute(XmlAttr.IsFinal).Value)); } }
private static int AddNewState(PDA <A, S> newPDA) { var newStateId = newPDA.States.Max(n => n.Key) + 1; newPDA.AddState(newStateId, false); return(newStateId); }
private static void AddStatesOfOriginalPDA(PDA <A, S> pda, PDA <A, S> newPDA, Func <int, int> transformer) { foreach (var state in pda.States) { newPDA.AddState(transformer(state.Key), false); } }
/// <summary> /// Merges the both given DPDA with acceptance condition 'empty stack' into a new one, that simply contains both DPDAs. The initial state /// of the result DPDA has two transitions, one to the initial state of pda1 and one to the initial state of pda2, each of these transitions /// reads the corresponding given stack symbol. That means, for simulating pda1 with the merged one you just have to start the simulation /// with the initialStackSymbol1 as start configuration /// </summary> /// <param name="dpda1">DPDA with empty stack</param> /// <param name="dpda2">DPDA with empty stack</param> /// <param name="initialStackSymbol1">the stack symbol that signals that the first DPDA should be simulated</param> /// <param name="initialStackSymbol2">the stack symbol that signals that the second DPDA should be simulated</param> /// <returns>the merged DPDA</returns> public static PDA <A, S> MergeDPDAsWithEmptyStack(PDA <A, S> dpda1, PDA <A, S> dpda2, S initialStackSymbol1, S initialStackSymbol2) { Assertion.Assert(dpda1.Deterministic, NotDeterministicError); Assertion.Assert(dpda2.Deterministic, NotDeterministicError); Assertion.Assert(dpda1.AcceptanceCondition.IsEmptyStack(), NotEmptyStackError); Assertion.Assert(dpda2.AcceptanceCondition.IsEmptyStack(), NotEmptyStackError); Assertion.Assert(!initialStackSymbol1.Equals(initialStackSymbol2), "the both initial stack symbols must not be the same"); var newStackSymbols = dpda1.AllStackSymbols.Concat(dpda2.AllStackSymbols).Concat(new S[] { initialStackSymbol1, initialStackSymbol2 }).Distinct(); var res = new PDA <A, S>(new AcceptanceCondition.EmptyStack(), true, initialStackSymbol1, false, newStackSymbols); int idTransformer1(int id) => id + 1; int maxIdOfDPDA1 = dpda1.States.Max(s => s.Key) + 1; int idTransformer2(int id) => idTransformer1(id + maxIdOfDPDA1); AddStatesOfOriginalPDA(dpda1, res, idTransformer1); AddStatesOfOriginalPDA(dpda2, res, idTransformer2); AddTransitionsOfOriginalPDA(dpda1, res, idTransformer1); AddTransitionsOfOriginalPDA(dpda2, res, idTransformer2); res.AddTransition().From(res.InitialState.Id).To(idTransformer1(dpda1.InitialState.Id)).Read().Pop(initialStackSymbol1).Push(new List <S>() { dpda1.FirstStackSymbol }); res.AddTransition().From(res.InitialState.Id).To(idTransformer2(dpda2.InitialState.Id)).Read().Pop(initialStackSymbol2).Push(new List <S>() { dpda2.FirstStackSymbol }); return(res); }
/// <summary> /// runs an approximative equality test of a <see cref="pdaCorrect"/> and a <see cref="pdaAttempt"/> /// </summary> /// <param name="pdaCorrect">PDA assumed to be the correct PDA</param> /// <param name="pdaAttempt">PDA to be testet if it equals the <see cref="pdaCorrect"/></param> /// <param name="alphabet">alphabet of the both PDAs</param> /// <param name="maximumWordLengthTested">the maximum length of words out of letters of the <see cref="alphabet"/>, which is tested for, if the PDAs accept them</param> /// <param name="maximumNumberOfWords">an upper bound for number of words to be tested</param> /// <param name="maximumMilliSeconds">an upper bound for the time the test should need</param> public PDAEqualityResult(PDA <char, S> pdaCorrect, PDA <char, T> pdaAttempt, IEnumerable <char> alphabet, int maximumWordLengthTested, int maximumNumberOfWords, int maximumMilliSeconds) { this.pdaCorrect = pdaCorrect; this.pdaAttempt = pdaAttempt; this.alphabet = alphabet; CheckWordsUntilLength(maximumWordLengthTested, maximumNumberOfWords, maximumMilliSeconds); }
private static void AddTransitionsForAddedSymbol(PDA <A, S> pda, PDA <A, S> newPDA, S lowestStackSymbol, A addedSymbol, Func <int, int> transformer) { foreach (var state in pda.States.ToList()) { var newId = transformer(state.Key); newPDA.AddTransition().From(newId).To(newId).Read(Symbol <A> .SymbolIn(addedSymbol)).Pop(lowestStackSymbol).Push(); } }
/// <summary> /// creates a new PDA, that accepts the same language as the given PDA, but with empty stack as acceptance condition; the given PDA is assumed to have final state as acceptance condition /// </summary> /// <param name="pda"></param> /// <returns></returns> internal static PDA <A, S> ToPDAWithEmptyStack(PDA <A, S> pda) { int idTransformer(int id) => id + 1; var pdaAndNewStateId = ToRawPDA(pda, idTransformer, false); AddTransitionsToEmptyingState(pda, pdaAndNewStateId.Item1, pdaAndNewStateId.Item2, Symbol <A> .EpsilonIn(), idTransformer); return(pdaAndNewStateId.Item1); }
private static void AddTransitionsToEmptyingState(PDA <A, S> pda, PDA <A, S> newPDA, int newStateId, Symbol <A> symbolIn, Func <int, int> transformer) { foreach (var finalState in pda.States.Where(s => s.Value.Final).ToList()) { foreach (var stackSymbol in newPDA.AllStackSymbols) { newPDA.AddTransition().From(transformer(finalState.Key)).To(newStateId).Read(symbolIn).Pop(stackSymbol).Push(); } } }
private static void AddTransitionsOfOriginalPDA(PDA <A, S> pda, PDA <A, S> newPDA, Func <int, int> transformer) { foreach (var state in pda.States) { var transitions = state.Value.Transitions; foreach (var t in transitions) { newPDA.AddTransition().From(transformer(state.Key)).To(transformer(t.Target.Id)).Read(t.SymbolIn).Pop(t.StackSymbolIn).Push(t.StackSymbolsWritten); } } }
public bool Equals(PDA <A, S> other) { var part1 = AcceptanceCondition.Equals(other.AcceptanceCondition); var part2 = Deterministic == other.Deterministic; var part3 = InitialState.Equals(other.InitialState); var part4 = FirstStackSymbol.Equals(other.FirstStackSymbol); var part5 = AllStackSymbols.OrderBy(s => s.ToString()).SequenceEqual(other.AllStackSymbols.OrderBy(s => s.ToString())); var part6 = States.Values.OrderBy(s => s.Id).SequenceEqual(other.States.Values.OrderBy(s => s.Id)); return(part1 && part2 && part3 && part4 && part5 && part6); }
/// <summary> /// transforms the given DPDA d with acceptance condition 'final state' to a DPDA with acceptance condition 'empty stack', /// that accepts the language {wa | w \element L(d)}, where "a" is the further alphabet symbol. /// The added symbol is necessary to keep the determinism-property of the DPDA /// </summary> /// <param name="pda">the DPDA with acceptance condition 'final state', that should be transformed</param> /// <param name="furtherAlphabetSymbol">the symbol, which is added to every word in the language of the given DPDA</param> /// <returns>the transformed DPDA</returns> public static PDA <A, S> ToDPDAWithEmptyStack(PDA <A, S> pda, A furtherAlphabetSymbol) { Assertion.Assert(pda.Deterministic, String.Format(NotDeterministicError, "")); int idTransformer(int id) => id + 1; var pdaAndNewStateId = ToRawPDA(pda, idTransformer, true); AddTransitionsToEmptyingState(pda, pdaAndNewStateId.Item1, pdaAndNewStateId.Item2, Symbol <A> .SymbolIn(furtherAlphabetSymbol), idTransformer); return(pdaAndNewStateId.Item1); }
private static Tuple <PDA <A, S>, int> ToRawPDA(PDA <A, S> pda, Func <int, int> idTransformer, bool deterministic) { Assertion.Assert(pda.AcceptanceCondition.IsFinalState(), AlreadyEmptyStackError); var res = new PDA <A, S>(new AcceptanceCondition.EmptyStack(), deterministic, pda.FurtherStackSymbol, false, pda.AllStackSymbols.Concat(new S[] { pda.FurtherStackSymbol })); AddStatesOfOriginalPDA(pda, res, idTransformer); var newStateId = AddNewState(res); AddTransitionsOfOriginalPDA(pda, res, idTransformer); AddInitialTransition(pda, res, idTransformer); AddEmptyingTransitions(res, newStateId); return(new Tuple <PDA <A, S>, int>(res, newStateId)); }
/// <summary> /// transforms the given DPDA d into a new DPDA e with language L(e) = {wa | w \element L(d)}, where "a" is the added symbol /// </summary> /// <param name="dpda">the DPDA to transform</param> /// <param name="addedSymbol">the symbol, which is added to every word in the language of the given DPDA</param> /// <returns>the transformed DPDA</returns> public static PDA <A, S> ToDPDAWithAddedAlphabetSymbol(PDA <A, S> dpda, A addedSymbol) { Assertion.Assert(dpda.Deterministic, NotDeterministicError); Assertion.Assert(dpda.AcceptanceCondition.IsEmptyStack(), NotEmptyStackError); Assertion.Assert(dpda.States.All(s => s.Value.Transitions.All(t => t.SymbolIn.IsEmpty() || !t.SymbolIn.GetSymbol().Equals(addedSymbol))), InvalidSymbolError); var res = new PDA <A, S>(new AcceptanceCondition.EmptyStack(), true, dpda.FurtherStackSymbol, false, dpda.AllStackSymbols.Concat(new S[] { dpda.FurtherStackSymbol })); int idTransformer(int id) => id + 1; AddStatesOfOriginalPDA(dpda, res, idTransformer); AddTransitionsOfOriginalPDA(dpda, res, idTransformer); AddInitialTransition(dpda, res, idTransformer); AddTransitionsForAddedSymbol(dpda, res, dpda.FurtherStackSymbol, addedSymbol, idTransformer); return(res); }
public PDA <A, S> Clone() { var res = new PDA <A, S>(AcceptanceCondition, true, FirstStackSymbol, InitialState.Final, AllStackSymbols.ToList()); foreach (var state in States.Where(s => s.Key != initialStateId).ToList()) { res.AddState(state.Key, state.Value.Final); } foreach (var state in States) { foreach (var t in state.Value.Transitions) { res.AddTransition().From(t.Origin.Id).To(t.Target.Id).Read(t.SymbolIn).Pop(t.StackSymbolIn).Push(t.StackSymbolsWritten); } } return(res); }
private static void AddTransitionsToPda(PDA <char, char> pda, XElement xmlPDA) { //FIXME: if deterministic is true, but a transition violations the determinism property, then throw a suitable exception, which is catched in the Grader foreach (var link in xmlPDA.Elements().Where(el => el.Name.LocalName == XmlNames.Links).First().Elements().Where(el => el.Name.LocalName == XmlNames.Link)) { var start = int.Parse(link.Attribute(XmlAttr.Start).Value); var target = int.Parse(link.Attribute(XmlAttr.End).Value); foreach (var transition in link.Elements().Where(el => el.Name.LocalName == XmlNames.TransitionGroup).First().Elements().Where(el => el.Name.LocalName == XmlNames.Transition)) { var inputSymbol = transition.Value[0] == Epsilon ? Symbol <char> .EpsilonIn() : Symbol <char> .SymbolIn(transition.Value[0]); var inputStackSymbol = transition.Value[2]; var writtenStackSymbols = transition.Value.Skip(4); pda.AddTransition().From(start).To(target).Read(inputSymbol).Pop(inputStackSymbol).Push(writtenStackSymbols); } } }
static internal FromBuilder BuildTrasition(PDA <A, S> pda) { return(new FromBuilder(new TransitionBuilder <A, S>(pda))); }
internal TransitionBuilder(PDA <A, S> pda) { this.pda = pda; }