public DFSM(FSM <T> fsm) : this() { List <BuildSet> marked = new List <BuildSet>(); marked.Add(new BuildSet(new int[] { 0 })); for (int j = 0; j < marked.Count; j++) { foreach (T s in fsm.Symbols) { List <int> acumulator = new List <int>(); foreach (int i in marked[j].Items) { acumulator.AddRange(fsm.StatesFrom(i, s)); } if (acumulator.Count > 0) { BuildSet set = new BuildSet(acumulator); if (!marked.Contains(set)) { marked.Add(set); } int k = marked.IndexOf(set); if (!this._transitions.ContainsKey(j)) { this._transitions[j] = new Dictionary <T, List <int> >(); } if (!this._transitions[j].ContainsKey(s)) { this._transitions[j][s] = new List <int>(); } if (!this._transitions[j][s].Contains(k)) { this._transitions[j][s].Add(k); } foreach (int fs in set.Items) { if (fsm.AcceptingStates.ContainsKey(fs)) { if (!this.AcceptingStates.ContainsKey(k)) { this.AcceptingStates[k] = new List <string>(); } this.AcceptingStates[k].AddRange(fsm.AcceptingStates[fs].Except(this.AcceptingStates[k])); } } } } } }
public DFSM <T> Minimize() { DFSM <T> result = new DFSM <T>(); //make clone result._transitions = new Dictionary <int, Dictionary <T, List <int> > >(); foreach (int i in this._transitions.Keys) { result._transitions[i] = new Dictionary <T, List <int> >(); foreach (T s in this._transitions[i].Keys) { result._transitions[i][s] = new List <int>(this._transitions[i][s]); } } foreach (KeyValuePair <int, List <string> > kv in this.AcceptingStates) { result.AcceptingStates[kv.Key] = new List <string>(kv.Value); } //remove unreachable and looped states result.Trim(); List <int> states = result.States; List <int> acc = result.AcceptingStates.Keys.ToList(); List <int> nonacc = result.States.Except(acc).ToList(); List <T> symbols = result.Symbols; List <BuildSet> distinctsets = new List <BuildSet>(); List <BuildSet> sets = new List <BuildSet>(); Dictionary <BuildSet, List <BuildSet> > deltasets = new Dictionary <BuildSet, List <BuildSet> >(); //populate all sets for (int i = 0; i < states.Count; i++) { for (int j = i + 1; j < states.Count; j++) { BuildSet newset = new BuildSet(new int[] { states[i], states[j] }); sets.Add(newset); if ((acc.Contains(states[i]) && nonacc.Contains(states[j])) || (acc.Contains(states[j]) && nonacc.Contains(states[i]))) { distinctsets.Add(newset); } else { if (!deltasets.ContainsKey(newset)) { deltasets[newset] = new List <BuildSet>(); } foreach (T s in symbols) { foreach (int x in result.StatesFrom(states[i], s)) { foreach (int y in result.StatesFrom(states[j], s)) { if (x != y) { deltasets[newset].Add(new BuildSet(new int[] { x, y })); } } } } deltasets[newset] = deltasets[newset].Distinct().ToList(); } } } //mark all distinct states int distcounter = 0; while (distinctsets.Count != distcounter) { distcounter = distinctsets.Count; foreach (BuildSet bs in deltasets.Keys) { if (deltasets[bs].Intersect(distinctsets).Any()) { distinctsets.Add(bs); } if (deltasets[bs].Count == 0) { distinctsets.Add(bs); } } distinctsets = distinctsets.Distinct().ToList(); foreach (BuildSet bs in distinctsets) { deltasets.Remove(bs); } } //join mergeble sets List <BuildSet> identicsets = sets.Except(distinctsets).ToList(); for (int i = 0; i < identicsets.Count; i++) { for (int j = i + 1; j < identicsets.Count; j++) { if (identicsets[i].Items.Intersect(identicsets[j].Items).Any()) { List <int> newset = identicsets[i].Items.Union(identicsets[j].Items).ToList(); identicsets.RemoveAt(j); identicsets.RemoveAt(i); identicsets.Insert(i, new BuildSet(newset)); j = i; } } } foreach (BuildSet b in identicsets) { List <int> items = new List <int>(b.Items); while (items.Count > 1) { result.RenumberState(items[1], items[0]); items.RemoveAt(1); } } return(result); }