001// ***** This file is automatically generated from SequencesIntersection.java.jpp
002
003package daikon.derive.binary;
004
005import org.checkerframework.checker.interning.qual.Interned;
006import org.checkerframework.dataflow.qual.Pure;
007import org.checkerframework.dataflow.qual.SideEffectFree;
008import daikon.*;
009import daikon.derive.*;
010import java.util.logging.Logger;
011import org.plumelib.util.ArraysPlume;
012import org.plumelib.util.Intern;
013
014/** Intersection between two comparable sequences. */
015public final class SequenceScalarIntersection extends BinaryDerivation {
016  public static final Logger debug =
017    Logger.getLogger("daikon.derive.binary.SequenceScalarIntersection");
018
019  static final long serialVersionUID = 20020122L;
020
021  // Variables starting with dkconfig_ should only be set via the
022  // daikon.config.Configuration interface.
023  /** Boolean. True iff SequenceScalarIntersection derived variables should be generated. */
024  public static boolean dkconfig_enabled = false;
025
026  SequenceScalarIntersection(VarInfo vi1, VarInfo vi2) {
027    super(vi1, vi2);
028  }
029
030  @Override
031  public ValueAndModified computeValueAndModifiedImpl(ValueTuple full_vt) {
032    debug.fine("Computing value and modified");
033
034    int mod1 = base1.getModified(full_vt);
035    if (mod1 == ValueTuple.MISSING_NONSENSICAL) {
036      return ValueAndModified.MISSING_NONSENSICAL;
037    }
038    int mod2 = base2.getModified(full_vt);
039    if (mod2 == ValueTuple.MISSING_NONSENSICAL) {
040      return ValueAndModified.MISSING_NONSENSICAL;
041    }
042    Object val1 = base1.getValue(full_vt);
043    if (val1 == null) {
044      return ValueAndModified.MISSING_NONSENSICAL;
045    }
046    long[] val1_array = (long[]) val1;
047    Object val2 = base2.getValue(full_vt);
048    if (val2 == null) {
049      return ValueAndModified.MISSING_NONSENSICAL;
050    }
051    long[] val2_array = (long[]) val2;
052
053    long[] tmp = new long[val1_array.length + val2_array.length];
054    int size = 0;
055    for (int i = 0; i < val1_array.length; i++) {
056      long v = val1_array[i];
057      if ((ArraysPlume.indexOf(val2_array, v) != -1)
058          && (size == 0 || (ArraysPlume.indexOf(ArraysPlume.subarray(tmp, 0, size), v) == -1))) {
059        tmp[size++] = v;
060      }
061    }
062
063    long[] intersect = ArraysPlume.subarray(tmp, 0, size);
064    intersect = Intern.intern(intersect);
065
066    int mod =
067        (((mod1 == ValueTuple.UNMODIFIED) && (mod2 == ValueTuple.UNMODIFIED))
068               ? ValueTuple.UNMODIFIED
069               : ValueTuple.MODIFIED);
070    return new ValueAndModified(intersect, mod);
071  }
072
073  @Override
074  protected VarInfo makeVarInfo() {
075    debug.fine("Computing varInfo");
076    return VarInfo.make_function("intersection", base1, base2);
077  }
078
079  @Pure
080  @Override
081  public boolean isSameFormula(Derivation other) {
082    return (other instanceof SequenceScalarIntersection);
083  }
084
085  @SideEffectFree
086  @Override
087  public String esc_name(String index) {
088    return String.format("intersection[%s,%s]", base1.esc_name(), base2.esc_name());
089  }
090}