001package daikon.inv.unary.scalar;
002
003import daikon.PptSlice;
004import daikon.VarInfo;
005import daikon.inv.InvariantStatus;
006import daikon.inv.unary.UnaryInvariant;
007import org.checkerframework.checker.initialization.qual.UnknownInitialization;
008import org.checkerframework.checker.interning.qual.Interned;
009import org.checkerframework.checker.lock.qual.GuardSatisfied;
010import typequals.prototype.qual.Prototype;
011
012/**
013 * Abstract base class for invariants over one numeric (scalar) variable, such as {@code x != 0}.
014 */
015public abstract class SingleScalar extends UnaryInvariant {
016  // We are Serializable, so we specify a version to allow changes to
017  // method signatures without breaking serialization.  If you add or
018  // remove fields, you should change this number to the current date.
019  static final long serialVersionUID = 20020122L;
020
021  protected SingleScalar(PptSlice ppt) {
022    super(ppt);
023  }
024
025  protected @Prototype SingleScalar() {
026    super();
027  }
028
029  public VarInfo var(@GuardSatisfied @UnknownInitialization(SingleScalar.class) SingleScalar this) {
030    return ppt.var_infos[0];
031  }
032
033  /**
034   * Returns whether or not the specified types are valid for unary scalar. (Static version of
035   * method.)
036   */
037  public static final boolean valid_types_static(VarInfo[] vis) {
038    return (vis.length == 1) && vis[0].file_rep_type.isScalar();
039  }
040
041  /** Returns whether or not the specified types are valid for unary scalar. */
042  @Override
043  public final boolean valid_types(VarInfo[] vis) {
044    return valid_types_static(vis);
045  }
046
047  // Should never be called with modified == ValueTuple.MISSING_NONSENSICAL.
048  // Subclasses need not override this except in special cases;
049  // just implement {@link #add_modified(Object,int)}.
050  @Override
051  public InvariantStatus add(@Interned Object val, int mod_index, int count) {
052    assert !falsified;
053    assert (mod_index >= 0) && (mod_index < 2);
054    long value = ((Long) val).longValue();
055    if (mod_index == 0) {
056      return add_unmodified(value, count);
057    } else {
058      return add_modified(value, count);
059    }
060  }
061
062  @Override
063  public InvariantStatus check(@Interned Object val, int mod_index, int count) {
064    assert !falsified;
065    assert (mod_index >= 0) && (mod_index < 2);
066    long value = ((Long) val).longValue();
067    if (mod_index == 0) {
068      return check_unmodified(value, count);
069    } else {
070      return check_modified(value, count);
071    }
072  }
073
074  /**
075   * Similar to {@link #check_modified} except that it can change the state of the invariant if
076   * necessary. If the invariant doesn't have any state, then the implementation should simply call
077   * {@link #check_modified}. This method need not check for falsification; that is done by the
078   * caller.
079   */
080  public abstract InvariantStatus add_modified(long value, int count);
081
082  /** By default, do nothing if the value hasn't been seen yet. Subclasses can override this. */
083  public InvariantStatus add_unmodified(long value, int count) {
084    // System.out.println("SingleScalar.add_unmodified " + ppt.name() + ": parent=" + ppt.parent);
085    return InvariantStatus.NO_CHANGE;
086  }
087
088  /**
089   * Presents a sample to the invariant. Returns whether the sample is consistent with the
090   * invariant. Does not change the state of the invariant.
091   *
092   * @param count how many identical samples were observed in a row. For example, three calls to
093   *     check_modified with a count parameter of 1 is equivalent to one call to check_modified with
094   *     a count parameter of 3.
095   * @return whether or not the sample is consistent with the invariant
096   */
097  public abstract InvariantStatus check_modified(long value, int count);
098
099  public InvariantStatus check_unmodified(long value, int count) {
100    return InvariantStatus.NO_CHANGE;
101  }
102
103  // This has no additional suppression factories beyond those of Invariant.
104
105}