`BitCode.java`

    // FILE. . . . . /home/hak/hlt/src/hlt/osfv2/util/BitCode.java
    // EDIT BY . . . Hassan Ait-Kaci
    // ON MACHINE. . Hak-Laptop
    // STARTED ON. . Mon Sep 02 15:37:36 2013

This class extends the class `java.util.BitSet` with a few methods not provided by that class; mainly, static methods for Boolean operations that reuse one of their arguments whenever possible.
Author: |  | Hassan Aït-Kaci
Copyright: |  | © Hassan Aït-Kaci
Version: |  | Last modified on Tue Jan 21 08:08:30 2014 by hak

    package hlt.osf.util;

    import java.util.BitSet;
    import java.util.HashSet;

    import hlt.language.util.IntIterator;

    import hlt.osf.base.Sort;
    import hlt.osf.exec.Context;
    import hlt.osf.exec.Taxonomy;

    public class BitCode extends BitSet
    {

Constructs a new bit code; (all bits set to `false`).

      public BitCode ()
      {
        super();
      }

Constructs a new bit code whose initial size is large enough to explicitly represent bits with indices in the range `0` through `nbits-1`; (all bits set to false).
Parameters: |  |
`nbits` | - the initial capacity of the bit code.

      public BitCode (int nbits)
      {
        super(nbits);
      }

      /* ************************************************************************ */

This is used for the "set" character when displaying this as a string. It is '`1`' by default.

      private static char _ON = '1';

This is used for the "not set" character when displaying this as a string. It is '`0`' by default.

      private static char _OFF = '0';

This sets the "set" character when displaying this as a string to the specified character.

      public static void setOnChar (char c)
      {
        _ON = c;
      }

This sets the "not set" character when displaying this as a string to the specified character.

      public static void setOffChar (char c)
      {
        _OFF = c;
      }

      /* ************************************************************************ */

This is used as a temporary reusable BitCode for avoiding unecessary multiple cloning.

      private static BitCode _TEMP = new BitCode();

      /* ************************************************************************ */

Returns true iff the set of set of bits in this code is contained in that of the specified code. That is, iff `(this and code) == this`.

      public boolean isContainedIn (BitCode code)
      {
        _TEMP.clear();	// reset all bits to 0
        _TEMP.or(this);	// copy this into it
        _TEMP.and(code);	// intersect it with code
        return this.equals(_TEMP);
      }

Returns true iff this code is strictly contained in the specified code.

      public boolean isStrictlyContainedIn (BitCode code)
      {
        return this.equals(code) ? false : this.isContainedIn(code);
      }

Returns true iff this code is unrelated to the specified code.

      public boolean isUnrelatedTo (BitCode code)
      {
        return !this.equals(code) && !this.isContainedIn(code) && !code.isContainedIn(this) ;
      }

      /* ************************************************************************ */

This is true iff this bitset may not be modified by the 3 boolean static operations 'not', 'and', and 'or' defined below.

      private boolean _isLocked = false;

Returns true iff this bit code is locked - which means that it will not be modified by the 3 boolean static dyadic operations 'not', 'and', and 'or' defined below.

      public boolean isLocked ()
      {
        return _isLocked;
      }

Locks this bit code - which means that it will not be modified by the 3 boolean static dyadic operations 'not', 'and', and 'or' defined below.

      public BitCode lock ()
      {
        _isLocked = true;
        return this;
      }

Unlocks this bit code - which means that it may be modified by the 3 boolean static dyadic operations 'not', 'and', and 'or' defined below.

      public BitCode unlock ()
      {
        _isLocked = false;
        return this;
      }

      /* ************************************************************************ */

Adds the specified index to this BitCode (i.e., it sets it to true), and returns this BitCode.

      public BitCode add (int index) throws LockedBitCodeException
      {
        if (_isLocked)
          throw new LockedBitCodeException("Cannot add to a locked BitCode");

        set(index);
        return this;
      }

      /* ************************************************************************ */

Removes the specified index from this BitCode (i.e., it sets it to false), and returns this BitCode.

      public BitCode remove (int index) throws LockedBitCodeException
      {
        if (_isLocked)
          throw new LockedBitCodeException("Cannot remove from a locked BitCode");

        set(index,false);
        return this;
      }

      /* ************************************************************************ */

Removes all the true bits from this BitCode (i.e., all set to false), and returns this BitCode.

      public BitCode erase () throws LockedBitCodeException
      {
        if (_isLocked)
          throw new LockedBitCodeException("Cannot clear a locked BitCode");

        super.clear();
        return this;
      }

      /* ************************************************************************ */

Returns a bit code that is the logical `not` of its bit code argument up to the sort code size. The bit code argument is left unchanged if locked. If the bit code argument is not locked, the returned bit code is the argument modified in place. Otherwise, a new bit code is returned with its bits set to their appropriate values.

      public static BitCode not (BitCode c)
      {
        if (!c.isLocked())
          {
    	c.flip(0,Sort.codeSize());
    	return c;
          }

        BitCode newcode = c.copy();
        newcode.flip(0,Sort.codeSize());
        return newcode;
      }

      /* ************************************************************************ */

Returns a bit code that is the logical `and` of its arguments, which are left unchanged if locked. If the first argument is not locked, the returned bit code is the first argument modified in place. Otherwise, if the second argument is not locked, the returned bit code is the second argument modified in place. Otherwise, a new bit code is returned with its bits set to their appropriate values.

      public static BitCode and (BitCode c1, BitCode c2)
      {
        if (!c1.isLocked())
          {
    	c1.and(c2);
    	return c1;
          }

        if (!c2.isLocked())
          {
    	c2.and(c1);
    	return c2;
          }

        BitCode newcode = c1.copy();
        newcode.and(c2);
        return newcode;
      }

      /* ************************************************************************ */

Returns the position on the least true bit (or -1 if there is none).

      public final int first ()
      {
        return nextSetBit(0);
      }

Returns the position on the highest true bit (or -1 if there is none).

      public final int last ()
      {
        return length()-1;
      }

      /* ************************************************************************ */

Returns a bit code that is the logical `or` of its arguments, which are left unchanged if locked. If the first argument is not locked, the returned bit code is the first argument modified in place. Otherwise, if the second argument is not locked, the returned bit code is the second argument modified in place. Otherwise, a new bit code is returned with its bits set to their appropriate values.

      public static BitCode or (BitCode c1, BitCode c2)
      {
        if (!c1.isLocked())
          {
    	c1.or(c2);
    	return c1;
          }

        if (!c2.isLocked())
          {
    	c2.or(c1);
    	return c2;
          }

        BitCode newcode = c1.copy();
        newcode.or(c2);
        return newcode;
      }

      /* ************************************************************************ */

Returns a new unlocked BitCode that is an equal copy of this one.

      public BitCode copy ()
      {
        if (Context.isTracing())
          Context.tallyCodeCopy();
        return ((BitCode)super.clone()).unlock();
      }

      /* ************************************************************************ */

Returns this bit code of length equal to the sort code size as a string of ON and OFF characters (which default to `0` and `1`). These can be set to different characters using the static methods `setOnChar` and `setOffChar`. All bits at index higher or equal to that size are always false.

      public String toBitString (int size)
      {
        String s = "";
        for (int i=size; i-->0;)
          s += get(i) ? _ON : _OFF;
        return s;
      }

      public String toBitString ()
      {
        return toBitString(Sort.codeSize());
      }

      public String toTrueBitString ()
      {
        return toBitString(length());
      }

Returns this bit code as a bit string followed by a marker whether it is locked or not.

      public String toString ()
      {
        return toBitString()+" "+(_isLocked ? "[]" : "][");
      }

      /* ************************************************************************ */

This returns a `String` form of this `BitCode` as a space-separated sequence of pairs of integers, each number corresponding to the next true index followed by the next false index, going from the lowest to the highest. For example, the bitcode:
          000011111001111000000110000
corresponds to the string:
          "4 6 12 16 18 23"
If there are no true bits (i.e., all the bits are `false`), this returns the empty string.

      public String toSaveFormatString ()
      {
        StringBuffer result = new StringBuffer();

        int trueIndex = nextSetBit(0);

        while (trueIndex != -1)
          {
    	int falseIndex = nextClearBit(trueIndex);
    	result = result.append(trueIndex+" "+falseIndex+" ");
    	trueIndex = nextSetBit(falseIndex);
          }

        return result.toString();
      }

      /* ************************************************************************ */

Returns a HashSet containing the set of sorts denoted by this BitCode.

      public HashSet toHashSet (Taxonomy taxonomy)
      {
        if (isEmpty())
          return null;

        HashSet hset = new HashSet(3*length());	// allocate three times the number of actual bits

        for (IntIterator it=iterator(); it.hasNext();)
          hset.add(taxonomy.getSort(it.next()));

        return hset;
      }

      /* ************************************************************************ */

Returns an iterator over the `1` bits of this bitcode.

      public IntIterator iterator ()
        {
          return new BitCodeIterator(this);
        }

      private class BitCodeIterator implements IntIterator
        {
          private BitCode _code;
          private boolean _getNext = true;
          private int _next = -1;

          BitCodeIterator (BitCode code)
            {
              _code = code;
            }

          public final boolean hasNext ()
            {
    	  if (_getNext)
    	    {
    	      _next = _code.nextSetBit(_next+1);
    	      _getNext = false;
    	    }

              return _next >= 0;
            }

          public final int next ()
            {
    	  _getNext = true;
              return _next;
            }

        }

      /* ************************************************************************ */

Returns an iterator over the `0` bits of this bitcode up to its length (exclusive).

      public IntIterator zeroIterator ()
        {
          return new BitCodeZeroIterator(this,length()-1);
        }

Returns an iterator over the `0` bits of this bitcode up to, but excluding, position `max`.

      public IntIterator zeroIterator (int max)
        {
          return new BitCodeZeroIterator(this,max);
        }

      private class BitCodeZeroIterator implements IntIterator
        {
          private BitCode _code;
          private int _stop;
          private boolean _getNext = true;
          private int _next = -1;

          BitCodeZeroIterator (BitCode code, int max)
            {
              _code = code;
    	  _stop = max-1;
            }

          public final boolean hasNext ()
            {
    	  if (_next >= _stop)
    	    return false;

      	  if (_getNext)
      	    {
      	      _next = _code.nextClearBit(_next+1);
      	      _getNext = false;
      	    }

              return _next >= 0;
            }

          public final int next ()
            {
      	  _getNext = true;
              return _next;
            }

        }

      /* ************************************************************************ */
    }

This file was generated on Tue Jan 21 09:56:10 CET 2014 from file `BitCode.java`
by the `hlt.language.tools.Hilite` Java tool written by Hassan Aït-Kaci