示例#1
0
  public void checkTermination(Context ctxt) {
    Expr no_annos = dropAnnos(ctxt).defExpandTop(ctxt);
    if (no_annos.construct == FUN_TERM || no_annos.construct == CONST) return;
    if (no_annos.construct != TERM_APP)
      handleError(
          ctxt,
          "We are checking termination of a term application where"
              + " dropping\nannotations gives an unexpected form of expression."
              + "1. the term application: "
              + toString(ctxt)
              + "\n2. with annotations dropped: "
              + no_annos.toString(ctxt));
    TermApp t = (TermApp) ((TermApp) no_annos).spineForm(ctxt, true, true, true);

    TermApp anno_t = (TermApp) spineForm(ctxt, false, true, true);
    if (ctxt.getFlag("debug_terminates")) {
      ctxt.w.println(
          "termTerminates checking TermApp.\n"
              + "\n1. original term, no annos: "
              + no_annos.toString(ctxt)
              + "\n2. spine form, no annos: "
              + t.toString(ctxt)
              + "\n3. spine form, with annos: "
              + anno_t.toString(ctxt)
              + "\n4. head:"
              + anno_t.head.toString(ctxt)
              + "\n5. inj:"
              + anno_t.isI(ctxt)
              + "\n5. head is ctor:"
              + (anno_t.head.construct == CONST ? ctxt.isTermCtor((Const) anno_t.head) : "false"));
      ctxt.w.flush();
    }

    if (t.head.construct != CONST)
      handleError(
          ctxt,
          "Checking termination, the head of an application is "
              + "not a constant.\n"
              + "1. the application in spine form: "
              + t.toString(ctxt)
              + "\n2. the head: "
              + t.head.toString(ctxt));

    Const c = (Const) t.head;
    boolean is_total = ctxt.isTotal(c);
    if (!is_total && !ctxt.isTermCtor(c))
      handleError(
          ctxt,
          "Checking termination, the head of an application is "
              + "neither\ndeclared total nor a term constructor.\n"
              + "1. the application in spine form: "
              + t.toString(ctxt)
              + "\n2. the head: "
              + c.toString(ctxt));

    if (is_total) {
      /* a little more work is needed here to check that if
      totality were proved when some arguments are certain
      fixed other terms, we have those arguments here. */
      Collection thms = ctxt.getTotalityTheorems(c);
      Iterator it = thms.iterator();

      boolean problem = true;
      while (it.hasNext()) {
        Forall F = (Forall) it.next();
        TermApp lhs = (TermApp) ((Atom) ((Exists) F.body).body).Y1;

        problem = false;
        for (int j = 0, jend = lhs.X.length; j < jend; j++)
          if (lhs.X[j].construct != VAR)
            if (!lhs.X[j].defEq(ctxt, t.X[j])) {
              problem = true;
              break; // out of for loop
            }
        if (!problem)
          // we have found a matching totality theorem.
          break; // out of while loop
      }

      if (problem) {
        String s =
            ("Termination checking cannot find a registered totality theorem"
                + " for the\ngiven application.  The number of theorems registered"
                + " for the head is "
                + (new Integer(thms.size())).toString()
                + ".\n"
                + "1. the term to termination check: "
                + t.toString());
        if (thms.size() > 0) {
          s = s + "2. the totality theorems registered for the head:\n";
          it = thms.iterator();
          while (it.hasNext()) {
            Forall F = (Forall) it.next();
            s = s + "-- " + F.toString(ctxt);
          }
        }
        handleError(ctxt, s);
      }
    }

    /* we cannot look at just t next, because terminates casts
    will have been dropped computing it. */
    for (int i = 0, iend = t.X.length; i < iend; i++) anno_t.X[i].checkTermination(ctxt);
  }