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
10namespace mim::plug::vec {
11
12template<fold id>
13const Def* normalize_fold(const Def*, const Def* c, const Def* arg) {
14 auto& w = c->world();
15 auto callee = c->as<App>();
16 auto f = callee->arg();
17
18 auto [acc, vec] = arg->projs<2>();
19 if constexpr (id == fold::r) std::swap(acc, vec);
20
21 if (auto tuple = vec->isa<Tuple>()) {
22 if constexpr (id == fold::l)
23 for (auto op : tuple->ops())
24 acc = w.app(f, {acc, op});
25 else // fold::r
26 for (auto op : tuple->ops() | std::ranges::views::reverse)
27 acc = w.app(f, {op, acc});
28 return acc;
29 }
30
31 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
32
33 if (auto l = vec->isa<Lit>()) {
34 if constexpr (id == fold::l)
35 return w.app(f, {acc, l});
36 else
37 return w.app(f, {l, acc});
38 }
39
40 return nullptr;
41}
42
43template<scan id>
44const Def* normalize_scan(const Def*, const Def* c, const Def* vec) {
45 auto& w = c->world();
46 auto callee = c->as<App>();
47 auto p = callee->arg();
48
49 if (auto tuple = vec->isa<Tuple>()) {
50 const Def* acc = w.lit_bool(id != scan::exists);
51 for (auto op : tuple->ops())
52 acc = w.call(id == scan::exists ? core::bit2::or_ : core::bit2::and_, 0_n, Defs{acc, w.app(p, op)});
53 return acc;
54 }
55
56 if (auto pack = vec->isa_imm<Pack>()) w.WLOG("packs not yet implemented: {}", pack);
57
58 return nullptr;
59}
60
61const Def* normalize_is_unique(const Def*, const Def*, const Def* vec) {
62 auto& w = vec->world();
63
64 if (auto tuple = vec->isa<Tuple>()) {
65 auto seen = DefSet();
66 for (auto op : tuple->ops()) {
67 auto [_, ins] = seen.emplace(op);
68 if (!ins) return w.lit_ff();
69 }
70 return tuple->is_closed() ? w.lit_tt() : nullptr;
71 }
72
73 if (auto pack = vec->isa_imm<Pack>()) {
74 if (auto l = Lit::isa(pack->arity())) return w.lit_ff();
75 }
76
77 if (vec->isa<Lit>()) return w.lit_tt();
78
79 return nullptr;
80}
81
82const Def* normalize_cat(const Def*, const Def* callee, const Def* arg) {
83 auto [a, b] = arg->projs<2>();
84 auto [n, m] = callee->as<App>()->decurry()->args<2>([](auto def) { return Lit::isa(def); });
85 if (n && *n == 0) return b;
86 if (m && *m == 0) return a;
87 if (n && m) return mim::cat_tuple(*n, *m, a, b);
88 return nullptr;
89}
90
91const Def* normalize_diff(const Def* type, const Def* c, const Def* arg) {
92 if (auto arr = type->isa<Arr>()) {
93 if (arr->arity()->isa<Bot>()) return nullptr; // ack error
94 }
95
96 auto& w = type->world();
97 auto callee = c->as<App>();
98 auto [n, m] = callee->args<2>([](auto def) { return Lit::isa(def); });
99 auto [vec, is] = arg->projs<2>();
100
101 if (!n || !m) return nullptr;
102 if (n == 1 && m == 1) return w.tuple();
103
104 if (auto tup_vec = vec->isa<Tuple>()) {
105 if (auto tup_is = is->isa<Tuple>(); tup_is && tup_is->is_closed()) {
106 auto defs = DefVec();
107 auto set = absl::btree_set<nat_t>();
108 for (auto opi : tup_is->ops())
109 set.emplace(Lit::as(opi));
110
111 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
112 if (!set.contains(i)) defs.emplace_back(tup_vec->op(i));
113 return w.tuple(defs);
114 }
115 if (auto lit_is = Lit::isa(is)) {
116 auto defs = DefVec();
117
118 for (size_t i = 0, e = tup_vec->num_ops(); i != e; ++i)
119 if (i != lit_is) defs.emplace_back(tup_vec->op(i));
120 return w.tuple(defs);
121 }
122 }
123
124 if (auto tup_pack = vec->isa_imm<Pack>()) return w.pack(*n - *m, tup_pack->body());
125
126 return nullptr;
127}
128
130
131} // namespace mim::plug::vec
const Def * arg() const
Definition lam.h:286
A (possibly paramterized) Array.
Definition tuple.h:117
Base class for all Defs.
Definition def.h:251
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_closed() const
Has no free_vars()?
Definition def.cpp:415
static std::optional< T > isa(const Def *def)
Definition def.h:824
static T as(const Def *def)
Definition def.h:830
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)
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:149
GIDSet< const Def * > DefSet
Definition def.h:74
TExt< false > Bot
Definition lattice.h:171
#define MIM_vec_NORMALIZER_IMPL
Definition autogen.h:83