/** * Simplify a finite automaton by merging simulation equivalent states * @param fa: a finite automaton * @param Sim: some simulation rel_specation over states in the spec automaton * * @return an equivalent finite automaton */ private FiniteAutomaton quotient(FiniteAutomaton fa, HashSet <Pair <FAState, FAState> > rel) { FiniteAutomaton result = new FiniteAutomaton(); Dictionary <FAState, FAState> map = new Dictionary <FAState, FAState>(); Dictionary <FAState, FAState> reducedMap = new Dictionary <FAState, FAState>(); foreach (FAState state in fa.states) { map.Add(state, state); foreach (FAState state2 in fa.states) { if (rel.Contains(new Pair <FAState, FAState>(state, state2)) && rel.Contains(new Pair <FAState, FAState>(state2, state))) { map.Add(state, state2); } } } FAState init = result.createState(); reducedMap.Add(map[fa.InitialState], init); result.InitialState = init; foreach (FAState state in fa.states) { if (!reducedMap.ContainsKey(map[state])) { reducedMap.Add(map[state], result.createState()); } if (fa.F.Contains(state)) { result.F.Add(reducedMap[map[state]]); } foreach (KeyValuePair <string, HashSet <FAState> > sym_it in state.next) { String sym = sym_it.Key; foreach (FAState to in sym_it.Value) { if (!reducedMap.ContainsKey(map[to])) { reducedMap.Add(map[to], result.createState()); } result.addTransition(reducedMap[map[state]], reducedMap[map[to]], sym); } } } HashSet <Pair <FAState, FAState> > newrel_spec = new HashSet <Pair <FAState, FAState> >(); foreach (Pair <FAState, FAState> sim in rel) { newrel_spec.Add(new Pair <FAState, FAState>(reducedMap[map[sim.Left]], reducedMap[map[sim.Right]])); } rel.Clear(); rel = new HashSet <Pair <FAState, FAState> >(newrel_spec); return(result); }
private bool lasso_finding_test(HashSet <Arc> g, HashSet <Arc> h, int init) { if (!Head.ContainsKey(g.ToString())) { HashSet <int> H = new HashSet <int>(); foreach (Arc arc_g in g) { if (arc_g.From == init) { H.Add(arc_g.To); } } Head.Add(g.ToString(), H); } if (!Tail.ContainsKey(h.ToString())) { FiniteAutomaton fa = new FiniteAutomaton(); OneToOneTreeMap <int, FAState> st = new OneToOneTreeMap <int, FAState>(); foreach (Arc arc_h in h) { if (!st.containsKey(arc_h.From)) { st.put(arc_h.From, fa.createState()); } if (!st.containsKey(arc_h.To)) { st.put(arc_h.To, fa.createState()); } fa.addTransition(st.getValue(arc_h.From), st.getValue(arc_h.To), arc_h.Label ? "1" : "0"); } SCC s = new SCC(fa); HashSet <int> T = new HashSet <int>(); foreach (FAState state in s.getResult()) { T.Add(st.getKey(state)); } int TailSize = 0; HashSet <Arc> isolatedArcs = h; while (TailSize != T.Count) { TailSize = T.Count; HashSet <Arc> isolatedArcsTemp = new HashSet <Arc>(); foreach (Arc arc in isolatedArcs) { if (!T.Contains(arc.To)) { isolatedArcsTemp.Add(arc); } else { T.Add(arc.From); } } isolatedArcs = isolatedArcsTemp; } Tail.Add(h.ToString(), T); } HashSet <int> intersection = new HashSet <int>(Head[g.ToString()]); //intersection.retainAll(Tail[h.ToString()]); intersection.IntersectWith(Tail[h.ToString()]); //if(debug){ // if(intersection.isEmpty()){ // //debug("g_graph:"+g+", Head: "+Head.get(g.ToString())); // //debug("h_graph:"+h+", Tail: "+Tail.get(h.ToString())); // } //} return(intersection.Count > 0); }