21 auto& w =
shape->world();
25 auto r =
shape->num_projs();
26 for (
size_t i = 0, e = r; i != e; ++i) {
27 auto dim =
shape->proj(r, i);
29 if (dim_lit == 1)
continue;
32 index_dims.push_back(index->proj(r, i));
35 assert(dims.size() == index_dims.size());
36 return std::make_tuple(dims.size(), w.tuple(dims), w.tuple(index_dims));
42 auto [arr, index] = arg->
projs<2>();
43 auto callee = c->as<
App>();
44 auto [T, r, s] = callee->args<3>();
46 w.DLOG(
"normalize_get");
47 w.DLOG(
" arr = {} : {}", arr, arr->type());
48 w.DLOG(
" index = {} : {}", index, index->type());
49 w.DLOG(
" T = {} : {}", T, T->type());
50 w.DLOG(
" r = {} : {}", r, r->type());
51 w.DLOG(
" s = {} : {}", s, s->type());
55 w.DLOG(
" new_index = {} : {}", new_index, new_index->type());
56 w.DLOG(
" new_s = {} : {}", new_s, new_s->type());
57 w.DLOG(
" new_r = {} : {}", w.lit_nat(new_r), w.lit_nat(new_r)->type());
58 if (new_r == 0)
return arr;
59 if (new_s != s || new_index != index)
return op_get(T, w.lit_nat(new_r), new_s, arr, new_index);
63 w.DLOG(
"get after set, try to bypass");
65 auto [_, target_index, x] =
set->args<3>();
66 if (target_index == index) {
67 w.DLOG(
"bypass successful");
72 w.DLOG(
"get after get, try to bypass");
74 auto [outer_arr, outer_index] =
get->args<2>();
75 auto [o_T, o_r, o_s] =
get->callee()->as<
App>()->args<3>();
76 w.DLOG(
" outer_arr = {} : {}", outer_arr, outer_arr->
type());
77 w.DLOG(
" outer_index = {} : {}", outer_index, outer_index->type());
78 w.DLOG(
" o_T = {} : {}", o_T, o_T->type());
79 w.DLOG(
" o_r = {} : {}", o_r, o_r->type());
80 w.DLOG(
" o_s = {} : {}", o_s, o_s->type());
86 return op_get(T, new_r, new_s, outer_arr, new_index);
94 w.DLOG(
"get after repeat, try to bypass");
95 auto input = rep->arg();
96 auto [Tr, s_in, s_out] = rep->callee()->as<
App>()->uncurry_args<3>();
99 for (
u64 d = 0; d < *r_l; ++d) {
100 auto in_d = s_in->proj(*r_l, d);
101 auto idx_d = index->proj(*r_l, d);
102 if (in_d == s_out->proj(*r_l, d)) {
103 new_index[d] = idx_d;
105 new_index[d] = w.lit_idx(1, 0);
107 new_index[d] = w.lit_idx(*e, *i % *e);
112 w.DLOG(
"bypass successful");
113 return op_get(T, Tr->proj(2, 1), s_in, input, w.tuple(new_index));
121 w.DLOG(
"get after broadcast, try to bypass");
122 auto [s_in, s_out, input] = bc->args<3>();
123 auto [b_T, b_r] = bc->callee()->as<
App>()->args<2>();
126 for (
u64 d = 0; d < *r_l; ++d) {
127 auto in_d = s_in->proj(*r_l, d);
128 if (in_d == s_out->proj(*r_l, d))
129 new_index[d] = index->proj(*r_l, d);
131 new_index[d] = w.lit_idx(1, 0);
135 w.DLOG(
"bypass successful");
136 return op_get(T, b_r, s_in, input, w.tuple(new_index));
144 auto& w = c->world();
146 auto [arr, index, x] = arg->
projs<3>();
147 w.DLOG(
"normalize_set");
148 w.DLOG(
" arr = {} : {}", arr, arr->type());
149 w.DLOG(
" index = {} : {}", index, index->type());
150 w.DLOG(
" x = {} : {}", x, x->type());
152 auto callee = c->as<
App>();
153 auto [T, r, s] = callee->args<3>();
157 w.DLOG(
" new_index = {} : {}", new_index, new_index->type());
158 w.DLOG(
" new_s = {} : {}", new_s, new_s->type());
159 w.DLOG(
" new_r = {} : {}", w.lit_nat(new_r), w.lit_nat(new_r)->type());
160 if (new_r == 0)
return x;
161 if (new_s != s || new_index != index)
return op_set(T, w.lit_nat(new_r), new_s, arr, new_index, x);
165 w.DLOG(
"set after get, try to bypass");
167 auto [inner_arr, inner_index] =
get->args<2>();
168 if (inner_arr == arr && inner_index == index) {
169 w.DLOG(
"bypass successful");
175 w.DLOG(
"set after set, try to bypass");
176 auto inner_set = x->as<
App>();
177 auto [inner_arr, inner_index, inner_x] = inner_set->args<3>();
178 auto [i_T, i_r, i_s] = inner_set->
callee()->as<
App>()->args<3>();
180 w.DLOG(
" inner_arr = {} : {}", inner_arr, inner_arr->
type());
181 w.DLOG(
" inner_index = {} : {}", inner_index, inner_index->
type());
182 w.DLOG(
" inner_x = {} : {}", inner_x, inner_x->type());
183 w.DLOG(
" i_T = {} : {}", i_T, i_T->type());
184 w.DLOG(
" i_r = {} : {}", i_r, i_r->type());
185 w.DLOG(
" i_s = {} : {}", i_s, i_s->type());
188 auto [g_arr, g_index] = inner_get->args<2>();
189 if (g_arr == arr && g_index == index) {
194 return op_set(i_T, new_r, new_s, arr, new_index, inner_x);
197 w.DLOG(
"set after set bypass not applicable: inner_arr is not get(arr, index)");
199 w.DLOG(
"no normalization applicable");
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.
const Def * op_set(const Def *T, const Def *r, const Def *s, const Def *arr, const Def *index, const Def *x)