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