public DiscardInfo isObviousStatically(VarInfo[] vis) {
    VarInfo var1 = vis[0];
    VarInfo var2 = vis[1];

    Object[] obv1 = SubSequence.isObviousSubSequence(var1, var2);
    Object[] obv2 = SubSequence.isObviousSubSequence(var2, var1);
    if (obv1[1] != null) {
      Global.implied_noninstantiated_invariants++;
      return new DiscardInfo(this, (DiscardCode) obv1[0], (String) obv1[1]);
    } else if (obv2[1] != null) {
      Global.implied_noninstantiated_invariants++;
      return new DiscardInfo(this, (DiscardCode) obv1[0], (String) obv1[1]);
    }

    // Don't instantiate if the variables can't have order
    if (!var1.aux.getFlag(VarInfoAux.HAS_ORDER) || !var2.aux.getFlag(VarInfoAux.HAS_ORDER)) {
      if (debug.isLoggable(Level.FINE)) {
        debug.fine(
            "Not instantitating for because order has no meaning: "
                + var1.name()
                + " and "
                + var2.name());
      }
      return new DiscardInfo(
          this, DiscardCode.obvious, "Obvious statically since order has no meaning");
    }

    return super.isObviousStatically(vis);
  }
 protected boolean isParam() {
   return (base1.isParam() || base2.isParam() || base3.isParam());
   // VIN
   // return (base1.aux.getFlag(VarInfoAux.IS_PARAM)
   //         || base2.aux.getFlag(VarInfoAux.IS_PARAM)
   //         || base3.aux.getFlag(VarInfoAux.IS_PARAM));
 }
Exemplo n.º 3
0
  public DiscardInfo isObviousStatically(VarInfo[] vis) {

    VarInfo subvar = var1(vis);
    VarInfo supervar = var2(vis);

    // check for x[i..j] subsequence of x[]
    VarInfo subvar_super = subvar.isDerivedSubSequenceOf();
    if (subvar_super == supervar) {
      debug.fine("  returning true because subvar_super == supervar");
      return new DiscardInfo(this, DiscardCode.obvious, "x[i..j] subsequence of x[] is obvious");
    }

    Object[] obv1 = SubSequence.isObviousSubSequence(subvar, supervar);
    if (obv1[1] != null) {
      return new DiscardInfo(this, (DiscardCode) obv1[0], (String) obv1[1]);
    }

    // JHP: This is not a valid obvious check, since it  doesn't imply that
    // the invariant is true.
    if (!subvar.aux.getFlag(VarInfoAux.HAS_ORDER) || !supervar.aux.getFlag(VarInfoAux.HAS_ORDER)) {
      // Doesn't make sense to consider subsequence if order doens't matter
      return new DiscardInfo(
          this, DiscardCode.obvious, "Order doesn't matter, so subsequence is meaningless");
    }

    return super.isObviousStatically(vis);
  }
  public UnaryDerivation /*@Nullable*/[] instantiate(VarInfo vi) {
    if (!SequenceLength.dkconfig_enabled) {
      return null;
    }

    if (!vi.is_direct_array()) return null;

    if (!vi.aux.getFlag(VarInfoAux.HAS_SIZE)) {
      // Don't derive if auxiliary info says size of this collection
      // has no meaning
      return null;
    }

    if (!SequenceLength.applicable(vi)) {
      Global.tautological_suppressed_derived_variables++;
      return null;
    }

    if (debug.isLoggable(Level.FINE)) {
      debug.fine("Instantiating for " + vi.name() + " in " + vi.ppt);
    }

    if (vi.aux.getFlag(VarInfoAux.NULL_TERMINATING)) {
      return new UnaryDerivation[] {new SequenceLength(vi, 0), new SequenceLength(vi, -1)};
    } else {
      // If it can't terminate with nulls, then all members are important,
      // so we only need to do shift for 0
      return new UnaryDerivation[] {new SequenceLength(vi, 0)};
    }
  }
Exemplo n.º 5
0
 private boolean includePosteriorVarsCheckLoops(VarInfo prior) {
   boolean loopDetected = false;
   for (int i = 0, n = pi.blocklist.length; i < n; i++) {
     BasicBlock b = pi.blocklist[i];
     VarInfo v = pi.vars[slot][b.pc1];
     if (v == prior) {
       for (int j = 0, m = b.next != null ? b.next.length : 0; j < m; j++) {
         BasicBlock b1 = b.next[j];
         VarInfo v1 = pi.vars[slot][b1.pc0];
         if (v1 != prior) {
           loopDetected |= includeVarAndPosteriorVars(v1);
           if (v1.isPhiVar()) includePriorVarsIgnoreLoops(v1);
         }
       }
     } else {
       for (int pc = b.pc1 - 1; pc >= b.pc0; pc--) {
         if (pi.vars[slot][pc] == prior) {
           loopDetected |= includeVarAndPosteriorVars(pi.vars[slot][pc + 1]);
           break;
         }
       }
     }
   }
   return loopDetected;
 }
  /**
   * Checks to see if the same invariant exists over supersequences of these variables:
   *
   * <p>(A[] op B[]) ^ (i == j) ==> A[i..] op B[j..] (A[] op B[]) ^ (i == j) ==> A[..i] op B[..j]
   */
  private DiscardInfo superseq_implies(VarInfo[] vis) {

    // Make sure the variables are SequenceScalarSubsequence with the same start/end
    VarInfo v1 = vis[0];
    VarInfo v2 = vis[1];
    if (!v1.isDerived() || !(v1.derived instanceof SequenceScalarSubsequence)) return (null);
    if (!v2.isDerived() || !(v2.derived instanceof SequenceScalarSubsequence)) return (null);
    SequenceScalarSubsequence der1 = (SequenceScalarSubsequence) v1.derived;
    SequenceScalarSubsequence der2 = (SequenceScalarSubsequence) v2.derived;
    if ((der1.from_start != der2.from_start) || (der1.index_shift != der2.index_shift))
      return (null);

    // Make sure the subscripts are equal
    DiscardInfo di = new DiscardInfo(this, DiscardCode.obvious, "");
    if (!ppt.parent.check_implied_canonical(di, der1.sclvar(), der2.sclvar(), IntEqual.get_proto()))
      return (null);

    // See if the super-sequences have the same invariant
    if (!ppt.parent.check_implied_canonical(
        di, der1.seqvar(), der2.seqvar(), PairwiseIntLessThan.get_proto())) return (null);

    // Add in the vis variables to di reason (if they are different)
    di.add_implied_vis(vis);
    return (di);
  }
  /* IOA */
  public String format_ioa() {
    if (var1().isIOASet() || var2().isIOASet()) return "Not valid for sets: " + format();
    Quantify.IOAQuantification quant1 = VarInfo.get_ioa_quantify(var1());
    Quantify.IOAQuantification quant2 = VarInfo.get_ioa_quantify(var2());

    return quant1.getQuantifierExp()
        + quant1.getVarIndexedString(0)
        + " "
        + "< "
        + quant2.getVarIndexedString(0)
        + quant1.getClosingExp();
  }
