001// ***** This file is automatically generated from PairwiseIntComparison.java.jpp 002 003package daikon.inv.binary.twoSequence; 004 005import daikon.*; 006import daikon.Quantify.QuantFlags; 007import daikon.derive.binary.*; 008import daikon.inv.*; 009import daikon.inv.binary.twoScalar.*; 010import daikon.suppress.*; 011import java.util.Arrays; 012import java.util.Iterator; 013import java.util.logging.Level; 014import java.util.logging.Logger; 015import org.checkerframework.checker.interning.qual.Interned; 016import org.checkerframework.checker.lock.qual.GuardSatisfied; 017import org.checkerframework.checker.nullness.qual.NonNull; 018import org.checkerframework.checker.nullness.qual.Nullable; 019import org.checkerframework.dataflow.qual.Pure; 020import org.checkerframework.dataflow.qual.SideEffectFree; 021import org.plumelib.util.ArraysPlume; 022import org.plumelib.util.Intern; 023import typequals.prototype.qual.NonPrototype; 024import typequals.prototype.qual.Prototype; 025 026/** 027 * Represents an invariant between corresponding elements of two sequences of double values. The 028 * length of the sequences must match for the invariant to hold. A comparison is made over each 029 * {@code (x[i], y[i])} pair. Thus, {@code x[0]} is compared to {@code y[0]}, 030 * {@code x[1]} to {@code y[1]}, and so forth. Prints as {@code x[] == y[]}. 031 */ 032public class PairwiseFloatEqual extends TwoSequenceFloat { 033 // We are Serializable, so we specify a version to allow changes to 034 // method signatures without breaking serialization. If you add or 035 // remove fields, you should change this number to the current date. 036 static final long serialVersionUID = 20030822L; 037 038 /** Debug tracer. */ 039 public static final Logger debug = 040 Logger.getLogger("daikon.inv.binary.twoSequence.PairwiseFloatEqual"); 041 042 // Variables starting with dkconfig_ should only be set via the 043 // daikon.config.Configuration interface. 044 /** Boolean. True iff PairwiseIntComparison invariants should be considered. */ 045 public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault; 046 047 static final boolean debugPairwiseIntComparison = false; 048 049 protected PairwiseFloatEqual(PptSlice ppt) { 050 super(ppt); 051 } 052 053 protected @Prototype PairwiseFloatEqual() { 054 super(); 055 } 056 057 private static @Prototype PairwiseFloatEqual proto = new @Prototype PairwiseFloatEqual(); 058 059 /** Returns the prototype invariant for PairwiseFloatEqual */ 060 public static @Prototype PairwiseFloatEqual get_proto() { 061 return proto; 062 } 063 064 /** Returns whether or not this invariant is enabled. */ 065 @Override 066 public boolean enabled() { 067 return dkconfig_enabled; 068 } 069 070 /** PairwiseFloatEqual is only valid on integral types. */ 071 @Override 072 public boolean instantiate_ok(VarInfo[] vis) { 073 074 if (!valid_types(vis)) { 075 return false; 076 } 077 078 return true; 079 } 080 081 /** instantiates the invariant on the specified slice */ 082 @Override 083 protected PairwiseFloatEqual instantiate_dyn(@Prototype PairwiseFloatEqual this, PptSlice slice) { 084 PairwiseFloatEqual inv = new PairwiseFloatEqual(slice); 085 if (logOn()) { 086 inv.log("instantiate"); 087 } 088 return inv; 089 } 090 091 @Pure 092 @Override 093 public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) { 094 VarInfo var1 = vis[0]; 095 VarInfo var2 = vis[1]; 096 097 DiscardInfo di = SubSequence.isObviousSubSequence(this, var1, var2); 098 if (di == null) { 099 di = SubSequence.isObviousSubSequence(this, var2, var1); 100 } 101 if (di != null) { 102 Global.implied_noninstantiated_invariants++; 103 return di; 104 } 105 106 // Don't instantiate if the variables can't have order 107 if (!var1.aux.hasOrder() || !var2.aux.hasOrder()) { 108 if (debug.isLoggable(Level.FINE)) { 109 debug.fine("Not instantitating for because order has no meaning: " 110 + var1.name() + " and " + var2.name()); 111 } 112 return new DiscardInfo(this, DiscardCode.obvious, "Obvious statically since order has no meaning"); 113 } 114 115 return super.isObviousStatically(vis); 116 } 117 118 @Pure 119 @Override 120 public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) { 121 DiscardInfo super_result = super.isObviousDynamically(vis); 122 if (super_result != null) { 123 return super_result; 124 } 125 126 // Subsequence invariants are implied by the same invariant over 127 // the supersequence 128 DiscardInfo di = superseq_implies(vis); 129 if (di != null) { 130 return di; 131 } 132 133 return null; 134 } 135 136 /** 137 * Checks to see if the same invariant exists over supersequences of these variables: 138 * 139 * <pre> 140 * (A[] op B[]) ^ (i == j) ⇒ A[i..] op B[j..] 141 * (A[] op B[]) ^ (i == j) ⇒ A[..i] op B[..j] 142 * </pre> 143 */ 144 private @Nullable DiscardInfo superseq_implies(VarInfo[] vis) { 145 146 // Make sure the variables are SequenceFloatSubsequence with the same start/end 147 VarInfo v1 = vis[0]; 148 VarInfo v2 = vis[1]; 149 if (!v1.isDerived() || !(v1.derived instanceof SequenceFloatSubsequence)) { 150 return null; 151 } 152 if (!v2.isDerived() || !(v2.derived instanceof SequenceFloatSubsequence)) { 153 return null; 154 } 155 @NonNull SequenceFloatSubsequence der1 = (SequenceFloatSubsequence) v1.derived; 156 @NonNull SequenceFloatSubsequence der2 = (SequenceFloatSubsequence) v2.derived; 157 if ((der1.from_start != der2.from_start) 158 || (der1.index_shift != der2.index_shift)) 159 return null; 160 161 // Make sure the subscripts are equal 162 DiscardInfo di = new DiscardInfo(this, DiscardCode.obvious, ""); 163 if (!ppt.parent.check_implied_canonical(di, der1.sclvar(), der2.sclvar(), 164 IntEqual.get_proto())) 165 return null; 166 167 // See if the super-sequences have the same invariant 168 if (!ppt.parent.check_implied_canonical(di, der1.seqvar(), der2.seqvar(), 169 PairwiseFloatEqual.get_proto())) 170 return null; 171 172 // Add in the vis variables to di reason (if they are different) 173 di.add_implied_vis(vis); 174 return di; 175 } 176 177 @Override 178 protected Invariant resurrect_done_swapped() { 179 180 return this; 181 } 182 183 @Pure 184 @Override 185 public boolean is_symmetric() { 186 return true; 187 } 188 189 @Override 190 public String repr(@GuardSatisfied PairwiseFloatEqual this) { 191 return "PairwiseFloatEqual" + varNames() + ": "; 192 } 193 194 public String getComparator() { 195 return "=="; 196 } 197 198 @SideEffectFree 199 @Override 200 public String format_using(@GuardSatisfied PairwiseFloatEqual this, OutputFormat format) { 201 202 if (format.isJavaFamily()) { 203 return format_java_family(format); 204 } 205 206 if (format == OutputFormat.DAIKON) { 207 return format_daikon(); 208 } 209 if (format == OutputFormat.ESCJAVA) { 210 return format_esc(); 211 } 212 if (format == OutputFormat.SIMPLIFY) { 213 return format_simplify(); 214 } 215 if (format == OutputFormat.CSHARPCONTRACT) { 216 return format_csharp(); 217 } 218 219 return format_unimplemented(format); 220 } 221 222 public String format_daikon(@GuardSatisfied PairwiseFloatEqual this) { 223 return var1().name() + " == " + var2().name() + " (elementwise)"; 224 } 225 226 public String format_esc(@GuardSatisfied PairwiseFloatEqual this) { 227 String[] form = VarInfo.esc_quantify(var1(), var2()); 228 return form[0] + "(" + form[1] + " == " + form[2] + ")" + form[3]; 229 } 230 231 public String format_simplify(@GuardSatisfied PairwiseFloatEqual this) { 232 String[] form = VarInfo.simplify_quantify(QuantFlags.element_wise(), var1(), var2()); 233 return form[0] + "(EQ " + form[1] + " " + form[2] + ")" + form[3]; 234 } 235 236 public String format_java_family(@GuardSatisfied PairwiseFloatEqual this, OutputFormat format) { 237 return "daikon.Quant.pairwiseEqual(" + var1().name_using(format) 238 + ", " + var2().name_using(format) + ")"; 239 } 240 241 public String format_csharp(@GuardSatisfied PairwiseFloatEqual this) { 242 243 String[] split1 = var1().csharp_array_split(); 244 String[] split2 = var2().csharp_array_split(); 245 246 String equals_str; 247 String end_str; 248 249 equals_str = " == "; 250 end_str = ""; 251 252 return "Contract.ForAll(0, " + split1[0] + ".Count(), i => " + split1[0] + "[i]" + split1[1] + equals_str + split2[0] + "[i]" + split2[1] + end_str + ")"; 253 } 254 255 @Override 256 public InvariantStatus check_modified(double @Interned [] a1, double @Interned [] a2, int count) { 257 assert a1 != null && a2 != null 258 : var1() + " " + var2() + " " + FileIO.get_linenum(); 259 if (a1.length != a2.length || a1.length == 0 || a2.length == 0) { 260 // destroyAndFlow(); 261 return InvariantStatus.FALSIFIED; 262 } 263 264 int len = a1.length; 265 // int len = Math.min(a1.length, a2.length); 266 267 for (int i = 0; i < len; i++) { 268 double v1 = a1[i]; 269 double v2 = a2[i]; 270 if (!Global.fuzzy.eq(v1, v2) ) { 271 // destroyAndFlow(); 272 return InvariantStatus.FALSIFIED; 273 } 274 } 275 return InvariantStatus.NO_CHANGE; 276 } 277 278 @Override 279 public InvariantStatus add_modified(double @Interned [] a1, double @Interned [] a2, 280 int count) { 281 if (logDetail()) { 282 log(debug, "saw add_modified (" + Arrays.toString(a1) 283 + ", " + Arrays.toString(a2) + ")"); 284 } 285 return check_modified(a1, a2, count); 286 } 287 288 @Override 289 protected double computeConfidence() { 290 // num_elt_values() would be more appropriate 291 // int num_values = ((PptSlice2) ppt).num_elt_values(); 292 int num_values = ppt.num_samples(); 293 if (num_values == 0) { 294 return Invariant.CONFIDENCE_UNJUSTIFIED; 295 } else { 296 297 // It's an equality invariant 298 return Invariant.CONFIDENCE_JUSTIFIED; 299 } 300 } 301 302 @Pure 303 @Override 304 public boolean isSameFormula(Invariant other) { 305 return true; 306 } 307 308 @Pure 309 @Override 310 public boolean isExclusiveFormula(Invariant other) { 311 return false; 312 } 313 314 // Look up a previously instantiated invariant. 315 public static @Nullable PairwiseFloatEqual find(PptSlice ppt) { 316 assert ppt.arity() == 2; 317 for (Invariant inv : ppt.invs) { 318 if (inv instanceof PairwiseFloatEqual) { 319 return (PairwiseFloatEqual) inv; 320 } 321 } 322 return null; 323 } 324 325 /** Returns a list of non-instantiating suppressions for this invariant. */ 326 @Pure 327 @Override 328 public @Nullable NISuppressionSet get_ni_suppressions() { 329 return suppressions; 330 } 331 332 private static @Nullable NISuppressionSet suppressions = null; 333 334}