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