MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1#include <absl/container/btree_set.h>
2
4
5#include "mim/tuple.h"
6#include "mim/world.h"
7
8#include "mim/plug/vec/vec.h"
9
10#include "absl/container/fixed_array.h"
11
12namespace mim::plug::vec {
13
14template<fold id>
15const Def* normalize_fold(const Def*, const Def* c, const Def* arg) {
16 auto& w = c->world();
17 auto callee = c->as<App>();
18 auto f = callee->arg();
19
20 auto [acc, vec] = arg->projs<2>();
21 if constexpr (id == fold::r) std::swap(acc, vec);
22
23 if (auto tuple = vec->isa<Tuple>()) {
24 if constexpr (id == fold::l)
25 for (auto op : tuple->ops())
26 acc = w.app(f, {acc, op});
27 else // fold::r
28 for (auto op : tuple->ops() | std::ranges::views::reverse)
29 acc = w.app(f, {op, acc});
30 return acc;
31 }
32
33 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
34
35 if (auto l = vec->isa<Lit>()) {
36 if constexpr (id == fold::l)
37 return w.app(f, {acc, l});
38 else
39 return w.app(f, {l, acc});
40 }
41
42 return nullptr;
43}
44
45const Def* normalize_zip(const Def* type, const Def* c, const Def* arg) {
46 if (arg->is_open()) return {};
47 auto& w = type->world();
48 auto [ni_n, _, f] = App::uncurry_args<3>(c);
49 auto [ni, n] = ni_n->projs<2>([](const Def* def) { return Lit::isa(def); });
50
51 if (!ni || !n) return {};
52 if (ni >= w.flags().scalarize_threshold || n >= w.flags().scalarize_threshold) return {};
53
54 auto res = absl::FixedArray<const Def*>(*n);
55 auto tup = absl::FixedArray<const Def*>(*ni);
56
57 for (size_t j = 0; j != n; ++j) {
58 for (size_t i = 0; i != ni; ++i)
59 tup[i] = arg->proj(*ni, i)->proj(*n, j);
60
61 res[j] = w.app(f, tup);
62 }
63
64 return w.tuple(res);
65}
66
67template<scan id>
68const Def* normalize_scan(const Def*, const Def* c, const Def* vec) {
69 auto& w = c->world();
70 auto callee = c->as<App>();
71 auto p = callee->arg();
72
73 if (auto tuple = vec->isa<Tuple>()) {
74 const Def* acc = w.lit_bool(id != scan::exists);
75 for (auto op : tuple->ops())
76 acc = w.call(id == scan::exists ? core::bit2::or_ : core::bit2::and_, 0_n, Defs{acc, w.app(p, op)});
77 return acc;
78 }
79
80 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
81
82 return nullptr;
83}
84
85const Def* normalize_is_unique(const Def*, const Def*, const Def* vec) {
86 auto& w = vec->world();
87
88 if (auto tuple = vec->isa<Tuple>()) {
89 auto seen = DefSet();
90 for (auto op : tuple->ops()) {
91 auto [_, ins] = seen.emplace(op);
92 if (!ins) return w.lit_ff();
93 }
94 return tuple->is_closed() ? w.lit_tt() : nullptr;
95 }
96
97 if (auto pack = vec->isa_imm<Pack>()) {
98 if (auto l = Lit::isa(pack->arity())) return w.lit_ff();
99 }
100
101 if (vec->isa<Lit>()) return w.lit_tt();
102
103 return nullptr;
104}
105
106const Def* normalize_cat(const Def*, const Def* callee, const Def* arg) {
107 auto [a, b] = arg->projs<2>();
108 auto [n, m] = callee->as<App>()->decurry()->args<2>([](auto def) { return Lit::isa(def); });
109 if (n && *n == 0) return b;
110 if (m && *m == 0) return a;
111 if (n && m) return mim::cat_tuple(*n, *m, a, b);
112 return nullptr;
113}
114
115const Def* normalize_diff(const Def* type, const Def* c, const Def* arg) {
116 if (auto arr = type->isa<Arr>()) {
117 if (arr->arity()->isa<Bot>()) return nullptr; // ack error
118 }
119
120 auto& w = type->world();
121 auto callee = c->as<App>();
122 auto [n, m] = callee->args<2>([](auto def) { return Lit::isa(def); });
123 auto [vec, is] = arg->projs<2>();
124
125 if (!n || !m) return nullptr;
126 if (n == 1 && m == 1) return w.tuple();
127
128 if (auto tup_vec = vec->isa<Tuple>()) {
129 if (auto tup_is = is->isa<Tuple>(); tup_is && tup_is->is_closed()) {
130 auto defs = DefVec();
131 auto set = absl::btree_set<nat_t>();
132 for (auto opi : tup_is->ops())
133 set.emplace(Lit::as(opi));
134
135 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
136 if (!set.contains(i)) defs.emplace_back(tup_vec->op(i));
137 return w.tuple(defs);
138 }
139 if (auto lit_is = Lit::isa(is)) {
140 auto defs = DefVec();
141
142 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
143 if (i != lit_is) defs.emplace_back(tup_vec->op(i));
144 return w.tuple(defs);
145 }
146 }
147
148 if (auto tup_pack = vec->isa_imm<Pack>()) return w.pack(*n - *m, tup_pack->body());
149
150 return nullptr;
151}
152
154
155} // namespace mim::plug::vec
auto uncurry_args() const
Definition lam.h:330
const Def * arg() const
Definition lam.h:285
A (possibly paramterized) Array.
Definition tuple.h:117
Base class for all Defs.
Definition def.h:251
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.
Definition def.cpp:587
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:390
bool is_open() const
Has free_vars()?
Definition def.cpp:425
bool is_closed() const
Has no free_vars()?
Definition def.cpp:417
static std::optional< T > isa(const Def *def)
Definition def.h:826
static T as(const Def *def)
Definition def.h:832
A (possibly paramterized) Tuple.
Definition tuple.h:166
Data constructor for a Sigma.
Definition tuple.h:68
The tuple Plugin
The vec Plugin
const Def * normalize_scan(const Def *, const Def *c, const Def *vec)
const Def * normalize_cat(const Def *, const Def *callee, const Def *arg)
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)
const Def * normalize_zip(const Def *type, const Def *c, const Def *arg)
View< const Def * > Defs
Definition def.h:76
Vector< const Def * > DefVec
Definition def.h:77
const Def * cat_tuple(nat_t n, nat_t m, const Def *a, const Def *b)
Definition tuple.cpp:156
GIDSet< const Def * > DefSet
Definition def.h:74
TExt< false > Bot
Definition lattice.h:171
#define MIM_vec_NORMALIZER_IMPL
Definition autogen.h:91