001// ***** This file is automatically generated from SequencesPredicate.java.jpp
002
003package daikon.derive.binary;
004
005import org.checkerframework.checker.interning.qual.Interned;
006import org.checkerframework.checker.lock.qual.GuardSatisfied;
007import org.checkerframework.dataflow.qual.Pure;
008import org.checkerframework.dataflow.qual.SideEffectFree;
009import daikon.*;
010import daikon.derive.*;
011import java.util.logging.Logger;
012import org.plumelib.util.Intern;
013
014/**
015 * Derived variable representing the selecting of elements of one sequence based on the values of
016 * another sequence. We only predicate if we know that both sequences came from the same original
017 * data structure. Derived type is the same as that of the first sequence.
018 */
019public final class SequencesPredicateFloat extends BinaryDerivation {
020  static final long serialVersionUID = 20020122L;
021
022  /** Debug tracer. */
023  public static final Logger debug =
024    Logger.getLogger("daikon.derive.binary.SequencesPredicateFloat");
025
026  // Variables starting with dkconfig_ should only be set via the
027  // daikon.config.Configuration interface.
028  /** Boolean. True iff SequencesPredicate derived variables should be generated. */
029  public static boolean dkconfig_enabled = false;
030
031  /**
032   * Boolean. True if Daikon should only generate derivations on fields of the same data structure.
033   */
034  public static boolean dkconfig_fieldOnly = true;
035
036  /** Boolean. True if Daikon should only generate derivations on boolean predicates. */
037  public static boolean dkconfig_boolOnly = true;
038
039  @Override
040  public VarInfo var1(@GuardSatisfied SequencesPredicateFloat this) {
041    return base1;
042  }
043
044  @Override
045  public VarInfo var2(@GuardSatisfied SequencesPredicateFloat this) {
046    return base2;
047  }
048
049  /** What value to predicate on. */
050  private double choose;
051
052  /** Whether we keep or discard values that match this.choose. */
053  private boolean keep;
054
055  /** What this predication is called (e.g. for choose == 0 and 1, use "false" and "true"). */
056  private String name;
057
058  /**
059   * Create a new SequencesJoin derivation.
060   *
061   * @param vi1 the first of the two variables this is based on
062   * @param vi2 the second of the two variables this is based on
063   */
064  SequencesPredicateFloat(VarInfo vi1, VarInfo vi2, double argChoose, String argName) {
065    this(vi1, vi2, argChoose, argName, true);
066  }
067
068  /**
069   * Create a new SequencesJoin derivation.
070   *
071   * @param vi1 the first of the two variables this is based on
072   * @param vi2 the second of the two variables this is based on
073   */
074  SequencesPredicateFloat(
075      VarInfo vi1, VarInfo vi2, double argChoose, String argName, boolean argKeep) {
076    super(vi1, vi2);
077    choose = argChoose;
078    name = argName;
079    keep = argKeep;
080  }
081
082  /**
083   * Returns a subset of val1 such that the corresponding element in var2 equals this.choose. It is
084   * assumed that val1 and val2 originated from the same, larger data structure.
085   *
086   * @param full_vt the value tuple of a program point to compute the derived value from
087   */
088  @Override
089  public ValueAndModified computeValueAndModifiedImpl(ValueTuple full_vt) {
090    Object val1 = var1().getValue(full_vt);
091    Object val2 = var2().getValue(full_vt);
092
093    int length1 = -1;
094    int length2 = -2; // They must equal in the end
095
096    if (val1 == null) {
097      length1 = 0;
098    }
099
100    if (val2 == null) {
101      length2 = 0;
102    }
103
104    if (val1 instanceof double[]) {
105      length1 = ((double[]) val1).length;
106    }
107
108    if (val2 instanceof double[]) {
109      length2 = ((double[]) val2).length;
110    }
111
112    if (val1 instanceof Object[]) {
113      length1 = ((Object[]) val1).length;
114    }
115
116    assert val2 == null || val2 instanceof double[];
117
118    if (length1 != length2) {
119      // This derived variable is no longer interesting
120      return new ValueAndModified(null, ValueTuple.MISSING_NONSENSICAL);
121    }
122
123    assert length1 == length2;
124
125    int mod = ValueTuple.UNMODIFIED;
126    int mod1 = var1().getModified(full_vt);
127    int mod2 = var2().getModified(full_vt);
128    if (mod1 == ValueTuple.MODIFIED) {
129      mod = ValueTuple.MODIFIED;
130    }
131    if (mod2 == ValueTuple.MODIFIED) {
132      mod = ValueTuple.MODIFIED;
133    }
134    if (mod1 == ValueTuple.MISSING_NONSENSICAL) {
135      mod = ValueTuple.MISSING_NONSENSICAL;
136    }
137    if (mod2 == ValueTuple.MISSING_NONSENSICAL) {
138      mod = ValueTuple.MISSING_NONSENSICAL;
139    }
140    /*
141     * v1\v2  Unm  Mod  Mis
142     *
143     * Unm    Unm  Mod  Mis
144     * Mod    Mod  Mod  Mis
145     * Mis    Mis  Mis  Mis
146     */
147
148    double[] predicate = (double[]) val2;
149    int count = 0;
150    // Find length of output first
151    for (int i = 0; i < predicate.length; i++) {
152      if ((predicate[i] == choose) ^ !keep) {
153        count += 1;
154      }
155    }
156
157    if (val1 instanceof double[]) {
158      double[] result = new double[count];
159      double[] values = (double[]) val1;
160      int j = 0;
161      for (int i = 0; i < length1; i++) {
162        if ((predicate[i] == choose) ^ !keep) {
163          result[j] = values[i];
164          j++;
165        }
166      }
167      return new ValueAndModified(Intern.intern(result), mod);
168    } else if (val1 instanceof Object[]) {
169      @Interned Object[] result = new @Interned Object[count];
170      @Interned Object[] values = (@Interned Object[]) val1;
171      int j = 0;
172      for (int i = 0; i < length1; i++) {
173        if ((predicate[i] == choose) ^ !keep) {
174          result[j] = values[i];
175          j++;
176        }
177      }
178      return new ValueAndModified(Intern.intern(result), mod);
179    } else if (val1 == null) {
180      return new ValueAndModified(null, mod);
181    } else {
182      throw new RuntimeException("Invalid input arrays");
183    }
184  }
185
186  @Override
187  protected VarInfo makeVarInfo() {
188    return VarInfo.make_function("predicateSlice", var1(), var2());
189  }
190
191  @SideEffectFree
192  @Override
193  public String toString(@GuardSatisfied SequencesPredicateFloat this) {
194    return "[SequencesPredicateFloat of "
195        + var1().name()
196        + " "
197        + var2().name()
198        + " for "
199        + name
200        + "]";
201  }
202
203  @Pure
204  @Override
205  public boolean isSameFormula(Derivation other) {
206    // For Toh (tohn) to do.
207    if (other instanceof SequencesPredicateFloat) {
208      SequencesPredicateFloat o = (SequencesPredicateFloat) other;
209      return o.var1().equals(var1()) && o.var2().equals(var2()) && choose == o.choose;
210    }
211    return false;
212  }
213
214  @SideEffectFree
215  @Override
216  public String esc_name(String index) {
217    return String.format("predicate(%s,%s)", var1().esc_name(), var2().esc_name());
218  }
219}