001// ***** This file is automatically generated from NonZero.java.jpp 002 003package daikon.inv.unary.scalar; 004 005import daikon.*; 006import daikon.derive.unary.*; 007import daikon.inv.*; 008import daikon.inv.binary.sequenceScalar.*; 009import daikon.inv.unary.sequence.*; 010import java.util.*; 011import java.util.logging.Level; 012import java.util.logging.Logger; 013import org.checkerframework.checker.lock.qual.GuardSatisfied; 014import org.checkerframework.checker.nullness.qual.Nullable; 015import org.checkerframework.dataflow.qual.Pure; 016import org.checkerframework.dataflow.qual.SideEffectFree; 017import org.plumelib.util.Intern; 018import typequals.prototype.qual.NonPrototype; 019import typequals.prototype.qual.Prototype; 020 021/** Represents double scalars that are non-zero. Prints as {@code x != 0}. */ 022 023public class NonZeroFloat extends SingleFloat { 024 static final long serialVersionUID = 20030822L; 025 026 // Variables starting with dkconfig_ should only be set via the 027 // daikon.config.Configuration interface. 028 /** Boolean. True iff NonZeroFloat invariants should be considered. */ 029 public static boolean dkconfig_enabled = Invariant.invariantEnabledDefault; 030 031 /** Debug tracer. */ 032 public static final Logger debug = Logger.getLogger("daikon.inv.unary.scalar.NonZeroFloat"); 033 034 /** Maximum value ever used for max-min in confidence calculation. */ 035 private static final long range_max = 50; 036 037 private NonZeroFloat(PptSlice ppt) { 038 super(ppt); 039 } 040 041 private @Prototype NonZeroFloat() { 042 super(); 043 } 044 045 private static @Prototype NonZeroFloat proto = new @Prototype NonZeroFloat(); 046 047 /** Returns the prototype invariant for NonZeroFloat */ 048 public static @Prototype NonZeroFloat get_proto() { 049 return proto; 050 } 051 052 @Override 053 public boolean enabled() { 054 return dkconfig_enabled; 055 } 056 057 @Override 058 public boolean instantiate_ok(VarInfo[] vis) { 059 060 if (!valid_types(vis)) { 061 return false; 062 } 063 064 if (vis[0].aux.isStruct() 065 || vis[0].aux.isNonNull() 066 || !vis[0].aux.hasNull()) 067 return false; 068 069 return true; 070 } 071 072 @Override 073 public NonZeroFloat instantiate_dyn(@Prototype NonZeroFloat this, PptSlice slice) { 074 return new NonZeroFloat(slice); 075 } 076 077 private String zero(@GuardSatisfied @Prototype NonZeroFloat this, @SuppressWarnings("UnusedVariable") OutputFormat format) { 078 079 return "0"; 080 } 081 082 @SideEffectFree 083 @Override 084 public String format_using(@GuardSatisfied @Prototype NonZeroFloat this, OutputFormat format) { 085 // // var() fails for prototype invariants 086 // if (ppt == null) { 087 // return "Prototype NonZeroFloat invariant (ppt == null)"; 088 // } 089 090 String name = var().name_using(format); 091 092 if (format.isJavaFamily()) { 093 094 return "daikon.Quant.fuzzy.ne(" + name + ", " + zero(format) + ")"; 095 } 096 097 if ((format == OutputFormat.DAIKON) 098 || (format == OutputFormat.ESCJAVA) 099 || (format == OutputFormat.CSHARPCONTRACT)) { 100 return name + " != " + zero(format); 101 } 102 103 if (format == OutputFormat.SIMPLIFY) { 104 return "(NEQ " + var().simplifyFixup(name) + " " + zero(format) + ")"; 105 } 106 107 return format_unimplemented(format); 108 } 109 110 @Override 111 public InvariantStatus check_modified(double v, int count) { 112 if (v == 0) { 113 return InvariantStatus.FALSIFIED; 114 } else { 115 return InvariantStatus.NO_CHANGE; 116 } 117 } 118 119 @Override 120 public InvariantStatus add_modified(double v, int count) { 121 InvariantStatus status = check_modified(v, count); 122 if (status == InvariantStatus.FALSIFIED) { 123 if (logOn()) { 124 log(debug, "falsified (value = " + v + ")"); 125 } 126 } // else if (logDetail()) 127 // log ("add_modified (" + v + ")"); 128 return status; 129 } 130 131 /** Returns whether or not the variable is a pointer. */ 132 @Pure 133 private boolean is_pointer(@GuardSatisfied NonZeroFloat this) { 134 return ppt.var_infos[0].file_rep_type == ProglangType.HASHCODE; 135 } 136 137 @Override 138 protected double computeConfidence() { 139 return 1 - computeProbability(); 140 } 141 142 // used by computeConfidence 143 protected double computeProbability() { 144 assert ! falsified; 145 // This method works by looking at all sample values and 146 // calculating the probability that they were all non-zero by 147 // chance (assuming a uniform distribution). If the variable is 148 // not a pointer, the range used is the observed range from sample 149 // data. Further observed constraints are used to change the 150 // returned probability, such as all samples being congruent some 151 // modulus. 152 153 ValueSet.ValueSetFloat vs = (ValueSet.ValueSetFloat) ppt.var_infos[0].get_value_set(); 154 155 // If greater than or less than 0, the bounds invariant will be more 156 // interesting 157 if (!is_pointer() && ((vs.min() > 0) || (vs.max() < 0))) { 158 159 // Maybe just use 0 as the min or max instead, and see what happens: 160 // see whether the "nonzero" invariant holds anyway. (Perhaps only 161 // makes sense to do if the {Lower,Upper}Bound invariant doesn't imply 162 // the non-zeroness.) In that case, do still check for no values yet 163 // received. 164 return Invariant.PROBABILITY_UNJUSTIFIED; 165 } else { 166 double range; 167 if (is_pointer()) { 168 range = 3; 169 } else { 170 long modulus = 1; 171 { 172 Modulus mi = Modulus.find(ppt); 173 if (mi != null) { 174 modulus = mi.modulus; 175 } 176 } 177 // Perhaps I ought to check that it's possible (given the modulus 178 // constraints) for the value to be zero; otherwise, the modulus 179 // constraint implies non-zero. 180 range = (vs.max() - vs.min() + 1) / modulus; 181 } 182 if ((range_max != 0) && (range > range_max)) { 183 range = range_max; 184 } 185 186 double probability_one_elt_nonzero = 1 - 1.0/range; 187 // This could underflow; so consider doing 188 // double log_probability = self.samples*math.log(probability); 189 // then calling Math.exp (if the value is in the range that wouldn't 190 // cause underflow). 191 // return Math.pow(probability_one_elt_nonzero, ppt.num_mod_samples()); 192 return Math.pow(probability_one_elt_nonzero, ppt.num_samples()); 193 } 194 } 195 196 @Pure 197 @Override 198 public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) { 199 VarInfo var = vis[0]; 200 201 if (var.aux.isStruct()) { 202 return new DiscardInfo(this, DiscardCode.obvious, 203 var.name() + " is a struct"); 204 } 205 206 if (var.aux.isNonNull()) { 207 return new DiscardInfo(this, DiscardCode.obvious, 208 "aux information says " + var.name() + " is non-null"); 209 } 210 211 if (!var.aux.hasNull()) { 212 return new DiscardInfo(this, DiscardCode.obvious, 213 "'null' has no special meaning for " + var.name()); 214 } 215 216 return super.isObviousStatically(vis); 217 } 218 219 @Pure 220 @Override 221 public @Nullable DiscardInfo isObviousDynamically(VarInfo[] vis) { 222 DiscardInfo super_result = super.isObviousDynamically(vis); 223 if (super_result != null) { 224 return super_result; 225 } 226 227 VarInfo var = vis[0]; 228 229 Debug dlog = new Debug(getClass(), ppt, vis); 230 231 if (logOn()) { 232 dlog.log("Checking IsObviousDynamically"); 233 } 234 235 // System.out.println("isObviousImplied: " + format()); 236 237 // For every EltNonZeroFloat at this program point, see if this variable is 238 // an obvious member of that sequence. 239 PptTopLevel parent = ppt.parent; 240 for (Iterator<Invariant> itor = parent.invariants_iterator(); itor.hasNext(); ) { 241 Invariant inv = itor.next(); 242 if ((inv instanceof EltNonZeroFloat) && inv.enoughSamples()) { 243 VarInfo v2 = inv.ppt.var_infos[0]; 244 // System.out.println("NonZeroFloat.isObviousImplied: calling " + MemberFloat + ".isObviousMember(" + var.name + ", " + v2.name + ")"); 245 // Don't use isEqualToObviousMember: that is too subtle 246 // and eliminates desirable invariants such as "return != null". 247 if (MemberFloat.isObviousMember(var, v2)) { 248 // System.out.println("NonZeroFloat.isObviousImplied: " + MemberFloat + ".isObviousMember(" + var.name + ", " + v2.name + ") = true"); 249 if (logOn()) { 250 dlog.log("isObvDyn- true, arg is member of nonzero sequence"); 251 } 252 String discardString = var.name() + " is a member of the non-zero sequence " + v2.name(); 253 if (logOn()) { 254 log("%s obviously implied from %s", format(), inv.format()); 255 } 256 return new DiscardInfo(this, DiscardCode.obvious, discardString); 257 } 258 } 259 } 260 261 if ((var.derived != null) 262 && (var.derived instanceof SequenceInitialFloat)) { 263 SequenceInitialFloat si = (SequenceInitialFloat) var.derived; 264 if (si.index == 0) { 265 266 // For each sequence variable, if var is an obvious member, and 267 // the sequence has the same invariant, then this one is obvious. 268 PptTopLevel pptt = ppt.parent; 269 for (int i = 0; i < pptt.var_infos.length; i++) { 270 VarInfo vi = pptt.var_infos[i]; 271 if (MemberFloat.isObviousMember(var, vi)) { 272 PptSlice1 other_slice = pptt.findSlice(vi); 273 if (other_slice != null) { 274 SeqIndexFloatNonEqual sine = SeqIndexFloatNonEqual.find(other_slice); 275 if ((sine != null) && sine.enoughSamples()) { 276 // System.out.println("NonZeroFloat.isObviousImplied true due to: " + sine.format()); 277 if (logOn()) { 278 dlog.log("isObvDyn- true due to " + sine.format()); 279 } 280 String discardString = var.name() + " is a member of the non-zero sequence " + vi.name(); 281 return new DiscardInfo(this, DiscardCode.obvious, discardString); 282 } 283 } 284 } 285 } 286 } 287 } 288 289 return null; 290 } 291 292 @Pure 293 @Override 294 public boolean isSameFormula(Invariant other) { 295 assert other instanceof NonZeroFloat; 296 return true; 297 } 298 299 @Pure 300 @Override 301 public boolean isExclusiveFormula(Invariant other) { 302 if (other instanceof OneOfScalar) { 303 OneOfScalar oos = (OneOfScalar) other; 304 if ((oos.num_elts() == 1) && (((Long)oos.elt()).doubleValue() == 0)) { 305 return true; 306 } 307 } 308 return false; 309 } 310}