/** Self-test. */ public static void _Main(string[] args) { const int ITER = 500; const int RANGE = 65536; SparseBitSet a = new SparseBitSet(); CUtility.ASSERT(!a.Get(0) && !a.Get(1)); CUtility.ASSERT(!a.Get(123329)); a.Set(0); CUtility.ASSERT(a.Get(0) && !a.Get(1)); a.Set(1); CUtility.ASSERT(a.Get(0) && a.Get(1)); a.clearAll(); CUtility.ASSERT(!a.Get(0) && !a.Get(1)); Random r = new Random(); Vector v = new Vector(); for (int n = 0; n < ITER; n++) { int rr = ((r.Next() >> 1) % RANGE) << 1; a.Set(rr); v.addElement(rr); // check that all the numbers are there. CUtility.ASSERT(a.Get(rr) && !a.Get(rr + 1) && !a.Get(rr - 1)); for (int i = 0; i < v.size(); i++) { CUtility.ASSERT(a.Get((int)v.elementAt(i))); } } SparseBitSet b = (SparseBitSet)a.Clone(); CUtility.ASSERT(a.Equals(b) && b.Equals(a)); for (int n = 0; n < ITER / 2; n++) { int rr = (r.Next() >> 1) % v.size(); int m = (int)v.elementAt(rr); b.clear(m); v.removeElementAt(rr); // check that numbers are removed properly. CUtility.ASSERT(!b.Get(m)); } CUtility.ASSERT(!a.Equals(b)); SparseBitSet c = (SparseBitSet)a.Clone(); SparseBitSet d = (SparseBitSet)a.Clone(); c.and(a); CUtility.ASSERT(c.Equals(a) && a.Equals(c)); c.xor(a); CUtility.ASSERT(!c.Equals(a) && c.size() == 0); d.or(b); CUtility.ASSERT(d.Equals(a) && !b.Equals(d)); d.and(b); CUtility.ASSERT(!d.Equals(a) && b.Equals(d)); d.xor(a); CUtility.ASSERT(!d.Equals(a) && !b.Equals(d)); c.or(d); c.or(b); CUtility.ASSERT(c.Equals(a) && a.Equals(c)); c = (SparseBitSet)d.Clone(); c.and(b); CUtility.ASSERT(c.size() == 0); System.Console.WriteLine("Success."); }
/*************************************************************** * Function: fix_dtrans * Description: Updates CDTrans table after minimization * using groups, removing redundant transition table states. **************************************************************/ private void fix_dtrans ( ) { Vector new_vector; int i; int size; Vector dtrans_group; CDTrans first; int c; new_vector = new Vector(); size = m_spec.m_state_dtrans.Length; for (i = 0; i < size; ++i) { if (CDTrans.F != m_spec.m_state_dtrans[i]) { m_spec.m_state_dtrans[i] = m_ingroup[m_spec.m_state_dtrans[i]]; } } size = m_group.size(); for (i = 0; i < size; ++i) { dtrans_group = (Vector)m_group.elementAt(i); first = (CDTrans)dtrans_group.elementAt(0); new_vector.addElement(first); for (c = 0; c < m_spec.m_dtrans_ncols; ++c) { if (CDTrans.F != first.m_dtrans[c]) { first.m_dtrans[c] = m_ingroup[first.m_dtrans[c]]; } } } m_group = null; m_spec.m_dtrans_vector = new_vector; }
/*************************************************************** * Function: init_groups * Description: **************************************************************/ private void init_groups ( ) { int i; int j; int group_count; int size; // CAccept accept; CDTrans dtrans; Vector dtrans_group; CDTrans first; bool group_found; m_group = new Vector(); group_count = 0; size = m_spec.m_dtrans_vector.size(); m_ingroup = new int[size]; for (i = 0; i < size; ++i) { group_found = false; dtrans = (CDTrans)m_spec.m_dtrans_vector.elementAt(i); if (CUtility.DEBUG) { CUtility.ASSERT(i == dtrans.m_label); CUtility.ASSERT(false == group_found); CUtility.ASSERT(group_count == m_group.size()); } for (j = 0; j < group_count; ++j) { dtrans_group = (Vector)m_group.elementAt(j); if (CUtility.DEBUG) { CUtility.ASSERT(false == group_found); CUtility.ASSERT(0 < dtrans_group.size()); } first = (CDTrans)dtrans_group.elementAt(0); if (CUtility.SLOW_DEBUG) { CDTrans check; int k; int s; s = dtrans_group.size(); CUtility.ASSERT(0 < s); for (k = 1; k < s; ++k) { check = (CDTrans)dtrans_group.elementAt(k); CUtility.ASSERT(check.m_accept == first.m_accept); } } if (first.m_accept == dtrans.m_accept) { dtrans_group.addElement(dtrans); m_ingroup[i] = j; group_found = true; if (CUtility.DEBUG) { CUtility.ASSERT(j == m_ingroup[dtrans.m_label]); } break; } } if (false == group_found) { dtrans_group = new Vector(); dtrans_group.addElement(dtrans); m_ingroup[i] = m_group.size(); m_group.addElement(dtrans_group); ++group_count; } } if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG) { System.Console.WriteLine("Initial grouping:"); pgroups(); System.Console.WriteLine(); } }
/*************************************************************** * Function: minimize * Description: Removes redundant transition table states. **************************************************************/ private void minimize ( ) { Vector dtrans_group; Vector new_group; int i; int j; int old_group_count; int group_count; CDTrans next; CDTrans first; int goto_first; int goto_next; int c; int group_size; bool added; init_groups(); group_count = m_group.size(); old_group_count = group_count - 1; while (old_group_count != group_count) { old_group_count = group_count; if (CUtility.DEBUG) { CUtility.ASSERT(m_group.Count == group_count); } for (i = 0; i < group_count; ++i) { dtrans_group = (Vector)m_group.elementAt(i); group_size = dtrans_group.size(); if (group_size <= 1) { continue; } new_group = new Vector(); added = false; first = (CDTrans)dtrans_group.elementAt(0); for (j = 1; j < group_size; ++j) { next = (CDTrans)dtrans_group.elementAt(j); for (c = 0; c < m_spec.m_dtrans_ncols; ++c) { goto_first = first.m_dtrans[c]; goto_next = next.m_dtrans[c]; if (goto_first != goto_next && (goto_first == CDTrans.F || goto_next == CDTrans.F || m_ingroup[goto_next] != m_ingroup[goto_first])) { if (CUtility.DEBUG) { CUtility.ASSERT(dtrans_group.elementAt(j) == next); } dtrans_group.removeElementAt(j); --j; --group_size; new_group.addElement(next); if (false == added) { added = true; ++group_count; m_group.addElement(new_group); } m_ingroup[next.m_label] = m_group.Count - 1; if (CUtility.DEBUG) { CUtility.ASSERT(m_group.contains(new_group) == true); CUtility.ASSERT(m_group.contains(dtrans_group) == true); CUtility.ASSERT(dtrans_group.contains(first) == true); CUtility.ASSERT(dtrans_group.contains(next) == false); CUtility.ASSERT(new_group.contains(first) == false); CUtility.ASSERT(new_group.contains(next) == true); CUtility.ASSERT(dtrans_group.size() == group_size); CUtility.ASSERT(i == m_ingroup[first.m_label]); CUtility.ASSERT((m_group.size() - 1) == m_ingroup[next.m_label]); } break; } } } } } System.Console.WriteLine(m_group.size() + " states after removal of redundant states."); if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG) { System.Console.WriteLine(); System.Console.WriteLine("States grouped as follows after minimization"); pgroups(); } fix_dtrans(); }
/*************************************************************** Function: minimize Description: Removes redundant transition table states. **************************************************************/ private void minimize( ) { Vector dtrans_group; Vector new_group; int i; int j; int old_group_count; int group_count; CDTrans next; CDTrans first; int goto_first; int goto_next; int c; int group_size; bool added; init_groups(); group_count = m_group.size(); old_group_count = group_count - 1; while (old_group_count != group_count) { old_group_count = group_count; if (CUtility.DEBUG) { CUtility.ASSERT(m_group.Count == group_count); } for (i = 0; i < group_count; ++i) { dtrans_group = (Vector) m_group.elementAt(i); group_size = dtrans_group.size(); if (group_size <= 1) { continue; } new_group = new Vector(); added = false; first = (CDTrans) dtrans_group.elementAt(0); for (j = 1; j < group_size; ++j) { next = (CDTrans) dtrans_group.elementAt(j); for (c = 0; c < m_spec.m_dtrans_ncols; ++c) { goto_first = first.m_dtrans[c]; goto_next = next.m_dtrans[c]; if (goto_first != goto_next && (goto_first == CDTrans.F || goto_next == CDTrans.F || m_ingroup[goto_next] != m_ingroup[goto_first])) { if (CUtility.DEBUG) { CUtility.ASSERT(dtrans_group.elementAt(j) == next); } dtrans_group.removeElementAt(j); --j; --group_size; new_group.addElement(next); if (false == added) { added = true; ++group_count; m_group.addElement(new_group); } m_ingroup[next.m_label] = m_group.Count - 1; if (CUtility.DEBUG) { CUtility.ASSERT(m_group.contains(new_group) == true); CUtility.ASSERT(m_group.contains(dtrans_group) == true); CUtility.ASSERT(dtrans_group.contains(first) == true); CUtility.ASSERT(dtrans_group.contains(next) == false); CUtility.ASSERT(new_group.contains(first) == false); CUtility.ASSERT(new_group.contains(next) == true); CUtility.ASSERT(dtrans_group.size() == group_size); CUtility.ASSERT(i == m_ingroup[first.m_label]); CUtility.ASSERT((m_group.size() - 1) == m_ingroup[next.m_label]); } break; } } } } } System.Console.WriteLine(m_group.size() + " states after removal of redundant states."); if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG) { System.Console.WriteLine(); System.Console.WriteLine("States grouped as follows after minimization"); pgroups(); } fix_dtrans(); }
/*************************************************************** Function: init_groups Description: **************************************************************/ private void init_groups( ) { int i; int j; int group_count; int size; // CAccept accept; CDTrans dtrans; Vector dtrans_group; CDTrans first; bool group_found; m_group = new Vector(); group_count = 0; size = m_spec.m_dtrans_vector.size(); m_ingroup = new int[size]; for (i = 0; i < size; ++i) { group_found = false; dtrans = (CDTrans) m_spec.m_dtrans_vector.elementAt(i); if (CUtility.DEBUG) { CUtility.ASSERT(i == dtrans.m_label); CUtility.ASSERT(false == group_found); CUtility.ASSERT(group_count == m_group.size()); } for (j = 0; j < group_count; ++j) { dtrans_group = (Vector) m_group.elementAt(j); if (CUtility.DEBUG) { CUtility.ASSERT(false == group_found); CUtility.ASSERT(0 < dtrans_group.size()); } first = (CDTrans) dtrans_group.elementAt(0); if (CUtility.SLOW_DEBUG) { CDTrans check; int k; int s; s = dtrans_group.size(); CUtility.ASSERT(0 < s); for (k = 1; k < s; ++k) { check = (CDTrans) dtrans_group.elementAt(k); CUtility.ASSERT(check.m_accept == first.m_accept); } } if (first.m_accept == dtrans.m_accept) { dtrans_group.addElement(dtrans); m_ingroup[i] = j; group_found = true; if (CUtility.DEBUG) { CUtility.ASSERT(j == m_ingroup[dtrans.m_label]); } break; } } if (false == group_found) { dtrans_group = new Vector(); dtrans_group.addElement(dtrans); m_ingroup[i] = m_group.size(); m_group.addElement(dtrans_group); ++group_count; } } if (m_spec.m_verbose && true == CUtility.OLD_DUMP_DEBUG) { System.Console.WriteLine("Initial grouping:"); pgroups(); System.Console.WriteLine(); } }
/*************************************************************** Function: fix_dtrans Description: Updates CDTrans table after minimization using groups, removing redundant transition table states. **************************************************************/ private void fix_dtrans( ) { Vector new_vector; int i; int size; Vector dtrans_group; CDTrans first; int c; new_vector = new Vector(); size = m_spec.m_state_dtrans.Length; for (i = 0; i < size; ++i) { if (CDTrans.F != m_spec.m_state_dtrans[i]) { m_spec.m_state_dtrans[i] = m_ingroup[m_spec.m_state_dtrans[i]]; } } size = m_group.size(); for (i = 0; i < size; ++i) { dtrans_group = (Vector) m_group.elementAt(i); first = (CDTrans) dtrans_group.elementAt(0); new_vector.addElement(first); for (c = 0; c < m_spec.m_dtrans_ncols; ++c) { if (CDTrans.F != first.m_dtrans[c]) { first.m_dtrans[c] = m_ingroup[first.m_dtrans[c]]; } } } m_group = null; m_spec.m_dtrans_vector = new_vector; }
/** Self-test. */ public static void _Main(string[] args) { const int ITER = 500; const int RANGE= 65536; SparseBitSet a = new SparseBitSet(); CUtility.ASSERT(!a.Get(0) && !a.Get(1)); CUtility.ASSERT(!a.Get(123329)); a.Set(0); CUtility.ASSERT(a.Get(0) && !a.Get(1)); a.Set(1); CUtility.ASSERT(a.Get(0) && a.Get(1)); a.clearAll(); CUtility.ASSERT(!a.Get(0) && !a.Get(1)); Random r = new Random(); Vector v = new Vector(); for (int n=0; n<ITER; n++) { int rr = ((r.Next()>>1) % RANGE) << 1; a.Set(rr); v.addElement(rr); // check that all the numbers are there. CUtility.ASSERT(a.Get(rr) && !a.Get(rr+1) && !a.Get(rr-1)); for (int i=0; i<v.size(); i++) CUtility.ASSERT(a.Get((int)v.elementAt(i))); } SparseBitSet b = (SparseBitSet) a.Clone(); CUtility.ASSERT(a.Equals(b) && b.Equals(a)); for (int n=0; n<ITER/2; n++) { int rr = (r.Next()>>1) % v.size(); int m = (int)v.elementAt(rr); b.clear(m); v.removeElementAt(rr); // check that numbers are removed properly. CUtility.ASSERT(!b.Get(m)); } CUtility.ASSERT(!a.Equals(b)); SparseBitSet c = (SparseBitSet) a.Clone(); SparseBitSet d = (SparseBitSet) a.Clone(); c.and(a); CUtility.ASSERT(c.Equals(a) && a.Equals(c)); c.xor(a); CUtility.ASSERT(!c.Equals(a) && c.size()==0); d.or(b); CUtility.ASSERT(d.Equals(a) && !b.Equals(d)); d.and(b); CUtility.ASSERT(!d.Equals(a) && b.Equals(d)); d.xor(a); CUtility.ASSERT(!d.Equals(a) && !b.Equals(d)); c.or(d); c.or(b); CUtility.ASSERT(c.Equals(a) && a.Equals(c)); c = (SparseBitSet) d.Clone(); c.and(b); CUtility.ASSERT(c.size()==0); System.Console.WriteLine("Success."); }