Exemplo n.º 8
0
 // Upval info representing the implied context containing only the environment.
 public UpvalInfo(ProtoInfo pi) {
   this.pi = pi;
   this.slot = 0;
   this.nvars = 1;
   this.var = new VarInfo[] {VarInfo.PARAM(0)};
   this.rw = false;
 }
Exemplo n.º 9
0
  public ValueAndModified computeValueAndModified(ValueTuple vt) {
    int source_mod = base.getModified(vt);
    if (source_mod == ValueTuple.MISSING_NONSENSICAL) return ValueAndModified.MISSING_NONSENSICAL;
    if (source_mod == ValueTuple.MISSING_FLOW) return ValueAndModified.MISSING_FLOW;

    return computeValueAndModifiedImpl(vt);
  }
Exemplo n.º 10
0
  public String format_simplify() {
    String[] form = VarInfo.simplify_quantify(QuantFlags.adjacent(), var(), var());

    String comparator = "EQ";

    return form[0] + "(" + comparator + " " + form[1] + " " + form[2] + ")" + form[3];
  }
 private VariableManager(VarInfo varInfo, String condition, String className)
     throws ParseException {
   this.varInfo = varInfo;
   name = varInfo.name();
   compilableName = compilableName(varInfo, className);
   fieldName = fieldName(varInfo, className);
   varName = varName(varInfo, className);
   type = makeIndexIfNeeded(getVarType(varInfo), compilableName, varInfo, condition);
 }
Exemplo n.º 12
0
 private boolean includeVarAndPosteriorVars(VarInfo var) {
   if (var == null || var == VarInfo.INVALID) return false;
   if (var.upvalue == this) return true;
   var.upvalue = this;
   appendVar(var);
   if (isLoopVariable(var)) return false;
   boolean loopDetected = includePosteriorVarsCheckLoops(var);
   if (loopDetected) includePriorVarsIgnoreLoops(var);
   return loopDetected;
 }
Exemplo n.º 13
0
  /*@Pure*/
  public /*@Nullable*/ DiscardInfo isObviousDynamically(VarInfo[] vis) {

    // Do not show x-1 = a (mod b).  There must be a different mod
    // invariant over x.  JHP: This should really find the invariant rather
    // than presuming it is true.
    VarInfo x = vis[0];
    if ((x.derived instanceof SequenceLength) && (((SequenceLength) x.derived).shift != 0)) {
      return (new DiscardInfo(
          this,
          DiscardCode.obvious,
          "The invariant "
              + format()
              + " is implied by a mod invariant "
              + "over "
              + x.name()
              + " without the offset"));
    }
    return (null);
  }
    /**
     * Creates a valuetuple for the receiver using the vt of the original. The method copies over
     * the values of variables shared by both program points and sets the rest of the variables in
     * the receiver's valuetuple as missing. Also, adds the orig and derived variables to the
     * receiver and returns the newly created valuetuple.
     */
    private static ValueTuple copySample(
        PptTopLevel receiver, PptTopLevel original, ValueTuple vt, int nonce) {

      // Make the vt for the receiver ppt
      //      Object values[] = new Object[receiver.num_tracevars];
      //      int mods[] = new int[receiver.num_tracevars];
      Object values[] = new Object[receiver.var_infos.length - receiver.num_static_constant_vars];
      int mods[] = new int[receiver.var_infos.length - receiver.num_static_constant_vars];

      // Build the vt for the receiver ppt by looking through the current
      // vt and filling in the gaps.
      int k = 0;
      for (Iterator<VarInfo> i = receiver.var_info_iterator(); i.hasNext(); ) {

        VarInfo var = i.next();
        if (var.is_static_constant) continue;
        boolean found = false;
        for (Iterator<VarInfo> j = original.var_info_iterator(); j.hasNext(); ) {
          VarInfo var2 = j.next();

          if (var.name().equals(var2.name())) {
            values[k] = vt.getValueOrNull(var2);
            mods[k] = vt.getModified(var2);
            found = true;
            break;
          }
        }

        if (!found) {
          values[k] = null;
          mods[k] = 2;
        }
        k++;
      }

      ValueTuple receiver_vt = new ValueTuple(values, mods);

      FileIO.add_orig_variables(receiver, receiver_vt.vals, receiver_vt.mods, nonce);
      FileIO.add_derived_variables(receiver, receiver_vt.vals, receiver_vt.mods);

      return receiver_vt;
    }
