001// ***** This file is automatically generated from SequenceScalar.java.jpp
002
003package daikon.inv.binary.sequenceScalar;
004
005import daikon.*;
006import daikon.inv.*;
007import daikon.inv.binary.BinaryInvariant;
008import org.checkerframework.checker.interning.qual.Interned;
009import org.checkerframework.checker.lock.qual.GuardSatisfied;
010import org.checkerframework.dataflow.qual.Pure;
011import org.plumelib.util.ArraysPlume;
012import org.plumelib.util.Intern;
013import typequals.prototype.qual.NonPrototype;
014import typequals.prototype.qual.Prototype;
015
016/**
017 * Abstract base class for comparing long sequences to long variables. Note that the sequence
018 * must always be passed in first. An example is {@code x is a member of a[]}.
019 */
020public abstract class SequenceScalar extends BinaryInvariant {
021
022  // We are Serializable, so we specify a version to allow changes to
023  // method signatures without breaking serialization.  If you add or
024  // remove fields, you should change this number to the current date.
025  static final long serialVersionUID = 20040113L;
026
027  protected SequenceScalar(PptSlice ppt) {
028    super(ppt);
029  }
030
031  protected @Prototype SequenceScalar() {
032    super();
033  }
034
035  /**
036   * Returns whether or not the specified types are valid. All subclasses accept a scalar in one
037   * parameter and an array over the same scalar type in the other.
038   */
039  @Override
040  public boolean valid_types(VarInfo[] vis) {
041
042    if (vis.length != 2) {
043      return false;
044    }
045
046    if (!vis[0].file_rep_type.baseIsScalar() || !vis[1].file_rep_type.baseIsScalar()) {
047      return false;
048    }
049
050    return vis[0].file_rep_type.isArray() ^ vis[1].file_rep_type.isArray();
051  }
052
053  /**
054   * Since the order is determined from the vars and the sequence is always first, no permute is
055   * necesesary. Subclasses can override if necessary.
056   */
057  protected Invariant resurrect_done_swapped() {
058    return this;
059  }
060
061  /**
062   * Since the order is determined from the vars and the sequence is always first, this is
063   * essentially symmetric. Subclasses can override if necessary.
064   */
065  @Pure
066  @Override
067  public boolean is_symmetric() {
068    return true;
069  }
070
071  // Check if swap occurred and call one of the other two methods
072  @Override
073  protected Invariant resurrect_done(int[] permutation) {
074    assert permutation.length == 2;
075    // assert ArraysPlume.fnIsPermutation(permutation);
076    if (permutation[0] == 1) {
077      return resurrect_done_swapped();
078    } else {
079      return resurrect_done_unswapped();
080    }
081  }
082
083   /** Subclasses can override in the rare cases they need to fix things even when not swapped. */
084  protected Invariant resurrect_done_unswapped() {
085    // do nothing
086    return this;
087  }
088
089 protected final boolean seq_first(@GuardSatisfied SequenceScalar this) {
090    return ppt.var_infos[0].rep_type == ProglangType.INT_ARRAY;
091  }
092
093  protected final int seq_index(@GuardSatisfied SequenceScalar this) {
094    return seq_first() ? 0 : 1;
095  }
096
097  protected final int scl_index(@GuardSatisfied SequenceScalar this) {
098    return seq_first() ? 1 : 0;
099  }
100
101  public VarInfo seqvar(@GuardSatisfied SequenceScalar this) {
102    return ppt.var_infos[seq_index()];
103  }
104
105  public VarInfo sclvar(@GuardSatisfied SequenceScalar this) {
106    return ppt.var_infos[scl_index()];
107  }
108
109  /**
110   * Return the sequence variable in the tuple whose VarInfos are corresponds to this.ppt.var_infos.
111   */
112  public VarInfo seqvar(VarInfo[] vis) {
113    return vis[seq_index()];
114  }
115
116  /**
117   * Return the scalar variable in the tuple whose VarInfos are corresponds to this.ppt.var_infos.
118   */
119  public VarInfo sclvar(VarInfo[] vis) {
120    return vis[scl_index()];
121  }
122
123  @Override
124  public InvariantStatus check(
125      @Interned Object val1, @Interned Object val2, int mod_index, int count) {
126    assert !falsified;
127    assert (mod_index >= 0) && (mod_index < 4);
128    long[] v1 = (long[]) val1;
129    long v2 = ((Long) val2).longValue();
130    if (v1 == null) {
131    } else if (mod_index == 0) {
132      return check_unmodified(v1, v2, count);
133    } else {
134      return check_modified(v1, v2, count);
135    }
136    return InvariantStatus.NO_CHANGE;
137  }
138
139  @Override
140  public InvariantStatus add(
141      @Interned Object val1, @Interned Object val2, int mod_index, int count) {
142    assert !falsified;
143    assert (mod_index >= 0) && (mod_index < 4);
144    long[] v1 = (long[]) val1;
145    long v2 = ((Long) val2).longValue();
146    if (v1 == null) {
147    } else if (mod_index == 0) {
148      return add_unmodified(v1, v2, count);
149    } else {
150      return add_modified(v1, v2, count);
151    }
152    return InvariantStatus.NO_CHANGE;
153  }
154
155  /**
156   * Presents a sample to the invariant. Returns whether the sample is consistent with the
157   * invariant. Does not change the state of the invariant.
158   *
159   * @param count how many identical samples were observed in a row. For example, three calls to
160   *     check_modified with a count parameter of 1 is equivalent to one call to check_modified with
161   *     a count parameter of 3.
162   * @return whether or not the sample is consistent with the invariant
163   */
164  public abstract InvariantStatus check_modified(long @Interned [] v1, long v2, int count);
165
166  public InvariantStatus check_unmodified(long @Interned [] v1, long v2, int count) {
167    return InvariantStatus.NO_CHANGE;
168  }
169
170  /**
171   * Similar to {@link #check_modified} except that it can change the state of the invariant if
172   * necessary. If the invariant doesn't have any state, then the implementation should simply call
173   * {@link #check_modified}. This method need not check for falsification; that is done by the
174   * caller.
175   */
176  public abstract InvariantStatus add_modified(long @Interned [] v1, long v2, int count);
177
178  /** By default, do nothing if the value hasn't been seen yet. Subclasses can override this. */
179  public InvariantStatus add_unmodified(long @Interned [] v1, long v2, int count) {
180    return InvariantStatus.NO_CHANGE;
181  }
182}