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