001// ***** This file is automatically generated from SubSet.java.jpp 002 003package daikon.inv.binary.twoSequence; 004 005import daikon.*; 006import daikon.inv.*; 007import daikon.suppress.*; 008import java.util.*; 009import java.util.logging.Level; 010import java.util.logging.Logger; 011import org.checkerframework.checker.lock.qual.GuardSatisfied; 012import org.checkerframework.checker.nullness.qual.NonNull; 013import org.checkerframework.checker.nullness.qual.Nullable; 014import org.checkerframework.dataflow.qual.Pure; 015import org.checkerframework.dataflow.qual.SideEffectFree; 016import org.plumelib.util.ArraysPlume; 017import typequals.prototype.qual.NonPrototype; 018import typequals.prototype.qual.Prototype; 019 020/** 021 * Represents two sequences of long values where one of the sequences is a subset of the other; that 022 * is each element of one sequence appears in the other. Prints as either 023 * {@code x[] is a subset of y[]} or as {@code x[] is a superset of y[]}. 024 */ 025public class SuperSet extends TwoSequence { 026 static final long serialVersionUID = 20031024L; 027 028 private static final Logger debug = 029 Logger.getLogger("daikon.inv.binary.twoSequence.SuperSet"); 030 031 // Variables starting with dkconfig_ should only be set via the 032 // daikon.config.Configuration interface. 033 /** Boolean. True iff SubSet invariants should be considered. */ 034 public static boolean dkconfig_enabled = false; 035 036 protected SuperSet(PptSlice ppt) { 037 super(ppt); 038 } 039 040 protected @Prototype SuperSet() { 041 super(); 042 } 043 044 private static @Prototype SuperSet proto = new @Prototype SuperSet(); 045 046 /** Returns the prototype invariant for SuperSet */ 047 public static @Prototype SuperSet get_proto() { 048 return proto; 049 } 050 051 @Override 052 public boolean enabled() { 053 return dkconfig_enabled; 054 } 055 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 public SuperSet instantiate_dyn(@Prototype SuperSet this, PptSlice slice) { 068 return new SuperSet(slice); 069 } 070 071 @Override 072 protected Invariant resurrect_done_swapped() { 073 return new SubSet(ppt); 074 } 075 076 @Override 077 public String repr(@GuardSatisfied SuperSet this) { 078 return "SuperSet" + varNames() + ": ,falsified=" + falsified; 079 } 080 081 @SideEffectFree 082 @Override 083 public String format_using(@GuardSatisfied SuperSet this, OutputFormat format) { 084 if (format == OutputFormat.DAIKON) { 085 return format(); 086 } 087 if (format == OutputFormat.ESCJAVA) { 088 return format_esc(); 089 } 090 if (format == OutputFormat.SIMPLIFY) { 091 return format_simplify(); 092 } 093 if (format == OutputFormat.CSHARPCONTRACT) { 094 return format_csharp_contract(); 095 } 096 if (format.isJavaFamily()) { 097 return format_java_family(format); 098 } 099 100 return format_unimplemented(format); 101 } 102 103 @SideEffectFree 104 @Override 105 public String format(@GuardSatisfied SuperSet this) { 106 String v1 = var1().name(); 107 String v2 = var2().name(); 108 109 return v1 + " is a superset of " + v2; 110 } 111 112 public String format_csharp_contract(@GuardSatisfied SuperSet this) { 113 String v1 = var1().csharp_collection_string(); 114 String v2 = var2().csharp_collection_string(); 115 116 return "Contract.ForAll(" + v2 + ", i => " + v1 + ".Contains(i))"; 117 } 118 119 public String format_esc(@GuardSatisfied SuperSet this) { 120 String classname = this.getClass().toString().substring(6); // remove leading "class" 121 return "warning: method " + classname + ".format_esc() needs to be implemented: " + format(); 122 } 123 124 public String format_simplify(@GuardSatisfied SuperSet this) { 125 if (Invariant.dkconfig_simplify_define_predicates) { 126 return format_simplify_defined(); 127 } else { 128 return format_simplify_explicit(); 129 } 130 } 131 132 private String format_simplify_defined(@GuardSatisfied SuperSet this) { 133 134 VarInfo subvar = var2(); 135 VarInfo supervar = var1(); 136 137 String[] sub_name = subvar.simplifyNameAndBounds(); 138 String[] super_name = supervar.simplifyNameAndBounds(); 139 140 if (sub_name == null || super_name == null) { 141 return String.format("%s.format_simplify_defined(%s): sub_name=%s, super_name=%s, for %s", 142 getClass().getSimpleName(), this, 143 Arrays.toString(sub_name), Arrays.toString(super_name), format()); 144 } 145 146 return "(subset " 147 + sub_name[0] + " " + sub_name[1] + " " + sub_name[2] + " " 148 + super_name[0] + " " + super_name[1] + " " + super_name[2] + ")"; 149 } 150 151 private String format_simplify_explicit(@GuardSatisfied SuperSet this) { 152 153 VarInfo subvar = var2(); 154 VarInfo supervar = var1(); 155 156 String[] sub_name = subvar.simplifyNameAndBounds(); 157 String[] super_name = supervar.simplifyNameAndBounds(); 158 159 if (sub_name == null || super_name == null) { 160 return String.format("%s.format_simplify_explicit(%s): sub_name=%s, super_name=%s, for %s", 161 getClass().getSimpleName(), this, 162 Arrays.toString(sub_name), Arrays.toString(super_name), format()); 163 } 164 165 String indices[] = VarInfo.get_simplify_free_indices(subvar, supervar); 166 167 // (FORALL (a i j b ip jp) 168 // (IFF (subset a i j b ip jp) 169 // (FORALL (x) 170 // (IMPLIES 171 // (AND (<= i x) (<= x j)) 172 // (EXISTS (y) 173 // (AND (<= ip y) (<= y jp) 174 // (EQ (select (select elems a) x) 175 // (select (select elems b) y)))))))) 176 177 return "(FORALL (" + indices[0] + ") (IMPLIES (AND (<= " + sub_name[1] 178 + " " + indices[0] + ") (<= " + indices[0] + " " + sub_name[2] + "))" 179 + "(EXISTS (" + indices[1] + ")(AND (<= " + super_name[1] + " " 180 + indices[1] + ") (<= " + indices[1] + " " + super_name[2]+ ")" 181 + "(EQ (select (select elems " + sub_name[0] + ") " + indices[0] + ") " 182 + "(select (select elems " + super_name[0] +") " + indices[1] + "))))))"; 183 184 } 185 186 public String format_java_family(@GuardSatisfied SuperSet this, OutputFormat format) { 187 188 String v1 = var1().name_using(format); 189 String v2 = var2().name_using(format); 190 191 return "daikon.Quant.subsetOf(" + v2 + ", " + v1 + ")"; 192 } 193 194 @Override 195 public InvariantStatus check_modified(long[] a1, long[] a2, int count) { 196 197 if (!ArraysPlume.isSubset(a2, a1)) { 198 199 return InvariantStatus.FALSIFIED; 200 } else { 201 return InvariantStatus.NO_CHANGE; 202 } 203 204 } 205 206 @Override 207 public InvariantStatus add_modified(long[] a1, long[] a2, int count) { 208 if (debug.isLoggable(Level.FINE)) { 209 debug.fine(Arrays.toString(a1)); 210 debug.fine(Arrays.toString(a2)); 211 } 212 return check_modified(a1, a2, count); 213 } 214 215 @Override 216 protected double computeConfidence() { 217 if (ppt.num_samples() == 0) { 218 return Invariant.CONFIDENCE_UNJUSTIFIED; 219 } 220 return Invariant.CONFIDENCE_JUSTIFIED; 221 } 222 223 // Convenience name to make this easier to find. 224 @Pure 225 public static @Nullable DiscardInfo isObviousSubSet(Invariant inv, VarInfo subvar, VarInfo supervar) { 226 return SubSequence.isObviousSubSequence(inv, subvar, supervar); 227 } 228 229 @Pure 230 @Override 231 public @Nullable DiscardInfo isObviousStatically(VarInfo[] vis) { 232 VarInfo var1 = vis[0]; 233 VarInfo var2 = vis[1]; 234 235 DiscardInfo di; 236 di = SuperSet.isObviousSubSet(this, var1, var2); 237 if (di == null) { 238 di = SuperSet.isObviousSubSet(this, var2, var1); 239 } 240 if (di != null) { 241 return di; 242 } 243 244 VarInfo subvar; 245 VarInfo supervar; 246 247 subvar = var2; 248 supervar = var2; 249 250 // Uninteresting if this is of the form x[0..i] subsequence 251 // x[0..j]. Not necessarily obvious. 252 VarInfo subvar_super = subvar.isDerivedSubSequenceOf(); 253 if (subvar_super == supervar) { 254 debug.fine(" returning true because subvar_super == supervar"); 255 return new DiscardInfo(this, DiscardCode.obvious, "x[0..i] subsequence of x[0..j] is uninteresting"); 256 } 257 258 VarInfo supervar_super = supervar.isDerivedSubSequenceOf(); 259 if (subvar_super != null && subvar_super == supervar_super) { 260 debug.fine(" returning true because subvar_super == supervar_super"); 261 return new DiscardInfo(this, DiscardCode.obvious, "x[0..i] subsequence of x[0..j] is uninteresting"); 262 } 263 264 di = SubSequence.isObviousSubSequence(this, var1, var2); 265 if (di == null) { 266 di = SubSequence.isObviousSubSequence(this, var2, var1); 267 } 268 if (di != null) { 269 return di; 270 } 271 return super.isObviousStatically(vis); 272 } 273 274 // Look up a previously instantiated SubSet relationship. 275 public static @Nullable SuperSet find(PptSlice ppt) { 276 assert ppt.arity() == 2; 277 for (Invariant inv : ppt.invs) { 278 if (inv instanceof SuperSet) { 279 return (SuperSet) inv; 280 } 281 } 282 return null; 283 } 284 285 @Pure 286 @Override 287 public boolean isSameFormula(Invariant other) { 288 assert other instanceof SuperSet; 289 return true; 290 } 291 292 /** NI suppressions, initialized in get_ni_suppressions() */ 293 private static @Nullable NISuppressionSet suppressions = null; 294 295 /** returns the ni-suppressions for SuperSet */ 296 @Pure 297 @Override 298 public NISuppressionSet get_ni_suppressions() { 299 if (suppressions == null) { 300 NISuppressee suppressee = new NISuppressee(SuperSet.class, 2); 301 302 // suppressor definitions (used in suppressions below) 303 NISuppressor v1_eq_v2 = new NISuppressor(0, 1, SeqSeqIntEqual.class); 304 NISuppressor v1_pw_eq_v2 = new NISuppressor(0, 1, PairwiseIntEqual.class); 305 306 // sub/super set suppressions. We have both SeqSeq and Pairwise 307 // as suppressions because each can be enabled separately. 308 suppressions = new NISuppressionSet( 309 new NISuppression[] { 310 // a[] == b[] ==> a[] sub/superset b[] 311 new NISuppression(v1_eq_v2, suppressee), 312 // a[] == b[] ==> a[] sub/superset b[] 313 new NISuppression(v1_pw_eq_v2, suppressee), 314 }); 315 } 316 317 return suppressions; 318 } 319}