Exemplo n.º 15
0
  /* IOA */
  public String format_ioa() {
    Quantify.IOAQuantification quant = VarInfo.get_ioa_quantify(var(), var());

    String result =
        quant.getQuantifierExp()
            + "("
            + quant.getMembershipRestriction(0)
            + " /\\ "
            + quant.getMembershipRestriction(1);

    // i \in X /\ j \in X => X[i] = X[j]

    result += ") => " + quant.getVarIndexedString(0) + " = " + quant.getVarIndexedString(1);
    return result + quant.getClosingExp();
  }
 /**
  * Calculates the base name of a variable. The base name of a variable is the part of the variable
  * with prefixes "this." and className removed, and "orig()" replaced by "orig_". For example
  * orig(this.x) goes to orig_x. If className is "Class" then "Class.x" would yield "x" and
  * "someOtherClass.x" would yield "someOtherClass_x". Finally, Java Reserved words are replaced
  * with appropriate substitutes.
  *
  * @param varInfo the VarInfo for the variable whose base name is desired.
  * @return the base name of the variable represented by varInfo.
  */
 private static String getBaseName(VarInfo varInfo, String className) {
   String name = varInfo.name();
   name = replaceReservedWords(name);
   if (name.length() > 5 && name.substring(0, 5).equals("orig(") && name.endsWith(")")) {
     name = name.substring(5, name.length() - 1);
     name = fixPrefixes(name, className);
     name = "orig_" + name;
   } else {
     name = fixPrefixes(name, className);
   }
   name = name.replace('.', '_');
   name = remove(name, ']');
   name = remove(name, '[');
   return name;
 }
  public BinaryDerivation /*@Nullable*/[] instantiate(VarInfo var1, VarInfo var2) {
    boolean enabled = SequencesPredicate.dkconfig_enabled;
    if (!enabled) return null;

    if (debug.isLoggable(Level.FINE)) {
      debug.fine("Trying to instantiate " + var1.name() + " and " + var2.name());
    }

    if (!(var1.rep_type.isArray()) || !(var2.rep_type.isArray())) {
      return null;
    }

    if (!var1.aux.getFlag(VarInfoAux.HAS_ORDER) || !var2.aux.getFlag(VarInfoAux.HAS_ORDER)) {
      // Order doesn't matter, then predication is meaningless
      return null;
    }

    if (SequencesPredicate.dkconfig_boolOnly) {
      if (!(var2.file_rep_type == ProglangType.BOOLEAN_ARRAY)) {
        return null;
      }
    }

    if (var1.derived != null || var2.derived != null) {
      // From derived variables.  Don't derive.
      return null;
    }

    if (SequencesPredicate.dkconfig_fieldOnly) {

      if (!var1.is_field() || !var2.is_field()) return null;

      if (!var1.has_same_parent(var2)) return null;
    } else {
      // There may be predications that aren't of the x.a and x.b type
    }

    // Now we finally can derive

    if (debug.isLoggable(Level.FINE)) {
      debug.fine(
          var1.ppt + ": " + var1.name() + " and " + var2.name() + " are worth deriving from");
    }

    return new BinaryDerivation[] {
      new SequencesPredicate(var1, var2, 0, "false"), new SequencesPredicate(var1, var2, 1, "true"),
      // new SequencesPredicate (var1, var2, 0, "nonNull", false),
    };
  }
Exemplo n.º 18
0
  // (Seems overkill to check for other transitive relationships.
  // Eventually that is probably the right thing, however.)
  public DiscardInfo isObviousDynamically(VarInfo[] vis) {

    // System.out.println("checking isObviousImplied for: " + format());
    if (debug.isLoggable(Level.FINE)) {
      debug.fine("isObviousDynamically: checking " + vis[0].name() + " in " + vis[1].name());
    }

    DiscardInfo super_result = super.isObviousDynamically(vis);
    if (super_result != null) {
      return super_result;
    }

    VarInfo subvar = var1(vis);
    VarInfo supervar = var2(vis);

    // JHP: The next check is an un-interesting check, not
    // an obvious check.  We need to figure out how to resolve this.

    // Uninteresting if this is of the form x[0..i] subsequence
    // x[0..j].  Not necessarily obvious.
    VarInfo subvar_super = subvar.isDerivedSubSequenceOf();
    VarInfo supervar_super = supervar.isDerivedSubSequenceOf();
    if (subvar_super != null && subvar_super == supervar_super) {
      debug.fine("  returning true because subvar_super == supervar_super");
      return new DiscardInfo(
          this, DiscardCode.obvious, "x[0..i] subsequence of x[0..j] is uninteresting");
    }

    if (isObviousSubSequenceDynamically(this, subvar, supervar)) {
      return new DiscardInfo(
          this,
          DiscardCode.obvious,
          subvar.name() + " is an obvious subsequence of " + supervar.name());
    }
    return null;
  }
    private void add(PptTopLevel ppt, ValueTuple vt, int nonce) {

      // if this is a numbered exit, apply to the combined exit as well
      if (ppt.ppt_name.isNumberedExitPoint()) {

        // Daikon.create_combined_exits(all_ppts);
        PptTopLevel parent = all_ppts.get(ppt.ppt_name.makeExit());
        if (parent != null) {
          parent.get_missingOutOfBounds(ppt, vt);
          add(parent, vt, nonce);

        } else {
          // make parent and apply

          // this is a hack. it should probably filter out orig and derived
          // vars instead of taking the first n.
          int len = ppt.num_tracevars + ppt.num_static_constant_vars;
          VarInfo[] exit_vars = new VarInfo[len];
          for (int j = 0; j < len; j++) {
            exit_vars[j] = new VarInfo(ppt.var_infos[j]);
            exit_vars[j].varinfo_index = ppt.var_infos[j].varinfo_index;
            exit_vars[j].value_index = ppt.var_infos[j].value_index;
            exit_vars[j].equalitySet = null;
          }

          parent = new PptTopLevel(ppt.ppt_name.makeExit().getName(), exit_vars);
          Daikon.init_ppt(parent, all_ppts);
          all_ppts.add(parent);
          parent.get_missingOutOfBounds(ppt, vt);
          add(parent, vt, nonce);
        }
      }

      // If the point has no variables, skip it
      if (ppt.var_infos.length == 0) {
        // The sample should be skipped but Daikon does not do this so
        // DaikonSimple will not do this to be consistent.
        // The better idea is for Daikon to assert that these valuetuples are
        // empty and then skip the sample.
        assert vt.size() == 0;
        return;
      }

      // Instantiate slices and invariants if this is the first sample
      if (ppt.num_samples() == 0) {
        instantiate_views_and_invariants(ppt);
      }

      // manually inc the sample number because DaikonSimple does not
      // use any of PptTopLevel's add methods which increase the sample
      // number
      ppt.incSampleNumber();

      // Loop through each slice
      for (Iterator<PptSlice> i = ppt.views_iterator(); i.hasNext(); ) {
        PptSlice slice = i.next();
        Iterator<Invariant> k = slice.invs.iterator();
        boolean missing = false;

        for (VarInfo v : slice.var_infos) {
          // If any var has encountered out of array bounds values,
          // stop all invariants in this slice. The presumption here is that
          // an index out of bounds implies that the derived variable (eg a[i])
          // doesn't really make any sense (essentially that i is not a valid
          // index for a). Invariants on the derived variable are thus not
          // relevant.
          // If any variables are out of bounds, remove the invariants
          if (v.missingOutOfBounds()) {
            while (k.hasNext()) {
              Invariant inv = k.next();
              k.remove();
            }
            missing = true;
            break;
          }

          // If any variables are missing, skip this slice
          if (v.isMissing(vt)) {
            missing = true;
            break;
          }
        }

        // keep a list of the falsified invariants
        if (!missing) {
          while (k.hasNext()) {

            Invariant inv = k.next();
            Invariant pre_inv = inv.clone();
            for (VarInfo vi : inv.ppt.var_infos) {
              assert vt.getValue(vi) != null : vi;
            }
            if (inv.ppt instanceof PptSlice2) assert inv.ppt.var_infos.length == 2;
            InvariantStatus status = inv.add_sample(vt, 1);
            if (status == InvariantStatus.FALSIFIED) {
              k.remove();
            }
          }
        }

        // update num_samples and num_values of a slice manually
        // because DaikonSimple does not call any of PptTopLevel's
        // add methods
        for (int j = 0; j < vt.vals.length; j++) {
          if (!vt.isMissing(j)) {
            ValueSet vs = ppt.value_sets[j];
            vs.add(vt.vals[j]);
          }
        }
        ppt.mbtracker.add(vt, 1);
      }
    }
