public Expr classify(Context ctxt, int approx, boolean spec) { if (ctxt.getFlag("debug_classify_term_apps")) { ctxt.w.print("(Classifying "); print(ctxt.w, ctxt); ctxt.w.println(""); ctxt.w.flush(); } Expr cl = head.classify(ctxt, approx, spec).defExpandTop(ctxt, false, spec); Expr ret = apply_classifier(FUN_TYPE, approx, spec, ctxt, cl, 0); FunType ch = (FunType) ((FunType) cl).coalesce(ctxt, spec); boolean check_spec_terminates = ctxt.getFlag("check_spec_terminates"); for (int i = 0; i < X.length; i++) { if (ch.owned[i].status == Ownership.SPEC) { if (check_spec_terminates) X[i].checkTermination(ctxt); specarg[i] = true; } } if (ctxt.getFlag("debug_classify_term_apps")) { ctxt.w.println(") Classifier is:"); ret.print(ctxt.w, ctxt); ctxt.w.println(""); ctxt.w.flush(); } return ret; }
public Expr dropNoncompArgs(Context ctxt) { if (ctxt.getFlag("debug_drop_noncomp")) { ctxt.w.println("Dropping non-comp arguments from term-app " + toString(ctxt)); ctxt.w.flush(); } ArrayList nX = new ArrayList(); ArrayList no = new ArrayList(); boolean changed = false; Boolean b = new Boolean(false); for (int i = 0, iend = X.length; i < iend; i++) { if (X[i].isProof(ctxt) || specarg[i]) changed = true; else { nX.add(X[i]); no.add(b); } } Expr ret = this; if (changed) { if (nX.size() == 0) ret = head; else ret = new TermApp(head, Parser.toExprArray(nX), Parser.toBooleanArray(no)); } if (ctxt.getFlag("debug_drop_noncomp")) { ctxt.w.println("Returning " + ret.toString(ctxt)); ctxt.w.flush(); } return ret; }
public App spineForm(Context ctxt, boolean drop_annos, boolean spec, boolean expand_defs) { Expr h = head; Expr prev = null; if (expand_defs) { Expr prev2 = null; while (h != prev) { prev2 = prev; prev = h; h = h.defExpandOne(ctxt, drop_annos, spec); } if (prev2 != null) prev = prev2; if (h.construct != construct && h.construct != CONST && h.construct != VAR) /* we are trying to keep these constructs in the head. */ h = prev; } if (ctxt.getFlag("debug_spine_form")) { ctxt.w.println("Computing spine form of " + toString(ctxt)); ctxt.w.println("{"); ctxt.w.println("Head expands to " + h.toString(ctxt)); ctxt.w.flush(); } App ret = this; if (h.construct == construct) { TermApp e = (TermApp) ((TermApp) h).spineForm(ctxt, drop_annos, spec, expand_defs); int eXlen = e.X.length; int newlen = X.length + eXlen; Expr[] X2 = new Expr[newlen]; boolean[] specarg2 = new boolean[newlen]; for (int i = 0; i < eXlen; i++) { X2[i] = e.X[i]; specarg2[i] = e.specarg[i]; } for (int i = 0, iend = X.length; i < iend; i++) { X2[i + eXlen] = X[i]; specarg2[i + eXlen] = specarg[i]; } ret = new TermApp(e.head, X2, specarg2); } else if (h != head) ret = new TermApp(h, X, specarg); if (ctxt.getFlag("debug_spine_form")) { ret.print(ctxt.w, ctxt); ctxt.w.println("\n}"); ctxt.w.flush(); } return ret; }
protected void print_arg(java.io.PrintStream w, Context ctxt, int i) { if (ctxt.getFlag("show_spec_args")) if (specarg[i]) w.print("spec "); super.print_arg(w, ctxt, i); }
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); }