11 auto codom = lam->
codom();
12 return !codom->isa<
Type>() && !codom->isa<
Pi>();
19 map(old_lam, new_lam);
20 if (!old_lam->
is_set())
return new_lam;
24 auto new_body = wire(scope.base(),
rewrite(old_lam->
body()));
25 return new_lam->set(new_filter, new_body);
28const Def* Conv::convert(
Lam* old_lam) {
30 auto old_pi = old_lam->
type();
31 auto new_dom =
rewrite(old_pi->dom());
34 if (
auto old_var = old_pi->has_var()) {
36 auto sigma = w.mut_sigma(2);
37 sigma->set(0, new_dom);
40 map(old_var, sigma->var(2, 0));
41 auto new_codom =
rewrite(old_pi->codom());
43 sigma->set(1, w.cn(new_codom));
44 new_lam = w.mut_con(sigma);
46 new_lam = w.mut_fun(new_dom,
rewrite(old_pi->codom()));
50 auto [param, ret] = new_lam->
vars<2>();
51 map(old_lam->
var(), param);
54 log().d(
"convert {}: {} → {}: {}", old_lam, old_pi, new_lam, new_lam->
type());
56 auto scope = Scope(*
this,
true);
59 new_lam->
set(new_filter, wire(scope.base(), tail));
69 if (
auto wrapped =
Axm::isa<cps2ds_dep>(new_callee))
return lift(wrapped->arg(), new_arg, old_app);
74const Def* Conv::lift(
const Def* k,
const Def* new_arg,
const App* old_app) {
76 auto cont = w.mut_con(
rewrite(old_app->
type()))->set_filter(
false);
77 auto res = cont->var();
78 cont->set(w.append_suffix(k->
sym(),
"_cont"));
80 pending_.emplace_back(k, new_arg, cont);
82 log().d(
"lift {} → {} ({}, {})", old_app, k, new_arg, cont);
87const Def* Conv::wire(
size_t base,
const Def* body) {
89 while (pending_.size() > base) {
90 auto [callee, arg, cont] = pending_.back();
93 body = w.app(callee,
Defs{arg, cont});
const Def * callee() const
static auto isa(const Def *def)
DbgKey dbg_key() const
Cheap handle for other->set(this->dbg_key()).
const Def * var(nat_t a, nat_t i) noexcept
auto vars(Projector auto f) noexcept
const Def * debug_suffix(std::string) const
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
bool is_external() const noexcept
bool is_annex() const noexcept
const Def * filter() const
static const Lam * isa_cn(const Def *d)
Lam * set(Filter filter, const Def *body)
const Def * codom() const
const fe::Log & log() const
A dependent function type.
World & new_world()
Create new Defs into this.
const Def * map(const Def *old_def, const Def *new_def)
void bind_new(const Var *var)
Adds the new var - if any - to the innermost scope.
virtual const Def * rewrite(const Def *)
void push(Vars old_vars={}, Vars new_vars={})
const Def * app(const Def *callee, const Def *arg)
Lam * mut_lam(const Pi *pi)
const Def * rewrite_mut_Lam(Lam *) final
const Def * rewrite_imm_App(const App *) final
const Def * op_cps2ds_dep(const Def *k)
static bool convertible(Lam *lam)
A term-level, direct-style function that we can and want to convert.
fe::View< const Def * > Defs
fe::Patricia< const Var, DefKey >::Set Vars