001// ***** This file is automatically generated from EltNonZero.java.jpp 002 003package daikon.inv.unary.sequence; 004 005import daikon.*; 006import daikon.inv.*; 007import daikon.inv.ValueSet; 008import daikon.inv.binary.twoSequence.*; 009import daikon.inv.unary.scalar.*; 010import daikon.suppress.*; 011import java.util.*; 012import java.util.logging.Level; 013import java.util.logging.Logger; 014import org.checkerframework.checker.interning.qual.Interned; 015import org.checkerframework.checker.lock.qual.GuardSatisfied; 016import org.checkerframework.checker.nullness.qual.NonNull; 017import org.checkerframework.checker.nullness.qual.Nullable; 018import org.checkerframework.dataflow.qual.Pure; 019import org.checkerframework.dataflow.qual.SideEffectFree; 020import org.plumelib.util.Intern; 021import typequals.prototype.qual.NonPrototype; 022import typequals.prototype.qual.Prototype; 023 024/** 025 * Represents the invariant "x != 0" where x represents all of the elements of a sequence of 026 * double. Prints as {@code x[] elements != 0}. 027 */ 028 029public final class EltNonZeroFloat extends SingleFloatSequence { 030 /** Debug tracer. */ 031 public static final Logger debug = 032 Logger.getLogger("daikon.inv.unary.sequence.EltNonZeroFloat"); 033 034 static final long serialVersionUID = 20030822L; 035 036 // Variables starting with dkconfig_ should only be set via the 037 // daikon.config.Configuration interface. 038 /** Boolean. True iff EltNonZero invariants should be considered. */ 039 public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault; 040 041 EltNonZeroFloat(PptSlice ppt) { 042 super(ppt); 043 } 044 045 @Prototype EltNonZeroFloat() { 046 super(); 047 } 048 049 private static @Prototype EltNonZeroFloat proto = new @Prototype EltNonZeroFloat(); 050 051 /** Returns the prototype invariant for EltNonZeroFloat */ 052 public static @Prototype EltNonZeroFloat get_proto() { 053 return proto; 054 } 055 056 @Override 057 public boolean enabled() { 058 return dkconfig_enabled; 059 } 060 061 @Override 062 protected EltNonZeroFloat instantiate_dyn(@Prototype EltNonZeroFloat this, PptSlice slice) { 063 return new EltNonZeroFloat(slice); 064 } 065 066 /** Returns whether or not the variable is a pointer. */ 067 @Pure 068 private boolean is_pointer(@GuardSatisfied EltNonZeroFloat this) { 069 return !ppt.var_infos[0].type.baseIsFloat(); 070 } 071 072 @Override 073 public String repr(@GuardSatisfied EltNonZeroFloat this) { 074 return "EltNonZeroFloat" + varNames() + ": " 075 + !falsified; 076 } 077 078 @SideEffectFree 079 @Override 080 public String format_using(@GuardSatisfied EltNonZeroFloat this, OutputFormat format) { 081 if (format.isJavaFamily()) { 082 return format_java_family(format); 083 } 084 085 if (format == OutputFormat.DAIKON) { 086 return format_daikon(); 087 } 088 if (format == OutputFormat.ESCJAVA) { 089 return format_esc(); 090 } 091 if (format == OutputFormat.CSHARPCONTRACT) { 092 return format_csharp_contract(); 093 } 094 if (format == OutputFormat.SIMPLIFY) { 095 return format_simplify(); 096 } 097 098 return format_unimplemented(format); 099 } 100 101 public String format_daikon(@GuardSatisfied EltNonZeroFloat this) { 102 return var().name() + " elements != " 103 + (is_pointer() ? "null" : "0"); 104 } 105 106 // We are a special case where a ghost field can actually talk about 107 // array contents. 108 @Pure 109 @Override 110 public boolean isValidEscExpression() { 111 return true; 112 } 113 114 public String format_esc(@GuardSatisfied EltNonZeroFloat this) { 115 // If this is an entire array or Collection (not a slice), then 116 // * for arrays: use \nonnullelements(A) 117 // * for Collections: use collection.containsNull == false 118 // (the latter also requires that ghost field to get set) 119 120 // if (var().isDerivedSubSequenceOf() == null) { 121 if (var().is_direct_non_slice_array()) { 122 VarInfo term = var().get_enclosing_var(); 123 String esc_name; 124 if (term == null) { 125 // Only happenes in internal format tests 126 esc_name = var().name().replace("[]", ""); 127 } else { 128 // System.out.printf("term = %s, var = %s%n", term.name, var().name); 129 esc_name = term.esc_name(); 130 } 131 if (var().type.isArray()) { 132 return "\\nonnullelements(" + esc_name + ")"; 133 } else { 134 return esc_name + ".containsNull == false"; 135 } 136 } 137 138 // If this is just part of an array or Collection (var is a 139 // slice), then calling viname.esc_name() will always throw an 140 // exception, since var() is certainly a sequence. So use the 141 // standard quantification. 142 143 String[] form = VarInfo.esc_quantify(var()); 144 return form[0] + "(" + form[1] + " != " 145 + (is_pointer() ? "null" : "0") + ")" + form[2]; 146 } 147 148 public String format_java_family(@GuardSatisfied EltNonZeroFloat this, OutputFormat format) { 149 String retval = 150 "daikon.Quant.eltsNotEqual(" + var().name_using(format) 151 + (is_pointer() ? ", null" : ", 0") + ")"; 152 153 return retval; 154 } 155 156 public String format_csharp_contract(@GuardSatisfied EltNonZeroFloat this) { 157 String[] split = var().csharp_array_split(); 158 return "Contract.ForAll(" + split[0] + ", x => x" + split[1] + " != " + (is_pointer() ? "null" : "0") + ")"; 159 } 160 161 public String format_simplify(@GuardSatisfied EltNonZeroFloat this) { 162 String[] form = VarInfo.simplify_quantify(var()); 163 return form[0] + "(NEQ " + form[1] + " " 164 + (is_pointer() ? "null" : "0") + ")" + form[2]; 165 } 166 167 @Override 168 @SuppressWarnings("UnnecessaryParentheses") // generated code, parentheses are sometimes needed 169 public InvariantStatus check_modified(double @Interned [] a, int count) { 170 for (int ai = 0; ai < a.length; ai++) { 171 double v = a[ai]; 172 173 if (Global.fuzzy.eq(v, 0)) { 174 return InvariantStatus.FALSIFIED; 175 } 176 } 177 return InvariantStatus.NO_CHANGE; 178 } 179 180 @Override 181 public InvariantStatus add_modified(double @Interned [] a, int count) { 182 183 // if (logOn()) { 184 // ValueSet.ValueSetFloatArray vs = (ValueSet.ValueSetFloatArray) ppt.var_infos[0].get_value_set(); 185 // log ("max=" + vs.max() + " array=" + Arrays.toString (a)); 186 // } 187 188 return check_modified(a, count); 189 } 190 191 @Override 192 protected double computeConfidence() { 193 // Maybe just use 0 as the min or max instead, and see what happens: 194 // see whether the "nonzero" invariant holds anyway. (Perhaps only 195 // makes sense to do if the {Lower,Upper}Bound invariant doesn't imply 196 // the non-zeroness.) In that case, do still check for no values yet 197 // received. 198 ValueSet.ValueSetFloatArray vs = (ValueSet.ValueSetFloatArray) ppt.var_infos[0].get_value_set(); 199 // log ("is_pointer()=" + is_pointer() + " vs.min=" + vs.min() 200 // + " vs.max=" + vs.max()); 201 if (!is_pointer() && ((vs.min() > 0) || (vs.max() < 0))) { 202 return Invariant.CONFIDENCE_UNJUSTIFIED; 203 } else { 204 double probability_one_elt_nonzero = 1 - confidence_one_elt_nonzero(); 205 double result = 1 - Math.pow(probability_one_elt_nonzero, ppt.num_samples()); 206 // if ((result < 0) || (result > 1)) 207 // System.err.println ("bad result: vs.max=" + vs.max() + " vs.min=" 208 // + vs.min() + " conf=" 209 // + confidence_one_elt_nonzero() + " range=" 210 // + (vs.max() - vs.min() + 1)/ 1); 211 return result; 212 } 213 } 214 215 @SuppressWarnings("UnnecessaryParentheses") // generated code, parentheses are sometimes needed 216 private double confidence_one_elt_nonzero() { 217 double range; 218 if (is_pointer()) { 219 range = 3; 220 } else { 221 int modulus = 1; 222 223 // I need to come back and make this work. 224 // { 225 // for (Invariant inv : ppt.invs) { 226 // if ((inv instanceof Modulus) && inv.enoughSamples()) { 227 // modulus = ((Modulus) inv).modulus; 228 // break; 229 // } 230 // } 231 // } 232 233 // Perhaps I ought to check that it's possible (given the modulus 234 // constraints) for the value to be zero; otherwise, the modulus 235 // constraint implies non-zero. 236 ValueSet.ValueSetFloatArray vs = (ValueSet.ValueSetFloatArray) ppt.var_infos[0].get_value_set(); 237 range = (vs.max() - vs.min() + 1) / (modulus); 238 } 239 return 1.0/range; 240 } 241 242 @Pure 243 @Override 244 public boolean isSameFormula(Invariant other) { 245 assert other instanceof EltNonZeroFloat; 246 return true; 247 } 248 249 @Pure 250 @Override 251 public boolean isExclusiveFormula(Invariant other) { 252 if (other instanceof EltOneOfFloat) { 253 EltOneOfFloat eoo = (EltOneOfFloat) other; 254 if ((eoo.num_elts() == 1) && (((Double)eoo.elt()).doubleValue() == 0)) { 255 return true; 256 } 257 } 258 return false; 259 } 260 261 @Pure 262 @Override 263 public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) { 264 // This test doesn't seem right: the invariant is obvious if the 265 // elements don't have null, not if the collection doesn't have null. 266 if (!vis[0].aux.hasNull()) { 267 // If it's not a number and null doesn't have special meaning... 268 return new DiscardInfo(this, DiscardCode.obvious, "'null' has no special meaning for " + vis[0].name()); 269 } 270 return super.isObviousStatically(vis); 271 } 272 273 @Pure 274 @Override 275 public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) { 276 DiscardInfo super_result = super.isObviousDynamically(vis); 277 if (super_result != null) { 278 return super_result; 279 } 280 281 VarInfo v1 = vis[0]; 282 283 // (a[] == []) ==> a[] != 0 284 if (ppt.parent.is_empty(v1)) { 285 return new DiscardInfo(this, DiscardCode.obvious, v1 + "is empty"); 286 } 287 288 // (a[] > 0) v (a[] < 0) ==> a[] != 0 289 EltLowerBoundFloat lb = (EltLowerBoundFloat) ppt.parent.find_inv_by_class 290 (vis, EltLowerBoundFloat.class); 291 if ((lb != null) && (lb.min() > 0)) { 292 return new DiscardInfo(this, DiscardCode.obvious, v1 + " > " + lb.min()); 293 } 294 EltUpperBoundFloat ub = (EltUpperBoundFloat) ppt.parent.find_inv_by_class 295 (vis, EltUpperBoundFloat.class); 296 if ((ub != null) && (ub.max() < 0)) { 297 return new DiscardInfo(this, DiscardCode.obvious, v1 + " < " + ub.max()); 298 } 299 300 // For every other EltNonZero at this program point, see if there is a 301 // subsequence relationship between that array and this one. 302 303 if (debug.isLoggable(Level.FINE)) { 304 debug.fine("Testing isObviousDynamically for " + vis[0].name()); 305 } 306 307 PptTopLevel parent = ppt.parent; 308 for (Iterator<Invariant> itor = parent.invariants_iterator(); itor.hasNext(); ) { 309 Invariant inv = itor.next(); 310 if ((inv instanceof EltNonZeroFloat) && (inv != this) && inv.enoughSamples()) { 311 VarInfo v2 = inv.ppt.var_infos[0]; 312 if (debug.isLoggable(Level.FINE)) { 313 debug.fine(" Have to test: " + inv.repr()); 314 } 315 316 if (Debug.logOn()) { 317 Daikon.current_inv = this; 318 } 319 if (parent.is_subsequence(v1, v2)) { 320 return new DiscardInfo(this, DiscardCode.obvious, v1.name() 321 + " is a subsequence of " + v2.name()); 322 } 323 } 324 } 325 326 return null; 327 } 328 329 // Look up a previously instantiated invariant. 330 public static @Nullable EltNonZeroFloat find(PptSlice ppt) { 331 assert ppt.arity() == 1; 332 for (Invariant inv : ppt.invs) { 333 if (inv instanceof EltNonZeroFloat) { 334 return (EltNonZeroFloat) inv; 335 } 336 } 337 return null; 338 } 339 340 /** NI suppressions, initialized in get_ni_suppressions() */ 341 private static @Nullable NISuppressionSet suppressions = null; 342 343 /** returns the ni-suppressions for EltNonZeroFloat */ 344 @Pure 345 @Override 346 public NISuppressionSet get_ni_suppressions() { 347 if (suppressions == null) { 348 NISuppressee suppressee = new NISuppressee(EltNonZeroFloat.class, 1); 349 350 // suppressor definitions (used in suppressions below) 351 NISuppressor v_eq_one = new NISuppressor(0, EltRangeFloat.EqualOne.class); 352 NISuppressor v_eq_minus_one = new NISuppressor(0, EltRangeFloat.EqualMinusOne.class); 353 354 suppressions = new NISuppressionSet( 355 new NISuppression[] { 356 // v == 1 ==> v != 0 357 new NISuppression(v_eq_one, suppressee), 358 // v == -1 ==> v != 0 359 new NISuppression(v_eq_minus_one, suppressee), 360 }); 361 } 362 363 return suppressions; 364 } 365}