MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
2
3#include "mim/world.h"
4
5#include "mim/plug/vec/vec.h"
6
7namespace mim::plug::vec {
8
9template<fold id> const Def* normalize_fold(const Def*, const Def* c, const Def* arg) {
10 auto& w = c->world();
11 auto callee = c->as<App>();
12 auto f = callee->arg();
13
14 auto [acc, vec] = arg->projs<2>();
15 if constexpr (id == fold::r) std::swap(acc, vec);
16
17 if (auto tuple = vec->isa<Tuple>()) {
18 if constexpr (id == fold::l)
19 for (auto op : tuple->ops()) acc = w.app(f, {acc, op});
20 else // fold::r
21 for (auto op : tuple->ops() | std::ranges::views::reverse) acc = w.app(f, {op, acc});
22 return acc;
23 }
24
25 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
26
27 return nullptr;
28}
29
30template<scan id> const Def* normalize_scan(const Def*, const Def* c, const Def* vec) {
31 auto& w = c->world();
32 auto callee = c->as<App>();
33 auto p = callee->arg();
34
35 if (auto tuple = vec->isa<Tuple>()) {
36 const Def* acc = w.lit_bool(id != scan::exists);
37 for (auto op : tuple->ops())
38 acc = w.call(id == scan::exists ? core::bit2::or_ : core::bit2::and_, 0_n, Defs{acc, w.app(p, op)});
39 return acc;
40 }
41
42 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
43
44 return nullptr;
45}
46
47const Def* normalize_is_unique(const Def*, const Def*, const Def* vec) {
48 auto& w = vec->world();
49
50 if (auto tuple = vec->isa<Tuple>()) {
51 auto seen = DefSet();
52 for (auto op : tuple->ops()) {
53 auto [_, ins] = seen.emplace(op);
54 if (!ins) return w.lit_ff();
55 }
56 return tuple->is_closed() ? w.lit_tt() : nullptr;
57 }
58
59 if (auto pack = vec->isa_imm<Pack>()) {
60 if (auto l = Lit::isa(pack->shape())) return w.lit_ff();
61 }
62
63 return nullptr;
64}
65
66const Def* normalize_diff(const Def* type, const Def* c, const Def* arg) {
67 if (type->as<Arr>()->shape()->isa<Bot>()) return nullptr; // ack error
68
69 auto& w = type->world();
70 auto callee = c->as<App>();
71 auto [n, m] = callee->args<2>([](auto def) { return Lit::isa(def); });
72 auto [vec, is] = arg->projs<2>();
73
74 if (!n || !m) return nullptr;
75 if (n == 1 && m == 1) return w.tuple();
76
77 if (auto tup_vec = vec->isa<Tuple>()) {
78 if (auto tup_is = is->isa<Tuple>(); tup_is && tup_is->is_closed()) {
79 auto defs = DefVec();
80 auto set = absl::btree_set<nat_t>();
81 for (auto opi : tup_is->ops()) set.emplace(Lit::as(opi));
82
83 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
84 if (!set.contains(i)) defs.emplace_back(tup_vec->op(i));
85 return w.tuple(defs);
86 }
87 }
88
89 if (auto tup_pack = vec->isa_imm<Pack>()) return w.pack(*n - *m, tup_pack->body());
90
91 return nullptr;
92}
93
95
96} // namespace mim::plug::vec
const Def * arg() const
Definition lam.h:230
A (possibly paramterized) Array.
Definition tuple.h:74
const Def * shape() const
Definition tuple.h:84
Base class for all Defs.
Definition def.h:198
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition def.h:345
bool is_closed() const
Has no free_vars()?
Definition def.cpp:366
static std::optional< T > isa(const Def *def)
Definition def.h:713
static T as(const Def *def)
Definition def.h:718
A (possibly paramterized) Tuple.
Definition tuple.h:122
Data constructor for a Sigma.
Definition tuple.h:56
The tuple Plugin
The vec Plugin
const Def * normalize_scan(const Def *, const Def *c, const Def *vec)
const Def * normalize_is_unique(const Def *, const Def *, const Def *vec)
const Def * normalize_diff(const Def *type, const Def *c, const Def *arg)
const Def * normalize_fold(const Def *, const Def *c, const Def *arg)
View< const Def * > Defs
Definition def.h:49
Vector< const Def * > DefVec
Definition def.h:50
GIDSet< const Def * > DefSet
Definition def.h:47
TExt< false > Bot
Definition lattice.h:158
#define MIM_vec_NORMALIZER_IMPL
Definition autogen.h:54