MimIR
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* type, 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::views::reverse)
29 acc = w.app(f, {op, acc});
30 return acc;
31 }
32
33 if (auto seq = vec->isa<Seq>()) {
34 if (auto n = Lit::isa<u64>(seq->arity()); n && type->isa<Nat>()) {
35 if constexpr (id == fold::l)
36 for (auto proj : seq->projs(*n)) acc = w.app(f, {acc, proj});
37 else // fold::r
38 for (auto proj : seq->projs(*n) | std::views::reverse) acc = w.app(f, {proj, acc});
39 return acc;
40 }
41 w.WLOG("packs with non-literal arity not yet implemented: {}", seq);
42 }
43
44 if (auto l = vec->isa<Lit>()) {
45 if constexpr (id == fold::l)
46 return w.app(f, {acc, l});
47 else
48 return w.app(f, {l, acc});
49 }
50
51 return nullptr;
52}
53
54const Def* normalize_zip(const Def* type, const Def* c, const Def* arg) {
55 if (arg->is_open()) return {};
56 auto& w = type->world();
57 auto [ni_n, _, f] = App::uncurry_args<3>(c);
58 auto [ni, n] = ni_n->projs<2>([](const Def* def) { return Lit::isa(def); });
59
60 if (!ni || !n) return {};
61 if (ni >= w.flags().scalarize_threshold || n >= w.flags().scalarize_threshold) return {};
62
63 auto res = absl::FixedArray<const Def*>(*n);
64 auto tup = absl::FixedArray<const Def*>(*ni);
65
66 for (size_t j = 0; j != n; ++j) {
67 for (size_t i = 0; i != ni; ++i)
68 tup[i] = arg->proj(*ni, i)->proj(*n, j);
69
70 res[j] = w.app(f, tup);
71 }
72
73 return w.tuple(res);
74}
75
76template<scan id>
77const Def* normalize_scan(const Def*, const Def* c, const Def* vec) {
78 auto& w = c->world();
79 auto callee = c->as<App>();
80 auto p = callee->arg();
81
82 if (auto tuple = vec->isa<Tuple>()) {
83 const Def* acc = w.lit_bool(id != scan::exists);
84 for (auto op : tuple->ops())
85 acc = w.call(id == scan::exists ? core::bit2::or_ : core::bit2::and_, 0_n, Defs{acc, w.app(p, op)});
86 return acc;
87 }
88
89 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
90
91 return nullptr;
92}
93
94const Def* normalize_is_unique(const Def*, const Def*, const Def* vec) {
95 auto& w = vec->world();
96
97 if (auto tuple = vec->isa<Tuple>()) {
98 auto seen = DefSet();
99 for (auto op : tuple->ops()) {
100 auto [_, ins] = seen.emplace(op);
101 if (!ins) return w.lit_ff();
102 }
103 return tuple->is_closed() ? w.lit_tt() : nullptr;
104 }
105
106 if (auto pack = vec->isa_imm<Pack>()) {
107 if (auto l = Lit::isa(pack->arity())) return w.lit_ff();
108 }
109
110 if (vec->isa<Lit>()) return w.lit_tt();
111
112 return nullptr;
113}
114
115const Def* normalize_cat(const Def*, const Def* callee, const Def* arg) {
116 auto [a, b] = arg->projs<2>();
117 auto [n, m] = callee->as<App>()->decurry()->args<2>([](auto def) { return Lit::isa(def); });
118 if (n && *n == 0) return b;
119 if (m && *m == 0) return a;
120 if (n && m) return mim::cat_tuple(*n, *m, a, b);
121 return nullptr;
122}
123
124const Def* normalize_diff(const Def* type, const Def* c, const Def* arg) {
125 if (auto arr = type->isa<Arr>()) {
126 if (arr->arity()->isa<Bot>()) return nullptr; // ack error
127 }
128
129 auto& w = type->world();
130 auto callee = c->as<App>();
131 auto [n, m] = callee->args<2>([](auto def) { return Lit::isa(def); });
132 auto [vec, is] = arg->projs<2>();
133
134 if (!n || !m) return nullptr;
135 if (n == 1 && m == 1) return w.tuple();
136
137 if (auto tup_vec = vec->isa<Tuple>()) {
138 if (auto tup_is = is->isa<Tuple>(); tup_is && tup_is->is_closed()) {
139 auto defs = DefVec();
140 auto set = absl::btree_set<nat_t>();
141 for (auto opi : tup_is->ops())
142 set.emplace(Lit::as(opi));
143
144 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
145 if (!set.contains(i)) defs.emplace_back(tup_vec->op(i));
146 return w.tuple(defs);
147 }
148 if (auto lit_is = Lit::isa(is)) {
149 auto defs = DefVec();
150
151 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
152 if (i != lit_is) defs.emplace_back(tup_vec->op(i));
153 return w.tuple(defs);
154 }
155 }
156
157 if (auto tup_pack = vec->isa_imm<Pack>()) return w.pack(*n - *m, tup_pack->body());
158
159 return nullptr;
160}
161
163
164} // 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:121
Base class for all Defs.
Definition def.h:261
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:635
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:402
bool is_open() const
Has free_vars()?
Definition def.cpp:436
bool is_closed() const
Has no free_vars()?
Definition def.cpp:428
static std::optional< T > isa(const Def *def)
Definition def.h:878
static T as(const Def *def)
Definition def.h:884
A (possibly paramterized) Tuple.
Definition tuple.h:170
Base class for Arr and Pack.
Definition tuple.h:86
Data constructor for a Sigma.
Definition tuple.h:70
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_fold(const Def *type, const Def *c, 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_zip(const Def *type, const Def *c, const Def *arg)
View< const Def * > Defs
Definition def.h:78
Vector< const Def * > DefVec
Definition def.h:79
const Def * cat_tuple(nat_t n, nat_t m, const Def *a, const Def *b)
Definition tuple.cpp:100
GIDSet< const Def * > DefSet
Definition def.h:76
TExt< false > Bot
Definition lattice.h:176
#define MIM_vec_NORMALIZER_IMPL
Definition autogen.h:91