@Override
  public String toString() {
    String str = "";
    for (int i = 0; i < FormulaType.values().length; i++)
      if (leftFormulas[i] != null) str += leftFormulas[i].toString();

    return str + "==>\n" + (rightSide == null ? "" : rightSide.toString());
  }
  @Override
  public void addLeft(Formula wff) {
    int idx = wff.getIndex();

    if (!leftSide.get(idx)) {
      leftSide.set(idx); // set the bit
      int type_idx = FormulaType.getFormulaType(wff).ordinal();
      if (leftFormulas[type_idx] == null) leftFormulas[type_idx] = new LinkedList<Formula>();
      leftFormulas[type_idx].add(wff);
    }
  }
 @Override
 public boolean removeLeft(Formula wff) {
   int idx = wff.getIndex();
   if (leftSide.get(idx)) {
     leftSide.set(idx, false);
     int type_idx = FormulaType.getFormulaType(wff).ordinal();
     LinkedList<Formula> list = leftFormulas[type_idx];
     list.remove(wff);
     if (list.size() == 0) leftFormulas[type_idx] = null;
     return true;
   } else return false;
 }
  @SuppressWarnings("unchecked")
  @Override
  public SingleSuccedentSequentOnBitSet clone() {
    try {
      SingleSuccedentSequentOnBitSet result = (SingleSuccedentSequentOnBitSet) super.clone();
      result.leftSide = (BitSet) this.leftSide.clone();
      result.leftFormulas = (LinkedList<Formula>[]) new LinkedList[FormulaType.values().length];
      for (int i = 0; i < this.leftFormulas.length; i++)
        if (this.leftFormulas[i] != null)
          result.leftFormulas[i] = (LinkedList<Formula>) this.leftFormulas[i].clone();

      result.rightSide = this.rightSide;
      return result;
    } catch (CloneNotSupportedException e) {
      throw new ImplementationError(e.getMessage());
    }
  }
 @SuppressWarnings("unchecked")
 public SingleSuccedentSequentOnBitSet(FormulaFactory factory) {
   leftSide = new BitSet(factory.numberOfGeneratedFormulas());
   leftFormulas = new LinkedList[FormulaType.values().length];
   rightSide = null;
 }
 @Override
 public Formula getRightFormulaOfType(FormulaType formulaType) {
   if (rightSide != null && FormulaType.getFormulaType(rightSide) == formulaType) return rightSide;
   else return null;
 }
 @Override
 public Formula getLeft(FormulaType formulaType) {
   LinkedList<Formula> list = leftFormulas[formulaType.ordinal()];
   if (list == null) return null;
   else return list.getFirst();
 }
 @Override
 public Collection<Formula> getAllLeftFormulas(FormulaType formulaType) {
   return leftFormulas[formulaType.ordinal()];
 }