term* normalize_fuel_elim(context *Sigma, typing_context* Delta, term* t, int fuel) { term* ans = NULL; term* last = normalize_fuel(Sigma, Delta, t->args[t->num_args - 1], fuel-1); if (!last) goto error; if (last->tag == INTRO) { term* c = term_dup(t); free_term(c->args[c->num_args - 1]); c->args[c->num_args - 1] = last; return normalize_and_free_fuel(Sigma, Delta, elim_over_intro(Delta, c), fuel-1); } else { ans = make_elim(variable_dup(t->var), t->num_args, t->num_params, t->num_indices); int i; for (i = 0; i < t->num_indices; i++) { ans->indices[i] = normalize_fuel(Sigma, Delta, t->indices[i], fuel-1); if (!ans->indices[i]) goto error; } for (i = 0; i < t->num_params; i++) { ans->params[i] = normalize_fuel(Sigma, Delta, t->params[i], fuel-1); if (!ans->params[i]) goto error; } for (i = 0; i < t->num_args - 1; i++) { ans->args[i] = normalize_fuel(Sigma, Delta, t->args[i], fuel-1); if (!ans->args[i]) goto error; } ans->args[t->num_args-1] = last; return ans; } error: free_term(last); free_term(ans); return NULL; }
term* normalize_fuel_datatype(context *Sigma, typing_context* Delta, term* t, int fuel) { term* ans = make_datatype_term(variable_dup(t->var), t->num_params, t->num_indices); int i; for (i = 0; i < t->num_params; i++) { ans->params[i] = normalize_fuel(Sigma, Delta, t->params[i], fuel-1); } for (i = 0; i < t->num_indices; i++) { ans->indices[i] = normalize_fuel(Sigma, Delta, t->indices[i], fuel-1); } return ans; }
term* normalize_fuel_pi(context *Sigma, typing_context* Delta, term* t, int fuel) { term* B = NULL; term* A = normalize_fuel(Sigma, Delta, t->left, fuel-1); if (!A) goto error; context* extend = context_add(variable_dup(t->var), NULL, Sigma); B = normalize_fuel(extend, Delta, t->right, fuel-1); context_pop(extend); if (!B) goto error; return make_pi(variable_dup(t->var), A, B); error: free_term(A); free_term(B); return NULL; }
term* normalize_fuel_lambda(context *Sigma, typing_context* Delta, term* t, int fuel) { term* b = NULL; term* A = normalize_fuel(Sigma, Delta, t->left, fuel-1); context* extend = context_add(variable_dup(t->var), NULL, Sigma); b = normalize_fuel(extend, Delta, t->right, fuel-1); context_pop(extend); if (!b) goto error; return make_lambda(variable_dup(t->var), A, b); error: free_term(A); free_term(b); return NULL; }
term* normalize_fuel_var(context *Sigma, typing_context* Delta, term* t, int fuel) { term* defn = context_lookup(t->var, Sigma); if (defn == NULL) { return term_dup(t); } return normalize_fuel(Sigma, Delta, defn, fuel-1); }
term* normalize_fuel_intro(context *Sigma, typing_context* Delta, term* t, int fuel) { term* ans = make_intro(variable_dup(t->var), term_dup(t->left), t->num_args, t->num_params); int i; for (i = 0; i < t->num_params; i++) { ans->params[i] = normalize_fuel(Sigma, Delta, t->params[i], fuel-1); } for (i = 0; i < t->num_args; i++) { // FIXME: this leaks on error --jrw ans->args[i] = normalize_fuel(Sigma, Delta, t->args[i], fuel-1); if (!ans->args[i]) goto error; } return ans; error: free_term(ans); return NULL; }
static term* normalize_fuel_app(context *Sigma, typing_context* Delta, term* t, int fuel) { term *f = normalize_fuel(Sigma, Delta, t->left, fuel-1); term *x = normalize_fuel(Sigma, Delta, t->right, fuel-1); if (!f || !x) goto error; if (f->tag == LAM) { term* subs = substitute(f->var, x, f->right); free_term(f); free_term(x); term* ans = normalize_fuel(Sigma, Delta, subs, fuel-1); free_term(subs); return ans; } return make_app(f, x); error: free_term(f); free_term(x); return NULL; }
term* normalize(context *Sigma, typing_context* Delta, term* t) { return normalize_fuel(Sigma, Delta, t, FUEL); }
static term* normalize_and_free_fuel(context *Sigma, typing_context* Delta, term* t, int fuel) { term* ans = normalize_fuel(Sigma, Delta, t, fuel); free_term(t); return ans; }