PsyBitSet.java

  1. package coneforest.psylla.core;

  2. import coneforest.psylla.runtime.*;
  3. import java.util.BitSet;
  4. import java.util.Iterator;

  5. /**
  6. *   The representation of {@code bitset}, a set of nonnegative {@code integer} objects.
  7. */
  8. @Type("bitset")
  9. public class PsyBitSet
  10.     implements PsyFormalSet<PsyInteger>
  11. {
  12.     /**
  13.     *   Context action of the {@code bitset} operator.
  14.     */
  15.     @OperatorType("bitset")
  16.     public static final ContextAction PSY_BITSET
  17.         =ContextAction.ofSupplier(PsyBitSet::new);

  18.     private final BitSet bitset;

  19.     /**
  20.     *   Instantiate an empty {@code bitset} object.
  21.     */
  22.     public PsyBitSet()
  23.     {
  24.         this(new BitSet());
  25.     }

  26.     /**
  27.     *   Instantiate a {@code bitset} object from a given {@link BitSet} object.
  28.     *
  29.     *   @param bitset a bit set.
  30.     */
  31.     public PsyBitSet(final BitSet bitset)
  32.     {
  33.         this.bitset=bitset;
  34.     }

  35.     @Override
  36.     public PsyBitSet psyClone()
  37.     {
  38.         return new PsyBitSet((BitSet)bitset.clone());
  39.     }

  40.     @Override
  41.     public String toSyntaxString()
  42.     {
  43.         final var sb=new StringBuilder("%bitset=");
  44.         int j=-1;
  45.         for(int i=bitset.nextSetBit(0); i>=0; i=bitset.nextSetBit(i+1))
  46.         {
  47.             for(int k=j+1; k<i; k++)
  48.                 sb.append('0');
  49.             sb.append('1');
  50.             j=i;
  51.         }
  52.         sb.append('%');
  53.         return sb.toString();
  54.     }

  55.     /*public BitSet getBitSet()
  56.     {
  57.         return bitset;
  58.     }*/

  59.     @Override
  60.     public void psyAppend(final PsyInteger oIndex)
  61.         throws PsyLimitCheckException, PsyRangeCheckException
  62.     {
  63.         //if(length()==Integer.MAX_VALUE)
  64.         //  throw new PsyLimitCheckException();
  65.         try
  66.         {
  67.             bitset.set(oIndex.intValue(), true);
  68.         }
  69.         catch(final IndexOutOfBoundsException ex)
  70.         {
  71.             throw new PsyRangeCheckException();
  72.         }
  73.     }

  74.     @Override
  75.     public void psyAppendAll(final PsyIterable<? extends PsyInteger> oIterable)
  76.         throws PsyLimitCheckException, PsyRangeCheckException
  77.     {
  78.         switch(oIterable)
  79.         {
  80.             case PsyBitSet oBitSet->bitset.or(oBitSet.bitset);
  81.             default->PsyFormalSet.super.psyAppendAll(oIterable);
  82.         }
  83.     }

  84.     @Override
  85.     public void psyRemove(final PsyInteger oIndex)
  86.     {
  87.         try
  88.         {
  89.             bitset.set(oIndex.intValue(), false);
  90.         }
  91.         catch(final IndexOutOfBoundsException ex)
  92.         {
  93.             // NOP
  94.         }
  95.     }

  96.     @Override
  97.     public void psyRemoveAll(final PsyIterable<? extends PsyInteger> oIterable)
  98.     {
  99.         switch(oIterable)
  100.         {
  101.             case PsyBitSet oBitSet->bitset.andNot(oBitSet.bitset);
  102.             default->PsyFormalSet.super.psyRemoveAll(oIterable);
  103.         }
  104.     }

  105.     @Override
  106.     public Iterator<PsyInteger> iterator()
  107.     {
  108.         return new Iterator<PsyInteger>()
  109.             {
  110.                 private int index=bitset.nextSetBit(0);

  111.                 @Override
  112.                 public boolean hasNext()
  113.                 {
  114.                     return index>=0;
  115.                 }

  116.                 @Override
  117.                 public PsyInteger next()
  118.                 {
  119.                     final var result=PsyInteger.of(index);
  120.                     index=bitset.nextSetBit(index+1);
  121.                     return result;
  122.                 }
  123.             };
  124.     }

  125.     @Override
  126.     public void psyClear()
  127.     {
  128.         bitset.clear();
  129.     }

  130.     @Override
  131.     public int length()
  132.     {
  133.         return bitset.cardinality();
  134.     }

  135.     @Override
  136.     public PsyBoolean psyContains(final PsyObject oElement)
  137.     {
  138.         return PsyBoolean.of(oElement instanceof PsyInteger oInteger
  139.                 && bitset.get(oInteger.intValue()));
  140.     }

  141.     @Override
  142.     public PsyBoolean psyIntersects(final PsyFormalSet<? extends PsyInteger> oSet)
  143.     {
  144.         if(oSet instanceof PsyBitSet oBitSet)
  145.             return PsyBoolean.of(bitset.intersects(oBitSet.bitset));
  146.         else
  147.             return PsyFormalSet.super.psyIntersects(oSet);
  148.     }

  149.     /*@Override
  150.     public PsyBoolean psyEq(final PsyObject o)
  151.     {
  152.         return PsyBoolean.of(o instanceof PsyBitSet oBitSet
  153.                 && bitset.equals(oBitSet.bitset));
  154.     }*/

  155.     @Override
  156.     public PsyFormalStream<PsyInteger> psyStream()
  157.     {
  158.         return PsyFormalStream.<PsyInteger>of(
  159.                 bitset.stream().<PsyInteger>mapToObj(PsyInteger::of));
  160.     }

  161.     @Override
  162.     public int hashCode()
  163.     {
  164.         return bitset.hashCode();
  165.     }

  166.     @Override
  167.     public boolean equals(final Object obj)
  168.     {
  169.         return switch(obj)
  170.             {
  171.                 case PsyBitSet oBitSet->bitset.equals(oBitSet.bitset);
  172.                 case PsyFormalSet<? extends PsyObject> oFormalSet->
  173.                     {
  174.                         if(length()!=oFormalSet.length())
  175.                             yield false;
  176.                         for(final var oInteger: this)
  177.                             if(!oFormalSet.psyContains(oInteger).booleanValue())
  178.                                 yield false;
  179.                         yield true;
  180.                     }
  181.                 default->false;
  182.             };
  183.     }
  184. }