Exemplo n.º 20
0
  /**
   * Extract consequents from a implications at a single program point. It only searches for top
   * level Program points because Implications are produced only at those points.
   */
  public static void extract_consequent_maybe(PptTopLevel ppt, PptMap all_ppts) {
    ppt.simplify_variable_names();

    List<Invariant> invs = new ArrayList<Invariant>();
    if (invs.size() > 0) {
      String pptname = cleanup_pptname(ppt.name());
      for (Invariant maybe_as_inv : invs) {
        Implication maybe = (Implication) maybe_as_inv;

        // don't print redundant invariants.
        if (Daikon.suppress_redundant_invariants_with_simplify
            && maybe.ppt.parent.redundant_invs.contains(maybe)) {
          continue;
        }

        // don't print out invariants with min(), max(), or sum() variables
        boolean mms = false;
        VarInfo[] varbls = maybe.ppt.var_infos;
        for (int v = 0; !mms && v < varbls.length; v++) {
          mms |= varbls[v].isDerivedSequenceMinMaxSum();
        }
        if (mms) {
          continue;
        }

        if (maybe.ppt.parent.ppt_name.isExitPoint()) {
          for (int i = 0; i < maybe.ppt.var_infos.length; i++) {
            VarInfo vi = maybe.ppt.var_infos[i];
            if (vi.isDerivedParam()) {
              continue;
            }
          }
        }

        Invariant consequent = maybe.consequent();
        Invariant predicate = maybe.predicate();
        Invariant inv, cluster_inv;
        boolean cons_uses_cluster = false, pred_uses_cluster = false;
        // extract the consequent (predicate) if the predicate
        // (consequent) uses the variable "cluster".  Ignore if they
        // both depend on "cluster"
        if (consequent.usesVarDerived("cluster")) cons_uses_cluster = true;
        if (predicate.usesVarDerived("cluster")) pred_uses_cluster = true;

        if (!(pred_uses_cluster ^ cons_uses_cluster)) {
          continue;
        } else if (pred_uses_cluster) {
          inv = consequent;
          cluster_inv = predicate;
        } else {
          inv = predicate;
          cluster_inv = consequent;
        }

        if (!inv.isInteresting()) {
          continue;
        }

        if (!inv.isWorthPrinting()) {
          continue;
        }

        if (contains_constant_non_012(inv)) {
          continue;
        }

        // filter out unwanted invariants

        // 1) Invariants involving sequences
        if (inv instanceof daikon.inv.binary.twoSequence.TwoSequence
            || inv instanceof daikon.inv.binary.sequenceScalar.SequenceScalar
            || inv instanceof daikon.inv.binary.sequenceString.SequenceString
            || inv instanceof daikon.inv.unary.sequence.SingleSequence
            || inv instanceof daikon.inv.unary.stringsequence.SingleStringSequence) {
          continue;
        }

        if (inv instanceof daikon.inv.ternary.threeScalar.LinearTernary
            || inv instanceof daikon.inv.binary.twoScalar.LinearBinary) {
          continue;
        }

        String inv_string = inv.format_using(OutputFormat.JAVA);
        if (orig_pattern.matcher(inv_string).find()
            || dot_class_pattern.matcher(inv_string).find()) {
          continue;
        }
        String fake_inv_string = simplify_inequalities(inv_string);
        HashedConsequent real = new HashedConsequent(inv, null);
        if (!fake_inv_string.equals(inv_string)) {
          // For instance, inv_string is "x != y", fake_inv_string is "x == y"
          HashedConsequent fake = new HashedConsequent(inv, inv_string);
          boolean added =
              store_invariant(
                  cluster_inv.format_using(OutputFormat.JAVA), fake_inv_string, fake, pptname);
          if (!added) {
            // We couldn't add "x == y", (when we're "x != y") because
            // it already exists; so don't add "x == y" either.
            continue;
          }
        }
        store_invariant(cluster_inv.format_using(OutputFormat.JAVA), inv_string, real, pptname);
      }
    }
  }
  /**
   * Returns whether or not the specified ternary slice should be created. The slice should not be
   * created if any of the following are true - Any var is an array - Any of the vars are not
   * compatible with the others - Any var is not (integral or float)
   *
   * <p>Since we are trying to create all of the invariants, the variables does not have to be a
   * leader and can be a constant. Note that the always missing check is only applicable when the
   * dynamic constants optimization is turned on (so we do not do the check here). In addition, we
   * do want to create the reflexive ones and partially reflexive invariants.
   *
   * @see daikon.PptTopLevel#is_slice_ok(VarInfo, VarInfo, VarInfo)
   */
  public static boolean is_slice_ok(VarInfo v1, VarInfo v2, VarInfo v3) {

    // Vars must be compatible
    return (v1.compatible(v2) && v1.compatible(v3) && v2.compatible(v3));
  }
  /**
   * Returns whether or not the specified binary slice should be created. The slice should not be
   * created if the vars not compatible.
   *
   * <p>Since we are trying to create all of the invariants, the variables does not have to be a
   * leader and can be a constant. Note that the always missing check is only applicable when the
   * dynamic constants optimization is turned on (so we do not do the check here).
   *
   * @see daikon.PptTopLevel#is_slice_ok(VarInfo, VarInfo)
   */
  public static boolean is_slice_ok(VarInfo v1, VarInfo v2) {

    return v1.compatible(v2);
  }
  // Note that some slightly inefficient code has been added to aid
  // in debugging. When creating binary and ternary views and debugging
  // is on, the outer loops will not terminate prematurely on innapropriate
  // (i.e., non-canonical) variables. This allows explicit debug statements
  // for each possible combination, simplifying determining why certain
  // slices were not created.
  //
  // Note that '///*' indicates code duplicated from PptTopLevel's
  // version but commented out because DaikonSimple does not need
  // to perform these checks
  public static void instantiate_views_and_invariants(PptTopLevel ppt) {

    // used only for debugging
    int old_num_vars = ppt.var_infos.length;
    int old_num_views = ppt.numViews();
    boolean debug_on = debug.isLoggable(Level.FINE);

    // / 1. all unary views

    // Unary slices/invariants.
    // Currently, there are no constraints on the unary
    // slices. Since we are trying to create all of the invariants, the
    // variables does not have to be a leader and can be a constant.
    // Note that the always missing check is only applicable when the
    // dynamic constants optimization is turned on (so we do not do the
    // check here).

    Vector<PptSlice> unary_views = new Vector<PptSlice>(ppt.var_infos.length);
    for (VarInfo vi : ppt.var_infos) {

      // /* if (!is_slice_ok(vi))
      // /* continue;

      PptSlice1 slice1 = new PptSlice1(ppt, vi);
      slice1.instantiate_invariants();

      unary_views.add(slice1);
    }
    ppt.addViews(unary_views);
    unary_views = null;

    // / 2. all binary views

    // Binary slices/invariants.
    Vector<PptSlice> binary_views = new Vector<PptSlice>();
    for (int i1 = 0; i1 < ppt.var_infos.length; i1++) {
      VarInfo var1 = ppt.var_infos[i1];

      // Variables can be constant and missing in DaikonSimple invariants
      // /* if (!is_var_ok_binary(var1))
      // /* continue;

      for (int i2 = i1; i2 < ppt.var_infos.length; i2++) {
        VarInfo var2 = ppt.var_infos[i2];

        // Variables can be constant and missing in DaikonSimple invariants
        // /* if (!is_var_ok_binary(var2))
        // /* continue;

        if (!(var1.compatible(var2)
            || (var1.type.isArray() && var1.eltsCompatible(var2))
            || (var2.type.isArray() && var2.eltsCompatible(var1)))) {
          continue;
        }

        PptSlice2 slice2 = new PptSlice2(ppt, var1, var2);
        slice2.instantiate_invariants();

        binary_views.add(slice2);
      }
    }
    ppt.addViews(binary_views);
    binary_views = null;

    // 3. all ternary views
    Vector<PptSlice> ternary_views = new Vector<PptSlice>();
    for (int i1 = 0; i1 < ppt.var_infos.length; i1++) {
      VarInfo var1 = ppt.var_infos[i1];

      if (!is_var_ok(var1)) continue;

      for (int i2 = i1; i2 < ppt.var_infos.length; i2++) {
        VarInfo var2 = ppt.var_infos[i2];

        if (!is_var_ok(var2)) continue;

        for (int i3 = i2; i3 < ppt.var_infos.length; i3++) {
          VarInfo var3 = ppt.var_infos[i3];

          if (!is_var_ok(var3)) continue;

          if (!is_slice_ok(var1, var2, var3)) {
            continue;
          }
          PptSlice3 slice3 = new PptSlice3(ppt, var1, var2, var3);
          slice3.instantiate_invariants();
          ternary_views.add(slice3);
        }
      }
    }

    ppt.addViews(ternary_views);

    // This method didn't add any new variables.
    assert old_num_vars == ppt.var_infos.length;
    ppt.repCheck();
  }
 protected VarInfo makeVarInfo() {
   return VarInfo.make_subscript(base, null, index);
 }
 public boolean isDerivedFromNonCanonical() {
   // We insist that both are canonical, not just one.
   return !(base1.isCanonical() && base2.isCanonical() && base3.isCanonical());
 }
