001// ***** This file is automatically generated from SequenceInitial.java.jpp
002
003package daikon.derive.unary;
004
005import org.checkerframework.dataflow.qual.SideEffectFree;
006import org.checkerframework.dataflow.qual.Pure;
007import org.checkerframework.checker.interning.qual.Interned;
008import daikon.*;
009import daikon.derive.*;
010import daikon.derive.binary.*;
011import org.plumelib.util.Intern;
012
013// originally from pass1.
014/**
015 * This represents a sequence element at a particular offset (such as first, second, penultimate,
016 * last).
017 */
018public final class SequenceInitialFloat extends UnaryDerivation {
019  // We are Serializable, so we specify a version to allow changes to
020  // method signatures without breaking serialization.  If you add or
021  // remove fields, you should change this number to the current date.
022  static final long serialVersionUID = 20020122L;
023
024  // Variables starting with dkconfig_ should only be set via the
025  // daikon.config.Configuration interface.
026  /** Boolean. True iff SequenceInitial derived variables should be generated. */
027  public static boolean dkconfig_enabled = false;
028
029  /** Typically 0, 1, -1, or -2. A negative number means counting from end. */
030  public final int index;
031
032  /** Array length required for the subscript to be meaningful:  (i.e., 1 or 2) */
033  final int minLength;
034
035  SequenceInitialFloat(VarInfo vi, int index) {
036    super(vi);
037    this.index = index;
038    if (index < 0) {
039      minLength = -index;
040    } else {
041      minLength = index + 1;
042    }
043  }
044
045  public VarInfo seqvar() {
046    return base;
047  }
048
049  public static boolean applicable(VarInfo vi) {
050    assert vi.rep_type == ProglangType.DOUBLE_ARRAY;
051    // For now, applicable if not a derived variable; a better test is if
052    // not a prefix subsequence (sequence slice) we have added.
053    if (vi.derived != null) {
054      assert (vi.derived instanceof SequenceFloatSubsequence)
055          || (vi.derived instanceof SequenceFloatIntersection)
056          || (vi.derived instanceof SequenceFloatUnion);
057      return false;
058    }
059
060    // If order doesn't matter
061    if (!vi.aux.hasOrder()) {
062      return false;
063    }
064
065    return true;
066  }
067
068  @Override
069  public ValueAndModified computeValueAndModifiedImpl(ValueTuple vt) {
070    int source_mod = base.getModified(vt);
071    if (source_mod == ValueTuple.MISSING_NONSENSICAL) {
072      return ValueAndModified.MISSING_NONSENSICAL;
073    }
074    Object val = base.getValue(vt);
075    if (val == null) {
076      return ValueAndModified.MISSING_NONSENSICAL;
077    }
078    if (base.rep_type == ProglangType.DOUBLE_ARRAY) {
079      double[] val_array = (double[]) val;
080      if (val_array.length < minLength) {
081        return ValueAndModified.MISSING_NONSENSICAL;
082      }
083      int real_index = (index < 0 ? val_array.length + index : index);
084      return new ValueAndModified(Intern.internedDouble(val_array[real_index]), source_mod);
085    } else {
086      @Interned Object[] val_array = (@Interned Object[]) val;
087      if (val_array.length < minLength) {
088        return ValueAndModified.MISSING_NONSENSICAL;
089      }
090      int real_index = (index < 0 ? val_array.length + index : index);
091      return new ValueAndModified(val_array[real_index], source_mod);
092    }
093  }
094
095  @Override
096  protected VarInfo makeVarInfo() {
097    return VarInfo.make_subscript(base, null, index);
098  }
099
100  @Pure
101  @Override
102  public boolean isSameFormula(Derivation other) {
103    return (other instanceof SequenceInitialFloat)
104      && (((SequenceInitialFloat) other).index == this.index);
105  }
106
107  /** Returns the ESC name. */
108  @SideEffectFree
109  @Override
110  public String esc_name(String index) {
111    return String.format("%s[0]", base.esc_name());
112  }
113}