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