// 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();
  }