001// ***** This file is automatically generated from EltwiseIntComparisons.java.jpp
002
003package daikon.inv.unary.sequence;
004
005import daikon.*;
006import daikon.Quantify.QuantFlags;
007import daikon.derive.*;
008import daikon.derive.binary.*;
009import daikon.inv.*;
010import java.util.*;
011import org.checkerframework.checker.interning.qual.Interned;
012import org.checkerframework.checker.lock.qual.GuardSatisfied;
013import org.checkerframework.checker.nullness.qual.Nullable;
014import org.checkerframework.dataflow.qual.Pure;
015import org.checkerframework.dataflow.qual.SideEffectFree;
016import org.plumelib.util.Intern;
017import typequals.prototype.qual.NonPrototype;
018import typequals.prototype.qual.Prototype;
019
020  /**
021   * Represents equality between adjacent elements (x[i], x[i+1]) of a double sequence. Prints as
022   * {@code x[] elements are equal}.
023   */
024
025public class EltwiseFloatEqual extends EltwiseFloatComparison {
026  // We are Serializable, so we specify a version to allow changes to
027  // method signatures without breaking serialization.  If you add or
028  // remove fields, you should change this number to the current date.
029  static final long serialVersionUID = 20030822L;
030
031  // Variables starting with dkconfig_ should only be set via the
032  // daikon.config.Configuration interface.
033  /** Boolean. True iff EltwiseIntComparison invariants should be considered. */
034  public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault;
035
036  static final boolean debugEltwiseIntComparison = false;
037
038  protected EltwiseFloatEqual(PptSlice ppt) {
039    super(ppt);
040  }
041
042  protected @Prototype EltwiseFloatEqual() {
043    super();
044  }
045
046  private static @Prototype EltwiseFloatEqual proto = new @Prototype EltwiseFloatEqual();
047
048  /** Returns the prototype invariant for EltwiseFloatEqual */
049  public static @Prototype EltwiseFloatEqual get_proto() {
050    return proto;
051  }
052
053  /** returns whether or not this invariant is enabled */
054  @Override
055  public boolean enabled() {
056    return dkconfig_enabled;
057  }
058
059  /** Non-equality EltwiseFloatEqual invariants are only valid on integral types. */
060  @Override
061  public boolean instantiate_ok(VarInfo[] vis) {
062
063    if (!valid_types(vis)) {
064      return false;
065    }
066
067    return true;
068  }
069
070  /** Instantiate the invariant on the specified slice. */
071  @Override
072  protected EltwiseFloatEqual instantiate_dyn(@Prototype EltwiseFloatEqual this, PptSlice slice) {
073    return new EltwiseFloatEqual(slice);
074  }
075
076  @SideEffectFree
077  @Override
078  public EltwiseFloatEqual clone(@GuardSatisfied EltwiseFloatEqual this) {
079    EltwiseFloatEqual result = (EltwiseFloatEqual) super.clone();
080    return result;
081  }
082
083  @Override
084  public String repr(@GuardSatisfied EltwiseFloatEqual this) {
085    return "EltwiseFloatEqual" + varNames() + ": falsified=" + falsified;
086  }
087
088  @SideEffectFree
089  @Override
090  public String format_using(@GuardSatisfied EltwiseFloatEqual this, OutputFormat format) {
091    if (format.isJavaFamily()) {
092      return format_java_family(format);
093    }
094
095    if (format == OutputFormat.DAIKON) {
096      return format_daikon();
097    }
098    if (format == OutputFormat.ESCJAVA) {
099      return format_esc();
100    }
101    if (format == OutputFormat.CSHARPCONTRACT) {
102      return format_csharp_contract();
103    }
104    if (format == OutputFormat.SIMPLIFY) {
105      return format_simplify();
106    }
107
108    return format_unimplemented(format);
109  }
110
111  public String format_daikon(@GuardSatisfied EltwiseFloatEqual this) {
112    if (debugEltwiseIntComparison) {
113      System.out.println(repr());
114    }
115
116    return var().name() + " sorted by ==";
117  }
118
119  public String format_esc(@GuardSatisfied EltwiseFloatEqual this) {
120    String[] form = VarInfo.esc_quantify(false, var(), var());
121
122      return form[0] + "(" + form[1] + " == " + form[2] + ")" + form[3];
123  }
124
125  public String format_java_family(@GuardSatisfied EltwiseFloatEqual this, OutputFormat format) {
126    return "daikon.Quant.eltwiseEqual(" + var().name_using(format) + ")";
127  }
128
129  public String format_csharp_contract(@GuardSatisfied EltwiseFloatEqual this) {
130    String[] split = var().csharp_array_split();
131    return "Contract.ForAll(0, " + split[0] + ".Count()-1, i => " + split[0] + "[i]" + split[1] + " == " + split[0] + "[i+1]" + split[1] + ")";
132  }
133
134  public String format_simplify(@GuardSatisfied EltwiseFloatEqual this) {
135    String[] form = VarInfo.simplify_quantify(QuantFlags.adjacent(),
136                                               var(), var());
137
138    String comparator = "EQ";
139
140    return form[0] + "(" + comparator + " " + form[1] + " " + form[2] + ")"
141      + form[3];
142  }
143
144  @Override
145  @SuppressWarnings("UnnecessaryParentheses")  // generated code, parentheses are sometimes needed
146  public InvariantStatus check_modified(double @Interned [] a, int count) {
147    for (int i = 1; i < a.length; i++) {
148      if (!Global.fuzzy.eq(a[i - 1], a[i])) {
149        return InvariantStatus.FALSIFIED;
150      }
151    }
152    return InvariantStatus.NO_CHANGE;
153  }
154
155  @Override
156  public InvariantStatus add_modified(double @Interned [] a, int count) {
157    return check_modified(a, count);
158  }
159
160  // Perhaps check whether all the arrays of interest have length 0 or 1.
161
162  @Override
163  protected double computeConfidence() {
164
165    if (ppt.num_samples() != 0) {
166      return Invariant.CONFIDENCE_JUSTIFIED;
167    } else {
168      return Invariant.CONFIDENCE_UNJUSTIFIED;
169    }
170
171  }
172
173  @Pure
174  @Override
175  public boolean isExact() {
176
177    return true;
178  }
179
180  @Pure
181  @Override
182  public boolean isSameFormula(Invariant other) {
183    return (other instanceof EltwiseFloatEqual);
184  }
185
186  // Not pretty... is there another way?
187  // Also, reasonably complicated, need to ensure exact correctness, not sure if the
188  // regression tests test this functionality
189
190  @Pure
191  @Override
192  public boolean isExclusiveFormula(Invariant other) {
193    // This whole approach is wrong in the case when the sequence can
194    // ever consist of only one element.  For now, just forget
195    // it. -SMcC
196    if (true) {
197      return false;
198    }
199
200    if (other instanceof EltwiseFloatComparison) {
201
202      return !((other instanceof EltwiseIntEqual) || (other instanceof EltwiseFloatEqual)
203               || (other instanceof EltwiseIntLessEqual) || (other instanceof EltwiseFloatLessEqual)
204               || (other instanceof EltwiseIntGreaterEqual) || (other instanceof EltwiseFloatGreaterEqual));
205
206    }
207    return false;
208  }
209
210  // Look up a previously instantiated invariant.
211  public static @Nullable EltwiseFloatEqual find(PptSlice ppt) {
212    assert ppt.arity() == 1;
213    for (Invariant inv : ppt.invs) {
214      if (inv instanceof EltwiseFloatEqual) {
215        return (EltwiseFloatEqual) inv;
216      }
217    }
218    return null;
219  }
220
221  // Copied from IntComparison.
222  // public boolean isExclusiveFormula(Invariant other)
223  // {
224  //   if (other instanceof IntComparison) {
225  //     return core.isExclusiveFormula(((IntComparison) other).core);
226  //   }
227  //   if (other instanceof IntNonEqual) {
228  //     return isExact();
229  //   }
230  //   return false;
231  // }
232
233  /**
234   * This function returns whether a sample has been seen by this Invariant that includes two or
235   * more entries in an array. For a 0 or 1 element array a, a[] sorted by any binary operation is
236   * "vacuously true" because no check is ever made since the binary operation requires two
237   * operands. Thus although invariants of this type are true regarding 0 or 1 length arrays, they
238   * are meaningless. This function is meant to be used in isObviousImplied() to prevent such
239   * meaningless invariants from being printed.
240   */
241  @Override
242  public boolean hasSeenNonSingletonSample() {
243    ValueSet.ValueSetFloatArray vs = (ValueSet.ValueSetFloatArray) ppt.var_infos[0].get_value_set();
244    return vs.nonsingleton_arr_cnt() > 0;
245  }
246
247  @Pure
248  @Override
249  public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) {
250    DiscardInfo super_result = super.isObviousDynamically(vis);
251    if (super_result != null) {
252      return super_result;
253    }
254
255    if (!hasSeenNonSingletonSample()) {
256      return new DiscardInfo(this, DiscardCode.obvious,
257                             "No samples sequences of size >=2 were seen. Vacuously true.");
258    }
259
260    EltOneOfFloat eoo = EltOneOfFloat.find(ppt);
261    if ((eoo != null) && eoo.enoughSamples() && (eoo.num_elts() == 1)) {
262      return new DiscardInfo(this, DiscardCode.obvious, "The sequence contains all equal values.");
263    }
264
265    // sorted by (any operation) for an entire sequence -> sorted by that same
266    // operation for a subsequence
267
268    // also, sorted by < for entire -> sorted by <= for subsequence
269    //       sorted by > for entire -> sorted by >= for subsequence
270
271    Derivation deriv = vis[0].derived;
272
273    if ((deriv instanceof SequenceScalarSubsequence) || (deriv instanceof SequenceFloatSubsequence)) {
274      // Find the slice with the full sequence, check for an invariant of this type
275      PptSlice sliceToCheck;
276
277      if (deriv instanceof SequenceScalarSubsequence) {
278        sliceToCheck = ppt.parent.findSlice(((SequenceScalarSubsequence)deriv).seqvar());
279      } else {
280        sliceToCheck = ppt.parent.findSlice(((SequenceFloatSubsequence)deriv).seqvar());
281      }
282
283      if (sliceToCheck != null) {
284        for (Invariant inv : sliceToCheck.invs) {
285
286          if (inv.getClass().equals(getClass())) {
287            String discardString = "This is a subsequence of a sequence for which the same invariant holds.";
288            return new DiscardInfo(this, DiscardCode.obvious, discardString);
289          }
290        }
291      }
292    }
293
294    return null;
295  }
296}