11 auto codom = lam->
codom();
12 return !codom->isa<
Type>() && !codom->isa<
Pi>();
17 return old2new[old_def] = new_def;
24 map(old_lam, new_lam);
25 if (!old_lam->
is_set())
return new_lam;
29 auto new_body = wire(scope.base(),
rewrite(old_lam->
body()));
30 return new_lam->set(new_filter, new_body);
33const Def* Conv::convert(
Lam* old_lam) {
35 auto old_pi = old_lam->
type();
36 auto new_dom =
rewrite(old_pi->dom());
39 if (
auto old_var = old_pi->has_var()) {
41 auto sigma = w.mut_sigma(2);
43 scoped_ = w.vars().insert(scoped_, sigma->has_var());
45 map(old_var, sigma->var(2, 0));
46 auto new_codom =
rewrite(old_pi->codom());
48 sigma->set(0, new_dom);
49 sigma->set(1, w.cn(new_codom));
50 new_lam = w.mut_con(sigma);
52 new_lam = w.mut_fun(new_dom,
rewrite(old_pi->codom()));
56 auto [param, ret] = new_lam->
vars<2>();
57 map(old_lam->
var(), param);
60 DLOG(
"convert {}: {} ↝ {}: {}", old_lam, old_pi, new_lam, new_lam->
type());
62 auto scope = Scope(*
this,
true);
65 new_lam->
set(new_filter, wire(scope.base(), tail));
75 if (
auto wrapped =
Axm::isa<cps2ds_dep>(new_callee))
return lift(wrapped->arg(), new_arg, old_app);
80const Def* Conv::lift(
const Def* k,
const Def* new_arg,
const App* old_app) {
82 auto cont = w.mut_con(
rewrite(old_app->
type()))->set_filter(
false);
83 auto res = cont->var();
84 cont->set(w.append_suffix(k->
sym(),
"_cont"));
85 scoped_ = w.vars().insert(scoped_, cont->has_var());
86 pending_.emplace_back(k, new_arg, cont);
88 DLOG(
"lift {} ↝ {} ({}, {})", old_app, k, new_arg, cont);
93const Def* Conv::wire(
size_t base,
const Def* body) {
95 while (pending_.size() > base) {
96 auto [callee, arg, cont] = pending_.back();
99 body = w.app(callee, w.tuple({arg, cont}));
const Def * callee() const
static auto isa(const Def *def)
bool is_set() const
Yields true if empty or the last op is set.
const Def * var(nat_t a, nat_t i) 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
Vars free_vars() const
Global set of free Vars: extends local_vars() by transitively following mutables as well.
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
A dependent function type.
World & new_world()
Create new Defs into this.
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
std::deque< Def2Def > old2news_
virtual const Def * rewrite(const Def *)
bool has_intersection(Set other) const noexcept
Is ?.
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 * map(const Def *, const Def *) final
#define DLOG(...)
Vaporizes to nothingness in Debug build.
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.