/** 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."); }
public bool MoveNext() { pos++; while (pos < mSet.size() && !mSet.Get(pos)) { pos++; } return(pos < mSet.size()); }
/******************************************************** * Function: contains *******************************************************/ public bool contains ( int i ) { bool result; result = m_set.Get(i); if (m_complement) { return(false == result); } return(result); }
/*************************************************************** * Function: processStates * Description: **************************************************************/ private void processStates ( SparseBitSet states, CNfa current ) { int size; int i; size = m_spec.m_states.Count; for (i = 0; i < size; ++i) { if (states.Get(i)) { m_spec.m_state_rules[i].addElement(current); } } }
/*************************************************************** * Function: reduce * Description: **************************************************************/ private void reduce ( ) { int i; int j; int k; int nrows; int reduced_ncols; int reduced_nrows; SparseBitSet Set; CDTrans dtrans; int size; Set = new SparseBitSet(); /* Save accept nodes and anchor entries. */ size = m_spec.m_dtrans_vector.size(); m_spec.m_anchor_array = new int[size]; m_spec.m_accept_vector = new Vector(); for (i = 0; i < size; ++i) { dtrans = (CDTrans)m_spec.m_dtrans_vector.elementAt(i); m_spec.m_accept_vector.addElement(dtrans.m_accept); m_spec.m_anchor_array[i] = dtrans.m_anchor; dtrans.m_accept = null; } /* Allocate column map. */ m_spec.m_col_map = new int[m_spec.m_dtrans_ncols]; for (i = 0; i < m_spec.m_dtrans_ncols; ++i) { m_spec.m_col_map[i] = -1; } /* Process columns for reduction. */ for (reduced_ncols = 0; ; ++reduced_ncols) { #if (DEBUG) { for (i = 0; i < reduced_ncols; ++i) { CUtility.ASSERT(-1 != m_spec.m_col_map[i]); } } #endif for (i = reduced_ncols; i < m_spec.m_dtrans_ncols; ++i) { if (-1 == m_spec.m_col_map[i]) { break; } } if (i >= m_spec.m_dtrans_ncols) { break; } #if (DEBUG) { CUtility.ASSERT(false == Set.Get(i)); CUtility.ASSERT(-1 == m_spec.m_col_map[i]); } #endif Set.Set(i); m_spec.m_col_map[i] = reduced_ncols; /* UNDONE: Optimize by doing all comparisons in one batch. */ for (j = i + 1; j < m_spec.m_dtrans_ncols; ++j) { if (-1 == m_spec.m_col_map[j] && col_equiv(i, j)) { m_spec.m_col_map[j] = reduced_ncols; } } } /* Reduce columns. */ k = 0; for (i = 0; i < m_spec.m_dtrans_ncols; ++i) { if (Set.Get(i)) { ++k; Set.clear(i); j = m_spec.m_col_map[i]; #if (DEBUG) { CUtility.ASSERT(j <= i); } #endif if (j == i) { continue; } col_copy(j, i); } } m_spec.m_dtrans_ncols = reduced_ncols; /* truncate m_dtrans at proper length (freeing extra) */ trunc_col(); #if (DEBUG) { CUtility.ASSERT(k == reduced_ncols); } #endif /* Allocate row map. */ nrows = m_spec.m_dtrans_vector.Count; m_spec.m_row_map = new int[nrows]; for (i = 0; i < nrows; ++i) { m_spec.m_row_map[i] = -1; } /* Process rows to reduce. */ for (reduced_nrows = 0; ; ++reduced_nrows) { #if (DEBUG) { for (i = 0; i < reduced_nrows; ++i) { CUtility.ASSERT(-1 != m_spec.m_row_map[i]); } } #endif for (i = reduced_nrows; i < nrows; ++i) { if (-1 == m_spec.m_row_map[i]) { break; } } if (i >= nrows) { break; } #if (DEBUG) { CUtility.ASSERT(false == Set.Get(i)); CUtility.ASSERT(-1 == m_spec.m_row_map[i]); } #endif Set.Set(i); m_spec.m_row_map[i] = reduced_nrows; /* UNDONE: Optimize by doing all comparisons in one batch. */ for (j = i + 1; j < nrows; ++j) { if (-1 == m_spec.m_row_map[j] && row_equiv(i, j)) { m_spec.m_row_map[j] = reduced_nrows; } } } /* Reduce rows. */ k = 0; for (i = 0; i < nrows; ++i) { if (Set.Get(i)) { ++k; Set.clear(i); j = m_spec.m_row_map[i]; #if (DEBUG) { CUtility.ASSERT(j <= i); } #endif if (j == i) { continue; } row_copy(j, i); } } m_spec.m_dtrans_vector.setSize(reduced_nrows); #if (DEBUG) { /*System.Console.WriteLine("k = " + k + "\nreduced_nrows = " + reduced_nrows + "");*/ CUtility.ASSERT(k == reduced_nrows); } #endif }
/** Compute minimum Set of character classes needed to disambiguate * edges. We optimistically assume that every character belongs to * a single character class, and then incrementally split classes * as we see edges that require discrimination between characters in * the class. [CSA, 25-Jul-1999] */ private void computeClasses(CSpec m_spec) { this.original_charset_size = m_spec.m_dtrans_ncols; this.ccls = new int[original_charset_size]; // initially all zero. int nextcls = 1; SparseBitSet clsA = new SparseBitSet(), clsB = new SparseBitSet(); Hashtable h = new Hashtable(); if (m_spec.m_verbose) { System.Console.Write("Working on character classes."); } IEnumerator e = m_spec.m_nfa_states.elements(); while (e.MoveNext()) { CNfa nfa = (CNfa)e.Current; if (nfa.m_edge == CNfa.EMPTY || nfa.m_edge == CNfa.EPSILON) { continue; // no discriminatory information. } clsA.clearAll(); clsB.clearAll(); for (int i = 0; i < ccls.Length; i++) { if (nfa.m_edge == i || // edge labeled with a character nfa.m_edge == CNfa.CCL && nfa.m_set.contains(i)) // Set of characters { clsA.Set(ccls[i]); } else { clsB.Set(ccls[i]); } } // now figure out which character classes we need to split. clsA.and(clsB); // split the classes which show up on both sides of edge if (m_spec.m_verbose) { System.Console.Write(clsA.size() == 0?".":":"); } if (clsA.size() == 0) { continue; // nothing to do. } // and split them. h.Clear(); // h will map old to new class name for (int i = 0; i < ccls.Length; i++) { if (clsA.Get(ccls[i])) // a split class { if (nfa.m_edge == i || nfa.m_edge == CNfa.CCL && nfa.m_set.contains(i)) { // on A side int split = ccls[i]; if (!h.ContainsKey(split)) { h.Add(split, (nextcls++)); // make new class } ccls[i] = (int)h[split]; } } } } if (m_spec.m_verbose) { System.Console.WriteLine(); System.Console.WriteLine("NFA has " + nextcls + " distinct character classes."); } this.mapped_charset_size = nextcls; }