14 auto n = app->num_targs();
15 if (n == 0)
return app;
17 auto [it, _] = lam2info_.emplace(var_lam, std::tuple(
Lattices(n), (
Lam*)
nullptr,
DefVec(n)));
18 auto& [lattice, prop_lam, old_args] = it->second;
21 if (std::ranges::all_of(lattice, [](
auto l) {
return l == Lattice::Keep; }))
return app;
23 DefVec new_args, new_doms, appxy_ops = {var_lam};
24 auto& args =
data(var_lam);
27 for (
size_t i = 0; i != n; ++i) {
29 case Lattice::Dead:
break;
32 world().DLOG(
"found proxy within app: {}@{} - wait till proxy is gone", var_lam, app);
34 }
else if (args[i] ==
nullptr) {
35 args[i] = app->arg(n, i);
36 }
else if (args[i] != app->arg(n, i)) {
37 appxy_ops.emplace_back(
world().lit_nat(i));
39 assert(args[i] == app->arg(n, i));
43 new_doms.emplace_back(var_lam->var(n, i)->type());
44 new_args.emplace_back(app->arg(n, i));
46 default: fe::unreachable();
50 world().DLOG(
"app->args(): {, }", app->args());
51 world().DLOG(
"args: {, }", args);
52 world().DLOG(
"new_args: {, }", new_args);
54 if (appxy_ops.size() > 1) {
55 auto appxy =
proxy(app->type(), appxy_ops, Appxy);
56 world().DLOG(
"appxy: '{}': {, }", appxy, appxy_ops);
60 assert(new_args.size() < n);
61 if (prop_lam ==
nullptr || !std::ranges::equal(old_args, args)) {
64 auto new_pi =
world().
pi(prop_dom, var_lam->codom());
65 prop_lam = var_lam->
stub(new_pi);
67 world().DLOG(
"new prop_lam: {}", prop_lam);
68 if (beta_red_) beta_red_->
keep(prop_lam);
69 if (eta_exp_) eta_exp_->
new2old(prop_lam, var_lam);
72 auto new_vars =
DefVec(n, [&, prop_lam = prop_lam](
size_t i) ->
Ref {
74 case Lattice::Dead:
return proxy(var_lam->var(n, i)->type(), {var_lam, world().lit_nat(i)}, Varxy);
75 case Lattice::Prop:
return args[i];
76 case Lattice::Keep:
return prop_lam->var(j++);
77 default: fe::unreachable();
81 prop_lam->set(var_lam->reduce(
world().tuple(new_vars)));
84 world().DLOG(
"var_lam => prop_lam: {}: {} => {}: {}", var_lam, var_lam->dom(), prop_lam, prop_lam->dom());
85 auto res = app->world().
app(prop_lam, new_args);
89 lam2info_.insert_or_assign(key, std::tuple(
Lattices(new_doms.size(), Lattice::Keep), (
Lam*)
nullptr,
DefVec()));