public Term clone() {
    OperatorImpl newOp = new OperatorImpl(this);

    newOp.preconds.clear();
    newOp.effects.clear();

    for (Proposition prop : preconds) {
      newOp.preconds.add((Proposition) prop.clone());
    }

    for (Proposition prop : effects) {
      newOp.effects.add((Proposition) prop.clone());
    }

    newOp.setSeam(this.isSeam());

    return newOp;
  }
  public final boolean isMutex(Operator operator) {
    // First, we verify if any of this Operator's preconditions is mutex
    // with any precondition or effect in the target Operator

    // If any mutex is found, we can return immediately
    for (Proposition proposition : preconds) {
      for (Proposition precond : operator.getPreconds()) {
        if (proposition.isMutex(precond)) {
          return true;
        }
      }

      for (Proposition effect : operator.getEffects()) {
        if (proposition.isMutex(effect)) {
          return true;
        }
      }
    }

    // Verify if any of this Operator's effetcs is mutex with any
    // precondition or effect in the target Operator
    // Again, if we bump into any mutex, we can return immediately
    for (Proposition proposition : effects) {
      for (Proposition precond : operator.getPreconds()) {
        if (proposition.isMutex(precond)) {
          return true;
        }
      }

      for (Proposition effect : operator.getEffects()) {
        if (proposition.isMutex(effect)) {
          return true;
        }
      }
    }
    return false;
  }
 public boolean isMutex(Proposition proposition) {
   return (proposition.getSignature().equals(this.getSignature())
       && proposition.negated() != this.negated());
 }