annotate Implab/Automaton/DFATable.cs @ 169:54270c2f29f2 ref20160224

DFA refactoring
author cin
date Thu, 03 Mar 2016 08:41:02 +0300
parents
children 0f70905b4652
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
169
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
1 using Implab;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
2 using System;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
3 using System.Collections.Generic;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
4 using System.Linq;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
5
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
6 namespace Implab.Automaton {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
7 public class DFATable : IDFATableBuilder {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
8 DFAStateDescriptior[] m_dfaTable;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
9
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
10 int m_stateCount;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
11 int m_symbolCount;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
12 int m_initialState;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
13
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
14 readonly HashSet<int> m_finalStates = new HashSet<int>();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
15 readonly HashSet<AutomatonTransition> m_transitions = new HashSet<AutomatonTransition>();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
16
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
17 void AssertNotReadOnly() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
18 if (m_dfaTable != null)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
19 throw new InvalidOperationException("The object is readonly");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
20 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
21
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
22
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
23 #region IDFADefinition implementation
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
24
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
25 public DFAStateDescriptior[] GetTransitionTable() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
26 if (m_dfaTable == null) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
27 if (m_stateCount <= 0)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
28 throw new InvalidOperationException("Invalid automaton definition: states count = {0}", m_stateCount);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
29 if (m_symbolCount <= 0)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
30 throw new InvalidOperationException("Invalid automaton definition: symbols count = {0}", m_symbolCount);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
31
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
32 m_dfaTable = ConstructTransitionTable();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
33 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
34 return m_dfaTable;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
35 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
36
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
37 public bool IsFinalState(int s) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
38 Safe.ArgumentInRange(s, 0, m_stateCount, "s");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
39
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
40 return m_dfaTable != null ? m_dfaTable[s].final : m_finalStates.Contains(s);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
41 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
42
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
43 public IEnumerable<int> FinalStates {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
44 get {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
45 return m_finalStates;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
46 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
47 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
48
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
49 public int StateCount {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
50 get { return m_stateCount; }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
51 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
52
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
53 public int AlphabetSize {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
54 get { return m_symbolCount; }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
55 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
56
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
57 public int InitialState {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
58 get { return m_initialState; }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
59 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
60
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
61 #endregion
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
62
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
63 protected virtual DFAStateDescriptior[] ConstructTransitionTable() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
64 var dfaTable = new DFAStateDescriptior[m_stateCount];
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
65
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
66
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
67 foreach (var t in m_transitions) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
68 if (dfaTable[t.s1].transitions == null)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
69 dfaTable[t.s1] = new DFAStateDescriptior(m_symbolCount, m_finalStates.Contains(t.s1));
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
70
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
71 dfaTable[t.s1].transitions[t.edge] = t.s2;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
72 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
73
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
74 foreach (var s in m_finalStates)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
75 if (!dfaTable[s].final)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
76 m_dfaTable[s] = new DFAStateDescriptior(m_symbolCount, true);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
77
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
78 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
79
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
80 public void SetInitialState(int s) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
81 Safe.ArgumentAssert(s >= 0, "s");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
82 m_initialState = s;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
83 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
84
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
85 public void MarkFinalState(int state) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
86 AssertNotReadOnly();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
87 m_finalStates.Add(state);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
88 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
89
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
90 public void Add(AutomatonTransition item) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
91 AssertNotReadOnly();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
92 Safe.ArgumentAssert(item.s1 >= 0, "item");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
93 Safe.ArgumentAssert(item.s2 >= 0, "item");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
94 Safe.ArgumentAssert(item.edge >= 0, "item");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
95
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
96 m_stateCount = Math.Max(m_stateCount, Math.Max(item.s1, item.s2) + 1);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
97 m_symbolCount = Math.Max(m_symbolCount, item.edge);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
98
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
99 m_transitions.Add(item);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
100 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
101
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
102 public void Clear() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
103 AssertNotReadOnly();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
104
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
105 m_stateCount = 0;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
106 m_symbolCount = 0;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
107 m_finalStates.Clear();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
108 m_transitions.Clear();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
109 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
110
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
111 public bool Contains(AutomatonTransition item) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
112 return m_transitions.Contains(item);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
113 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
114
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
115 public void CopyTo(AutomatonTransition[] array, int arrayIndex) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
116 m_transitions.CopyTo(array, arrayIndex);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
117 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
118
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
119 public bool Remove(AutomatonTransition item) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
120 AssertNotReadOnly();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
121 m_transitions.Remove(item);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
122 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
123
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
124 public int Count {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
125 get {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
126 return m_transitions.Count;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
127 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
128 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
129
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
130 public bool IsReadOnly {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
131 get {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
132 return m_dfaTable != null;
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
133 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
134 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
135
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
136 public IEnumerator<AutomatonTransition> GetEnumerator() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
137 return m_transitions.GetEnumerator();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
138 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
139
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
140 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
141 return GetEnumerator();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
142 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
143
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
144 /// <summary>Формирует множества конечных состояний перед началом работы алгоритма минимизации.</summary>
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
145 /// <remarks>
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
146 /// В процессе построения минимального автомата требуется разделить множество состояний,
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
147 /// на два подмножества - конечные состояния и все остальные, после чего эти подмножества
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
148 /// будут резделены на более мелкие. Иногда требуется гарантировать различия конечных сосотяний,
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
149 /// для этого необходимо переопределить даннцю фукнцию, для получения множеств конечных состояний.
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
150 /// </remarks>
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
151 /// <returns>The final states.</returns>
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
152 protected virtual IEnumerable<HashSet<int>> GroupFinalStates() {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
153 return new HashSet<int>[] { m_finalStates };
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
154 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
155
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
156 protected void Optimize<TInput, TState>(
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
157 IDFATableBuilder optimalDFA,
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
158 IAlphabet<TInput> inputAlphabet,
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
159 IAlphabetBuilder<TInput> optimalInputAlphabet,
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
160 IAlphabet<TState> stateAlphabet,
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
161 IAlphabetBuilder<TState> optimalStateAlphabet
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
162 ) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
163 Safe.ArgumentNotNull(optimalDFA, "dfa");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
164 Safe.ArgumentNotNull(optimalInputAlphabet, "optimalInputAlphabet");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
165 Safe.ArgumentNotNull(optimalStateAlphabet, "optimalStateAlphabet");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
166 Safe.ArgumentNotNull(inputAlphabet, "inputAlphabet");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
167 Safe.ArgumentNotNull(stateAlphabet, "stateAlphabet");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
168
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
169 if (inputAlphabet.Count != m_symbolCount)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
170 throw new InvalidOperationException("The input symbols aphabet mismatch");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
171 if (stateAlphabet.Count != m_stateCount)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
172 throw new InvalidOperationException("The states alphabet mismatch");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
173
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
174 var setComparer = new CustomEqualityComparer<HashSet<int>>(
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
175 (x, y) => x.SetEquals(y),
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
176 s => s.Sum(x => x.GetHashCode())
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
177 );
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
178
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
179 var optimalStates = new HashSet<HashSet<int>>(setComparer);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
180 var queue = new HashSet<HashSet<int>>(setComparer);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
181
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
182 // получаем конечные состояния, сгруппированные по маркерам
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
183 optimalStates.UnionWith(
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
184 GroupFinalStates()
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
185 );
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
186
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
187 var state = new HashSet<int>(
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
188 Enumerable
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
189 .Range(0, m_stateCount - 1)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
190 .Where(i => !m_finalStates.Contains(i))
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
191 );
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
192
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
193 optimalStates.Add(state);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
194 queue.Add(state);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
195
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
196 var rmap = m_transitions
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
197 .GroupBy(t => t.s2)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
198 .ToLookup(
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
199 g => g.Key, // s2
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
200 g => g.ToLookup(t => t.edge, t => t.s1)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
201 );
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
202
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
203 while (queue.Count > 0) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
204 var stateA = queue.First();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
205 queue.Remove(stateA);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
206
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
207 for (int c = 0; c < m_symbolCount; c++) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
208 var stateX = new HashSet<int>();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
209 foreach(var a in stateA)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
210 stateX.UnionWith(rmap[a][c]); // all states from wich 'c' leads to 'a'
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
211
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
212 foreach (var stateY in optimalStates.ToArray()) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
213 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
214 var stateR1 = new HashSet<int>(stateY);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
215 var stateR2 = new HashSet<int>(stateY);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
216
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
217 stateR1.IntersectWith(stateX);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
218 stateR2.ExceptWith(stateX);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
219
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
220 optimalStates.Remove(stateY);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
221 optimalStates.Add(stateR1);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
222 optimalStates.Add(stateR2);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
223
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
224 if (queue.Contains(stateY)) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
225 queue.Remove(stateY);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
226 queue.Add(stateR1);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
227 queue.Add(stateR2);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
228 } else {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
229 queue.Add(stateR1.Count <= stateR2.Count ? stateR1 : stateR2);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
230 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
231 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
232 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
233 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
234 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
235
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
236 // карта получения оптимального состояния по соотвествующему ему простому состоянию
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
237 var statesMap = stateAlphabet.Reclassify(optimalStateAlphabet, optimalStates);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
238
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
239 // получаем минимальный алфавит
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
240 // входные символы не различимы, если Move(s,a1) == Move(s,a2)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
241 var optimalAlphabet = m_transitions
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
242 .GroupBy(t => Tuple.Create(statesMap[t.s1], statesMap[t.s2]), t => t.edge);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
243
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
244 var alphabetMap = inputAlphabet.Reclassify(optimalInputAlphabet, optimalAlphabet);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
245
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
246 // построение автомата
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
247 optimalDFA.SetInitialState(statesMap[m_initialState]);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
248
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
249 foreach (var sf in m_finalStates.GroupBy(s => statesMap[s]))
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
250 optimalDFA.MarkFinalState(sf.Key);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
251
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
252 foreach (var t in m_transitions.Select(t => new AutomatonTransition(statesMap[t.s1],statesMap[t.s2],alphabetMap[t.edge])).Distinct())
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
253 optimalDFA.Add(t);
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
254
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
255 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
256
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
257 protected void PrintDFA<TInput, TState>(IAlphabet<TInput> inputAlphabet, IAlphabet<TState> stateAlphabet) {
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
258 Safe.ArgumentNotNull(inputAlphabet, "inputAlphabet");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
259 Safe.ArgumentNotNull(stateAlphabet, "stateAlphabet");
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
260
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
261 var inputMap = inputAlphabet.CreateReverseMap();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
262 var stateMap = stateAlphabet.CreateReverseMap();
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
263
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
264 for (int i = 0; i < inputMap.Length; i++)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
265 Console.WriteLine("C{0}: {1}", i, String.Join(",", inputMap[i]));
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
266
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
267
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
268 foreach(var t in m_transitions)
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
269 Console.WriteLine(
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
270 "[{0}] -{{{1}}}-> [{2}]{3}",
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
271 stateMap[t.s1],
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
272 String.Join(",", inputMap[t.edge]),
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
273 stateMap[t.s2],
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
274 m_finalStates.Contains(t.s2) ? "$" : ""
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
275 );
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
276
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
277 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
278
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
279 }
54270c2f29f2 DFA refactoring
cin
parents:
diff changeset
280 }