MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1#include <mim/tuple.h>
2#include <mim/world.h>
3
5
6namespace mim::plug::tuple {
7
8const Def* normalize_cat(const Def*, const Def* callee, const Def* arg) {
9 auto [a, b] = arg->projs<2>();
10 auto [n, m] = callee->as<App>()->decurry()->args<2>([](auto def) { return Lit::isa(def); });
11 if (n && *n == 0) return b;
12 if (m && *m == 0) return a;
13 return n && m ? Tuple::cat(*n, *m, a, b) : nullptr;
14}
15
16const Def* normalize_contains(const Def* type, const Def*, const Def* arg) {
17 auto& w = type->world();
18 auto [xs, x] = arg->projs<2>();
19
20 if (auto mut_pack = xs->isa_mut<Pack>()) {
21 if (auto imm = mut_pack->immutabilize())
22 xs = imm;
23 else
24 return nullptr;
25 }
26
27 // FIXME for n = 1, xs is the element itself; and a closed xs doesn't rule out an open x at runtime.
28 if (auto tuple = xs->isa<Tuple>()) {
29 for (auto op : tuple->ops())
30 if (op == x) return w.lit_tt();
31
32 return tuple->is_closed() ? w.lit_ff() : nullptr;
33 }
34
35 if (auto pack = xs->isa<Pack>()) {
36 if (pack->body() == x) return w.lit_tt();
37 return pack->is_closed() ? w.lit_ff() : nullptr;
38 }
39
40 return nullptr;
41}
42
43const Def* normalize_zip(const Def* type, const Def* c, const Def* arg) {
44 auto& w = type->world();
45 auto callee = c->as<App>();
46 auto is_os = callee->arg();
47 auto [n_i, Is, n_o, Os, f] = is_os->projs<5>();
48 auto [r, s] = callee->decurry()->args<2>();
49 auto lr = Lit::isa(r);
50 auto ls = Lit::isa(s);
51
52 // TODO commute
53 // TODO reassociate
54 // TODO select which Is/Os to zip
55
56 if (lr && ls && *lr == 1 && *ls == 1) return w.app(f, arg);
57
58 if (auto l_in = Lit::isa(n_i), l_o = Lit::isa(n_o); l_in && l_o) {
59 auto args = arg->projs(*l_in);
60
61 if (lr && std::ranges::all_of(args, [](const Def* arg) { return arg->isa<Prod>(); })) {
62 auto shapes = s->projs(*lr);
63 auto s_n = Lit::isa(shapes.front());
64
65 if (s_n) {
66 auto elems = DefVec(*s_n, [&, f = f](size_t s_i) {
67 auto inner_args = DefVec(args.size(), [&](size_t i) { return args[i]->proj(*s_n, s_i); });
68 if (*lr == 1) {
69 return w.app(f, inner_args);
70 } else {
71 auto app_zip = w.app(w.annex<zip>(), {w.lit_nat(*lr - 1), w.tuple(shapes.view().subspan(1))});
72 return w.app(w.app(app_zip, is_os), inner_args);
73 }
74 });
75 return w.tuple(DefVec(*l_o, [&](size_t o) {
76 return w.tuple(DefVec(*s_n, [&](size_t s_i) { return elems[s_i]->proj(*l_o, o); }));
77 }));
78 }
79 }
80 }
81
82 return {};
83}
84
86
87} // namespace mim::plug::tuple
auto args(Projector auto f) const noexcept
Definition lam.h:252
const Def * arg() const
Definition lam.h:251
Base class for all Defs.
Definition def.h:289
auto projs(Projector auto f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition def.h:457
static std::optional< T > isa(const Def *def)
Definition def.h:976
A (possibly paramterized) Tuple.
Definition tuple.h:332
Base class for Sigma and Tuple.
Definition tuple.h:13
Data constructor for a Sigma.
Definition tuple.h:84
static const Def * cat(nat_t n, nat_t m, const Def *a, const Def *b)
Definition tuple.h:92
The tuple Plugin
const Def * normalize_cat(const Def *, const Def *callee, const Def *arg)
const Def * normalize_zip(const Def *type, const Def *c, const Def *arg)
const Def * normalize_contains(const Def *type, const Def *, const Def *arg)
fe::Vector< const Def * > DefVec
Definition def.h:98
#define MIM_tuple_NORMALIZER_IMPL
Definition autogen.h:73