001package daikon.inv; 002 003import daikon.inv.filter.DerivedParameterFilter; 004import daikon.inv.filter.InvariantFilter; 005import daikon.inv.filter.ObviousFilter; 006import daikon.inv.filter.OnlyConstantVariablesFilter; 007import daikon.inv.filter.SimplifyFilter; 008import daikon.inv.filter.UnjustifiedFilter; 009import daikon.inv.filter.UnmodifiedVariableEqualityFilter; 010import daikon.inv.filter.VariableFilter; 011import java.io.ObjectStreamException; 012import java.io.Serializable; 013import org.checkerframework.checker.lock.qual.GuardSatisfied; 014import org.checkerframework.dataflow.qual.Pure; 015import org.checkerframework.dataflow.qual.SideEffectFree; 016 017/** 018 * DiscardCode is an enumeration type. It represents reasons why an invariant is falsified or 019 * disregarded. Methods that decide whether an Invariant should be printed later (such as 020 * isObviousImplied()), side effect Invariants to contain DiscardCode instances in their discardCode 021 * field slot. 022 * 023 * <p>The different elements of the enumeration are: 024 * 025 * <p>obvious // is implied by other already known invariants 026 * 027 * <p>bad_sample // is falsified by a seen example 028 * 029 * <p>bad_confidence // has an unjustified confidence 030 * 031 * <p>(unused) // was few_modified_samples 032 * 033 * <p>not_enough_samples // not enough samples seen for the Invariant 034 * 035 * <p>non_canonical_var // expression involves a non-canonical variable 036 * 037 * <p>implied_post_condition // implied by some prestate conditions 038 * 039 * <p>only_constant_vars // expression for invariant only contains constant variables 040 * 041 * <p>derived_param // has a VarInfo that has derived and uninteresting param 042 * 043 * <p>unmodified_var // invariant discarded because it says some var hasn't been modified 044 * 045 * <p>control_check // if discarded due to the ControlledInvariantFilter 046 * 047 * <p>exact // isExact() fails 048 * 049 * <p>var_filtered // Doesn't contain a desirable variable 050 * 051 * <p>filtered // filtered by some other means not in the above list 052 * 053 * <p>There is no representation for an invariant that is *not* discarded; don't use a DiscardCode 054 * in that situation. 055 */ 056public class DiscardCode implements Comparable<DiscardCode>, Serializable { 057 058 static final long serialVersionUID = 20031016L; 059 060 /** used when an invariant is implied by other known invariants. */ 061 public static final DiscardCode obvious = new DiscardCode(0); 062 063 /** used when an invariant is falsified by a seen example. */ 064 public static final DiscardCode bad_sample = new DiscardCode(1); 065 066 /** used when an invariant has an unjustified confidence. */ 067 public static final DiscardCode bad_confidence = new DiscardCode(2); 068 069 /** used when an invariant has not had enough samples. */ 070 public static final DiscardCode not_enough_samples = new DiscardCode(4); 071 072 /** used when an invariant contains a non-canonical variable. */ 073 public static final DiscardCode non_canonical_var = new DiscardCode(5); 074 075 /** used when an invariant is implied by some prestate conditions. */ 076 public static final DiscardCode implied_post_condition = new DiscardCode(6); 077 078 /** used when an invariant's expression contains only constant variables. */ 079 public static final DiscardCode only_constant_vars = new DiscardCode(7); 080 081 /** used when an invariant's VarInfo returns true for isDerivedParamAndUninteresting() */ 082 public static final DiscardCode derived_param = new DiscardCode(8); 083 084 /** used for invariants that describe unmodified variables. */ 085 public static final DiscardCode unmodified_var = new DiscardCode(9); 086 087 /** used for invariants discarded because of the ControlledInvariantsFilter. */ 088 public static final DiscardCode control_check = new DiscardCode(10); 089 090 /** used for invariants discarded when isExact() fails. */ 091 public static final DiscardCode exact = new DiscardCode(11); 092 093 /** used for invariants that don't contain desired variables. */ 094 public static final DiscardCode var_filtered = new DiscardCode(12); 095 096 /** used for invariants that are filtered by some means not in the above list. */ 097 public static final DiscardCode filtered = new DiscardCode(13); 098 099 /** Each member of the enumeration is associated with a distinct int for comparability. */ 100 public final int enumValue; 101 102 // Prevents the user from using DiscardCode types not in the enumeration 103 // by making the default constructor private. This constructor should never be 104 // used to make new elements of the enumeration. 105 private DiscardCode() { 106 this.enumValue = -1; 107 } 108 109 // Makes it easier to add a new DiscardCode type by simply constructing it as a field with the 110 // next non-used integer value. 111 private DiscardCode(int enumValue) { 112 this.enumValue = enumValue; 113 } 114 115 /** 116 * The enumeration members in sorted order: <br> 117 * obvious, bad_sample, bad_confidence, [unused], not_enough_samples, non_canonical_var,<br> 118 * implied_post_condition, only_constant_vars, derived_param, unmodified_var, control_check, 119 * exact, var filter 120 * 121 * @return this.enumValue.compareTo(o.enumValue) where the enumValue are treated as Integers 122 * @throws ClassCastException iff !(o instanceof DiscardCode) 123 */ 124 @Pure 125 @Override 126 public int compareTo(@GuardSatisfied DiscardCode this, DiscardCode o) { 127 if (this.enumValue < o.enumValue) { 128 return -1; 129 } else if (this.enumValue == o.enumValue) { 130 return 0; 131 } else { 132 return 1; 133 } 134 } 135 136 /** Returns the DiscardCode most associated with the given filter. */ 137 public static DiscardCode findCode(InvariantFilter filter) { 138 if ((filter instanceof ObviousFilter) || (filter instanceof SimplifyFilter)) { 139 return obvious; 140 } else if (filter instanceof DerivedParameterFilter) { 141 return derived_param; 142 } else if (filter instanceof OnlyConstantVariablesFilter) { 143 return only_constant_vars; 144 } else if (filter instanceof UnjustifiedFilter) { 145 return bad_confidence; 146 } else if (filter instanceof UnmodifiedVariableEqualityFilter) { 147 return unmodified_var; 148 } else if (filter instanceof VariableFilter) { 149 return var_filtered; 150 } else { 151 return filtered; 152 } 153 } 154 155 /** 156 * Prints out a string describing the reason for discard. 157 * 158 * @return one of {"Not discarded", "Obvious, "Bad sample seen", "Unjustified confidence", "Few 159 * modified samples", "Not enough samples", "Non-canonical variable", "Implied post state", 160 * "Only constant variables in this expression", "Derived Param", "Control Check", "Exact", 161 * "Variable Filter", "Filtered"} 162 */ 163 @SideEffectFree 164 @Override 165 public String toString(@GuardSatisfied DiscardCode this) { 166 if (this.enumValue == -1) { 167 return "Not discarded"; 168 } else if (this.enumValue == 0) { 169 return "Obvious"; 170 } else if (this.enumValue == 1) { 171 return "Bad sample seen"; 172 } else if (this.enumValue == 2) { 173 return "Unjustified confidence"; 174 } else if (this.enumValue == 3) { 175 return "Few modified samples"; 176 } else if (this.enumValue == 4) { 177 return "Not enough samples"; 178 } else if (this.enumValue == 5) { 179 return "Non-canonical variable"; 180 } else if (this.enumValue == 6) { 181 return "Implied post state"; 182 } else if (this.enumValue == 7) { 183 return "Only constant variables in this expression"; 184 } else if (this.enumValue == 8) { 185 return "Derived Param"; 186 } else if (this.enumValue == 9) { 187 return "Unmodified var"; 188 } else if (this.enumValue == 10) { 189 return "Control Check"; 190 } else if (this.enumValue == 11) { 191 return "Exact"; 192 } else if (this.enumValue == 12) { 193 return "Variable Filter"; 194 } else if (this.enumValue == 13) { 195 return "Filtered"; 196 } else { // this should never happen since the constructor is private 197 return "Unknown instance of DiscardCode used"; 198 } 199 } 200 201 /** 202 * To prevent deserialization causing more DiscardCodes to be instantiated. 203 * 204 * @return one of the static DiscardCode instances 205 */ 206 public Object readResolve() throws ObjectStreamException { 207 if (enumValue == 0) { 208 return obvious; 209 } else if (enumValue == 1) { 210 return bad_sample; 211 } else if (enumValue == 2) { 212 return bad_confidence; 213 } else if (enumValue == 3) throw new Error("few_modified_samples no longer exists"); 214 else if (enumValue == 4) { 215 return not_enough_samples; 216 } else if (enumValue == 5) { 217 return non_canonical_var; 218 } else if (enumValue == 6) { 219 return implied_post_condition; 220 } else if (enumValue == 7) { 221 return only_constant_vars; 222 } else if (enumValue == 8) { 223 return derived_param; 224 } else if (enumValue == 9) { 225 return unmodified_var; 226 } else if (enumValue == 10) { 227 return control_check; 228 } else if (enumValue == 11) { 229 return exact; 230 } else if (enumValue == 12) { 231 return var_filtered; 232 } else if (enumValue == 13) { 233 return filtered; 234 } else { // this should never happen 235 // return null; 236 throw new Error("impossible"); 237 } 238 } 239}