Exemplo n.º 26
0
  /**
   * @return Array "a" such that a[0] is a valid discardCode and a[1] is a valid discardString. If
   *     the Invariant is not an obvious subsequence, both are null
   */
  public static Object[] isObviousSubSequence(VarInfo subvar, VarInfo supervar) {
    // Must typecheck since this could be called with non sequence variables in
    // some methods.
    ProglangType rep1 = subvar.rep_type;
    ProglangType rep2 = supervar.rep_type;
    if (!(((rep1 == ProglangType.INT_ARRAY) && (rep2 == ProglangType.INT_ARRAY))
        || ((rep1 == ProglangType.DOUBLE_ARRAY) && (rep2 == ProglangType.DOUBLE_ARRAY))
        || ((rep1 == ProglangType.STRING_ARRAY) && (rep2 == ProglangType.STRING_ARRAY)))) {
      return new Object[] {null, null};
    }

    if (debug.isLoggable(Level.FINE)) {
      debug.fine("isObviousSubSequence " + subvar.name() + "in " + supervar.name());
    }

    // Standard discard reason/string
    DiscardCode discardCode = DiscardCode.obvious;
    String discardString = subvar.name() + " obvious subset/subsequence of " + supervar.name();

    // For unions and intersections, it probably doesn't make sense to
    // do subsequence or subset detection.  This is mainly to prevent
    // invariants of the form (x subset of union(x, y)) but this means
    // we also miss those of the form (z subset of union(x,y)) which
    // might be useful.  Subsequence, however, seems totally useless
    // on unions and intersections.
    if (supervar.derived instanceof SequenceScalarIntersection
        || supervar.derived instanceof SequenceScalarUnion
        || subvar.derived instanceof SequenceScalarIntersection
        || subvar.derived instanceof SequenceScalarUnion) {
      discardCode = DiscardCode.obvious;
      discardString =
          "Invariants involving subsets/subsequences of unions/intersections" + "are suppressed";
      debug.fine("  returning true because of union or intersection");
      return new Object[] {discardCode, discardString};
    }

    if (subvar.derived instanceof SequencesPredicate) {
      // It's not useful that predicate(x[], b[]) is a subsequence or subset
      // of x[]
      SequencesPredicate derived = (SequencesPredicate) subvar.derived;
      if (derived.var1().equals(supervar)) {
        discardCode = DiscardCode.obvious;
        discardString = subvar.name() + " is derived from " + supervar.name();
        debug.fine("  returning true because of predicate slicing");
        return new Object[] {discardCode, discardString + " [pred slicing]"};
      }
    }

    VarInfo subvar_super = subvar.isDerivedSubSequenceOf();
    if (subvar_super == null) {
      // If it's not a union, intersection or a subsequence, it's not obvious
      debug.fine("  returning false because subvar_super == null");
      return new Object[] {null, null};
    }

    if (subvar_super == supervar) {
      // System.out.println("SubSequence.isObviousDerived(" + subvar.name() + ", " + supervar.name +
      // ") = true");
      // System.out.println("  details: subvar_super=" + subvar_super.name + "; supervar_super=" +
      // supervar.isDerivedSubSequenceOf() == null ? "null" :
      // supervar.isDerivedSubSequenceOf().name);
      discardCode = DiscardCode.obvious;
      discardString = subvar.name() + "==" + supervar.name();
      debug.fine("  returning true because subvar_super == supervar");
      return new Object[] {discardCode, discardString + " [subvar_super == supervar]"};
    }

    // a[i+a..j+b] cmp a[i+c..j+d]
    VarInfo supervar_super = supervar.isDerivedSubSequenceOf();
    // we know subvar_super != null due to check above
    if (subvar_super == supervar_super) {
      // both sequences are derived from the same supersequence
      if ((subvar.derived instanceof SequenceScalarSubsequence
              || subvar.derived instanceof SequenceScalarArbitrarySubsequence)
          && (supervar.derived instanceof SequenceScalarSubsequence
              || supervar.derived instanceof SequenceScalarArbitrarySubsequence)) {
        // In "A[i..j] subseq B[k..l]": i=sub_left_var, j=sub_right_var,
        //  k=super_left_var, l=super_right_var.
        VarInfo sub_left_var = null,
            sub_right_var = null,
            super_left_var = null,
            super_right_var = null;
        // I'm careful not to access foo_shift unless foo_var has been set
        // to a non-null value, but Java is too stupid to recognize that.
        int sub_left_shift = 42,
            sub_right_shift = 69,
            super_left_shift = 1492,
            super_right_shift = 1776;
        if (subvar.derived instanceof SequenceScalarSubsequence) {
          SequenceScalarSubsequence sub = (SequenceScalarSubsequence) subvar.derived;
          if (sub.from_start) {
            sub_right_var = sub.sclvar();
            sub_right_shift = sub.index_shift;
          } else {
            sub_left_var = sub.sclvar();
            sub_left_shift = sub.index_shift;
          }
        } else if (subvar.derived instanceof SequenceScalarArbitrarySubsequence) {
          SequenceScalarArbitrarySubsequence sub =
              (SequenceScalarArbitrarySubsequence) subvar.derived;
          sub_left_var = sub.startvar();
          sub_left_shift = (sub.left_closed ? 0 : 1);
          sub_right_var = sub.endvar();
          sub_right_shift = (sub.right_closed ? 0 : -1);
        } else {
          Assert.assertTrue(false);
        }
        if (supervar.derived instanceof SequenceScalarSubsequence) {
          SequenceScalarSubsequence super_ = (SequenceScalarSubsequence) supervar.derived;
          if (super_.from_start) {
            super_right_var = super_.sclvar();
            super_right_shift = super_.index_shift;
          } else {
            super_left_var = super_.sclvar();
            super_left_shift = super_.index_shift;
          }
        } else if (supervar.derived instanceof SequenceScalarArbitrarySubsequence) {
          SequenceScalarArbitrarySubsequence super_ =
              (SequenceScalarArbitrarySubsequence) supervar.derived;
          super_left_var = super_.startvar();
          super_left_shift = (super_.left_closed ? 0 : 1);
          super_right_var = super_.endvar();
          super_right_shift = (super_.right_closed ? 0 : -1);
        } else {
          Assert.assertTrue(false);
        }
        boolean left_included = false, right_included = false;
        if (super_left_var == null) left_included = true;
        if (super_left_var == sub_left_var) {
          if (super_left_shift < sub_left_shift) left_included = true;
        }
        if (super_right_var == null) right_included = true;
        if (super_right_var == sub_right_var) {
          if (super_right_shift > sub_right_shift) right_included = true;
        }
        if (left_included && right_included) {
          discardCode = DiscardCode.obvious;
          discardString = subvar.name() + " obvious subset/subsequence of " + supervar.name();
          return new Object[] {discardCode, discardString + " [obvious]"};
        }
      } else if ((subvar.derived instanceof SequenceStringSubsequence)
          && (supervar.derived instanceof SequenceStringSubsequence)) {
        // Copied from (an old version) just above
        // XXX I think this code is dead; why isn't it just produced
        // from the above by macro expansion? -smcc
        SequenceStringSubsequence sss1 = (SequenceStringSubsequence) subvar.derived;
        SequenceStringSubsequence sss2 = (SequenceStringSubsequence) supervar.derived;
        VarInfo index1 = sss1.sclvar();
        int shift1 = sss1.index_shift;
        boolean start1 = sss1.from_start;
        VarInfo index2 = sss2.sclvar();
        int shift2 = sss2.index_shift;
        boolean start2 = sss2.from_start;
        if (index1 == index2) {
          if (start1 == true && start2 == true) {
            if (shift1 <= shift2) return new Object[] {discardCode, discardString + " [shift1]"};
          } else if (start1 == false && start2 == false) {
            if (shift1 >= shift2) return new Object[] {discardCode, discardString + " [shift2]"};
          }
        }
      } else {
        Assert.assertTrue(
            false,
            "how can this happen? "
                + subvar.name()
                + " "
                + subvar.derived.getClass()
                + " "
                + supervar.name()
                + " "
                + supervar.derived.getClass());
      }
    }

    return new Object[] {null, null};
  }
  public String format_esc() {
    String[] form = VarInfo.esc_quantify(false, var(), var());

    return form[0] + "((i+1 == j) ==> (" + form[1] + " < " + form[2] + "))" + form[3];
  }
