public void UpdateTransition(SimpleTransition t) { if (t == null) { throw new ArgumentNullException(); } t.Source.Delta[t.Read] = t; FullDefinitionString += " " + t.ToString(this) + ";"; UpdateShortDefinitionString(); }
public string GetShortDefinitionString(int?changeSuggestedMacroSize, SimpleTransition additionalTransition) { var s = ""; foreach (var q in Q.OrderBy(x => x.Key).Select(x => x.Value)) { if (s.Length > 0) { s += ","; } var ts = new List <SimpleTransition> (); if (q.Delta != null) { ts.AddRange(q.Delta); } if (additionalTransition != null && q == additionalTransition.Source) { if (ts.Any()) { if (ts[additionalTransition.Read] != null) { throw new InvalidOperationException("Tried to replace an existing transition in delta table."); } ts[additionalTransition.Read] = additionalTransition; } else { throw new Exception("ist das so ok?"); ts.Add(additionalTransition); } } foreach (var t in ts) { if (s.Length > 0) { s += " "; } if (t == null) { s += "---"; } else { s += t.Write; s += t.Direction == 1 ? "R" : "L"; s += t.Next.Name; } } } var k = changeSuggestedMacroSize ?? SuggestedMacroSize; if (k != null) { s += " K=" + k.Value; } return(s); }
public TmDefinition(JsonTmDefinition def) { if (def == null) { throw new ArgumentNullException(); } Gamma = MapSymbols(def.Gamma, 0); Sigma = new Dictionary <byte, string> (); foreach (var sig in def.Sigma) { Sigma.Add(Gamma.Where(p => p.Value == sig).First().Key, sig); } Func <string, State> createState = name => { var halting = false || def.AcceptingState == name || def.RefusingState == name; var ts = halting ? null : new SimpleTransition[Gamma.Count]; var q = new State(Q.Count, name, ts); Q.Add(name, q); return(q); }; Q0 = createState(def.InitialState); foreach (var qs in def.NonfinalStates) { if (qs == def.InitialState) { continue; } createState(qs); } if (def.AcceptingState != null) { createState(def.AcceptingState); } if (def.RefusingState != null) { createState(def.RefusingState); } foreach (var t in def.Delta) { var qin = Q[t.From]; byte gin = Gamma.First(p => p.Value == t.Read).Key; var qout = Q[t.To]; byte gout = Gamma.First(p => p.Value == t.Write).Key; short dir; switch (t.Dir) { case "R": dir = 1; break; case "L": dir = -1; break; case "S": dir = 0; break; default: throw new Exception(); } var st = new SimpleTransition(qin, gin, qout, gout, dir); qin.Delta[gin] = st; qout.Sources.Add(st); } SuggestedMacroSize = def.SuggestedMacroSize; UpdateShortDefinitionString(); }
/// <summary> /// </summary> /// <param name="s"> /// Format: /// q0,q1,...; Q /// s0,s1,...; Sigma /// g0,g1,...; Gamma without Sigma /// q,i -> q',o,d; Single Delta transition, repeatable /// K=n; Suggested macro width, optional /// /* anywhere: comments in old C style allowed */ /// </param> public TmDefinition(string s) { if (s == null) { throw new ArgumentNullException(); } if (s.Count(c => c == ';') <= 1) // todo: bug when ';' in comments { s = DefinitionLibrary.CreateBeaverFromNote(s); } FullDefinitionString = s; s = StripComments(s); var split = s.Split(';').Select(x => x.Trim()).ToList(); var sStates = split[0]; split.RemoveAt(0); var sHalting = split[0]; split.RemoveAt(0); var sSigma = split[0]; split.RemoveAt(0); var sGamma = split[0]; split.RemoveAt(0); /* * Sigma/Gamma */ var sigmasplit = sSigma.Split(','); var gammasplit = sGamma.Split(','); Sigma = MapSymbols(sigmasplit, 1); Gamma = MapSymbols(gammasplit.Skip(1), 1 + Sigma.Count); Gamma.Add(0, gammasplit[0]); foreach (var sig in Sigma) { Gamma.Add(sig.Key, sig.Value); } /* * Q * (can only be constructed once Gamma is known) */ var statessplit = sStates.Split(','); foreach (var p in statessplit.Select(x => x.Trim())) { if (p == "") { continue; } if (Q.Count >= 255) { throw new Exception(); } var q = new State((byte)Q.Count, p, new SimpleTransition[Gamma.Count]); Q.Add(p, q); if (Q0 == null) { Q0 = q; } } foreach (var p in sHalting.Split(',').Select(x => x.Trim())) { if (p == "") { continue; } if (Q.Count >= 255) { throw new Exception(); } var q = new State((byte)Q.Count, p, null); Q.Add(p, q); if (Q0 == null) { Q0 = q; } } var haltingStates = Q.Values.Where(q => q.Delta == null).ToArray(); if (haltingStates.Length == 0) { var nonhaltingStates = Q.OrderBy(x => x.Key).Select(x => x.Value).ToArray(); Qa = nonhaltingStates[nonhaltingStates.Length - 2]; Qr = nonhaltingStates[nonhaltingStates.Length - 1]; } else if (haltingStates.Length == 1) { Qa = haltingStates[0]; Qr = null; } else { Qa = haltingStates[0]; Qr = haltingStates[1]; } // Here be dragons /* * Delta */ while (split.Any()) { var d = split[0]; d = d.TrimStart(' ', '\t'); split.RemoveAt(0); if (d == "") { continue; } if (d.StartsWith("K=")) { d = d.Substring(2); SuggestedMacroSize = Unlog.Util.StringCutting.CutInt(ref d); split.Insert(0, d); continue; } var parts = d.Split(new[] { "->" }, 2, StringSplitOptions.None); var input = parts[0].Split(',').Select(x => x.Trim()).ToArray(); var output = parts[1].Split(',').Select(x => x.Trim()).ToArray(); var sqin = input[0]; var stin = input[1]; var sqout = output[0]; var stout = output[1]; var sd = output[2].ToUpperInvariant(); // Check different notation if (sd != "L" && sd != "R") { if (stout == "L" || stout == "R") { var tmp = sd; sd = stout; stout = sqout; sqout = tmp; } } var qin = Q[sqin]; byte gin = Gamma.First(p => p.Value == stin).Key; var qout = Q[sqout]; byte gout = Gamma.First(p => p.Value == stout).Key; short dir; switch (sd) { case "R": dir = 1; break; case "L": dir = -1; break; case "S": dir = 0; break; default: throw new Exception(); } var t = new SimpleTransition(qin, gin, qout, gout, dir); qin.Delta[gin] = t; qout.Sources.Add(t); } UpdateShortDefinitionString(); }