Exemplo n.º 28
0
  public String format_esc() {
    String[] form = VarInfo.esc_quantify(false, var(), var());

    return form[0] + "(" + form[1] + " == " + form[2] + ")" + form[3];
  }
Exemplo n.º 29
0
  /**
   * Returns true if the two original variables are related in a way that makes subsequence or
   * subset detection not informative.
   */
  public static boolean isObviousSubSequenceDynamically(
      Invariant inv, VarInfo subvar, VarInfo supervar) {

    VarInfo[] vis = {subvar, supervar};

    ProglangType rep1 = subvar.rep_type;
    ProglangType rep2 = supervar.rep_type;
    if (!(((rep1 == ProglangType.INT_ARRAY) && (rep2 == ProglangType.INT_ARRAY))
        || ((rep1 == ProglangType.DOUBLE_ARRAY) && (rep2 == ProglangType.DOUBLE_ARRAY))
        || ((rep1 == ProglangType.STRING_ARRAY) && (rep2 == ProglangType.STRING_ARRAY))))
      return false;

    if (debug.isLoggable(Level.FINE)) {
      debug.fine(
          "Checking isObviousSubSequenceDynamically " + subvar.name() + " in " + supervar.name());
    }

    Object[] di = isObviousSubSequence(subvar, supervar);
    if (di[1] != null) {
      inv.log("ObvSubSeq- true from isObviousSubSequence: " + di[1]);
      return true;
    }
    debug.fine("  not isObviousSubSequence(statically)");

    PptTopLevel ppt_parent = subvar.ppt;

    // If the elements of supervar are always the same (EltOneOf),
    // we aren't going to learn anything new from this invariant,
    // since each sequence should have an EltOneOf over it.
    if (false) {
      PptSlice1 slice = ppt_parent.findSlice(supervar);
      if (slice == null) {
        System.out.println("No slice: parent =" + ppt_parent);
      } else {
        System.out.println("Slice var =" + slice.var_infos[0]);
        for (Invariant superinv : slice.invs) {
          System.out.println("Inv = " + superinv);
          if (superinv instanceof EltOneOf) {
            EltOneOf eltinv = (EltOneOf) superinv;
            if (eltinv.num_elts() > 0) {
              inv.log(" obvious because of " + eltinv.format());
              return true;
            }
          }
        }
      }
    }

    // Obvious if subvar is always just []
    if (true) {
      PptSlice1 slice = ppt_parent.findSlice(subvar);
      if (slice != null) {
        for (Invariant subinv : slice.invs) {
          if (subinv instanceof OneOfSequence) {
            OneOfSequence seqinv = (OneOfSequence) subinv;
            if (seqinv.num_elts() == 1) {
              Object elt = seqinv.elt();
              if (elt instanceof long[] && ((long[]) elt).length == 0) {
                Debug.log(
                    debug, inv.getClass(), inv.ppt, vis, "ObvSubSeq- True from subvar being []");
                return true;
              }
              if (elt instanceof double[] && ((double[]) elt).length == 0) {
                inv.log("ObvSubSeq- True from subvar being []");
                return true;
              }
            }
          }
        }
      }
    }

    // Check for a[0..i] subseq a[0..j] but i < j.
    VarInfo subvar_super = subvar.isDerivedSubSequenceOf();
    VarInfo supervar_super = supervar.isDerivedSubSequenceOf();

    if (subvar_super != null && subvar_super == supervar_super) {
      // both sequences are derived from the same supersequence
      if ((subvar.derived instanceof SequenceScalarSubsequence
              || subvar.derived instanceof SequenceScalarArbitrarySubsequence)
          && (supervar.derived instanceof SequenceScalarSubsequence
              || supervar.derived instanceof SequenceScalarArbitrarySubsequence)) {
        VarInfo sub_left_var = null,
            sub_right_var = null,
            super_left_var = null,
            super_right_var = null;
        // I'm careful not to access foo_shift unless foo_var has been set
        // to a non-null value, but Java is too stupid to recognize that.
        int sub_left_shift = 42,
            sub_right_shift = 69,
            super_left_shift = 1492,
            super_right_shift = 1776;
        if (subvar.derived instanceof SequenceScalarSubsequence) {
          SequenceScalarSubsequence sub = (SequenceScalarSubsequence) subvar.derived;
          if (sub.from_start) {
            sub_right_var = sub.sclvar();
            sub_right_shift = sub.index_shift;
          } else {
            sub_left_var = sub.sclvar();
            sub_left_shift = sub.index_shift;
          }
        } else if (subvar.derived instanceof SequenceScalarArbitrarySubsequence) {
          SequenceScalarArbitrarySubsequence sub =
              (SequenceScalarArbitrarySubsequence) subvar.derived;
          sub_left_var = sub.startvar();
          sub_left_shift = (sub.left_closed ? 0 : 1);
          sub_right_var = sub.endvar();
          sub_right_shift = (sub.right_closed ? 0 : -1);
        } else {
          Assert.assertTrue(false);
        }
        if (supervar.derived instanceof SequenceScalarSubsequence) {
          SequenceScalarSubsequence super_ = (SequenceScalarSubsequence) supervar.derived;
          if (super_.from_start) {
            super_right_var = super_.sclvar();
            super_right_shift = super_.index_shift;
          } else {
            super_left_var = super_.sclvar();
            super_left_shift = super_.index_shift;
          }
        } else if (supervar.derived instanceof SequenceScalarArbitrarySubsequence) {
          SequenceScalarArbitrarySubsequence super_ =
              (SequenceScalarArbitrarySubsequence) supervar.derived;
          super_left_var = super_.startvar();
          super_left_shift = (super_.left_closed ? 0 : 1);
          super_right_var = super_.endvar();
          super_right_shift = (super_.right_closed ? 0 : -1);
        } else {
          Assert.assertTrue(false);
        }
        boolean left_included, right_included;
        if (super_left_var == null) left_included = true;
        else if (sub_left_var == null) // we know super_left_var != null here
        left_included = false;
        else
          left_included =
              VarInfo.compare_vars(
                  super_left_var, super_left_shift, sub_left_var, sub_left_shift, true /* <= */);
        if (super_right_var == null) right_included = true;
        else if (sub_right_var == null) // we know super_right_var != null here
        right_included = false;
        else
          right_included =
              VarInfo.compare_vars(
                  super_right_var,
                  super_right_shift,
                  sub_right_var,
                  sub_right_shift,
                  false /* >= */);
        //         System.out.println("Is " + subvar.name() + " contained in "
        //                            + supervar.name()
        //                            + "? left: " + left_included + ", right: "
        //                            + right_included);
        if (left_included && right_included) {
          inv.log("ObvSubSeq- True a[0..i] subseq a[0..j] and i < j");
          return true;
        }
      } else if ((subvar.derived instanceof SequenceStringSubsequence)
          && (supervar.derived instanceof SequenceStringSubsequence)) {
        // Copied from just above
        SequenceStringSubsequence sss1 = (SequenceStringSubsequence) subvar.derived;
        SequenceStringSubsequence sss2 = (SequenceStringSubsequence) supervar.derived;
        VarInfo index1 = sss1.sclvar();
        int shift1 = sss1.index_shift;
        boolean start1 = sss1.from_start;
        VarInfo index2 = sss2.sclvar();
        int shift2 = sss2.index_shift;
        boolean start2 = sss2.from_start;
        if (start1 == start2)
          if (VarInfo.compare_vars(index1, shift1, index2, shift2, start1)) {
            inv.log("True from comparing indices");
            return true;
          }
      } else {
        Assert.assertTrue(
            false,
            "how can this happen? "
                + subvar.name()
                + " "
                + subvar.derived.getClass()
                + " "
                + supervar.name()
                + " "
                + supervar.derived.getClass());
      }
    }

    // Also need to check A[0..i] subseq A[0..j] via compare_vars.

    // A subseq B[0..n] => A subseq B

    List<Derivation> derivees = supervar.derivees();
    // For each variable derived from supervar ("B")
    for (Derivation der : derivees) {
      // System.out.println("  ... der = " + der.getVarInfo().name() + " " + der);
      if (der instanceof SequenceScalarSubsequence) {
        // If that variable is "B[0..n]"
        VarInfo supervar_part = der.getVarInfo();
        // Get the canonical version; being equal to it is good enough.
        if (supervar_part.get_equalitySet_leader() == subvar) {
          Debug.log(debug, inv.getClass(), inv.ppt, vis, "ObvSubSeq- True from canonical leader");
          return true;
        }

        if (supervar_part.isCanonical()) {
          if (subvar == supervar_part) {
            System.err.println(
                "Error: variables "
                    + subvar.name()
                    + " and "
                    + supervar_part.name()
                    + " are identical.  Canonical");
            System.err.println(subvar.isCanonical());
            System.err.println(supervar_part.isCanonical());
            throw new Error();
          }

          // Check to see if there is a subsequence over the supervar
          if (ppt_parent.is_subsequence(subvar, supervar_part)) {
            if (Debug.logOn())
              inv.log(
                  "ObvSubSeq- true from A subseq B[0..n] "
                      + subvar.name()
                      + "/"
                      + supervar_part.name());
            return (true);
          }
        }
      }
    }
    return false;
  }
 public int derivedDepth() {
   return 1 + Math.max(base1.derivedDepth(), Math.max(base2.derivedDepth(), base3.derivedDepth()));
 }