20 auto& w = shape->world();
24 auto r = shape->num_projs();
25 for (
size_t i = 0, e = r; i != e; ++i) {
26 auto dim = shape->proj(r, i);
28 if (dim_lit == 1)
continue;
31 index_dims.push_back(index->proj(r, i));
34 assert(dims.size() == index_dims.size());
35 return std::make_tuple(dims.size(), w.tuple(dims), w.tuple(index_dims));
41 auto [arr, index] = arg->
projs<2>();
42 auto callee = c->as<
App>();
43 auto [T, r, s] = callee->args<3>();
45 w.DLOG(
"normalize_get");
46 w.DLOG(
" arr = {} : {}", arr, arr->type());
47 w.DLOG(
" index = {} : {}", index, index->type());
48 w.DLOG(
" T = {} : {}", T, T->
type());
49 w.DLOG(
" r = {} : {}", r, r->type());
50 w.DLOG(
" s = {} : {}", s, s->type());
54 w.DLOG(
" new_index = {} : {}", new_index, new_index->type());
55 w.DLOG(
" new_s = {} : {}", new_s, new_s->type());
56 w.DLOG(
" new_r = {} : {}", w.lit_nat(new_r), w.lit_nat(new_r)->type());
57 if (new_r == 0)
return arr;
58 if (new_s != s || new_index != index)
return op_get(T, w.lit_nat(new_r), new_s, arr, new_index);
62 w.DLOG(
"get after set, try to bypass");
64 auto [_, target_index, x] =
set->args<3>();
65 if (target_index == index) {
66 w.DLOG(
"bypass successful");
71 w.DLOG(
"get after get, try to bypass");
73 auto [outer_arr, outer_index] =
get->args<2>();
74 auto [o_T, o_r, o_s] =
get->callee()->as<
App>()->args<3>();
75 w.DLOG(
" outer_arr = {} : {}", outer_arr, outer_arr->
type());
76 w.DLOG(
" outer_index = {} : {}", outer_index, outer_index->type());
77 w.DLOG(
" o_T = {} : {}", o_T, o_T->type());
78 w.DLOG(
" o_r = {} : {}", o_r, o_r->type());
79 w.DLOG(
" o_s = {} : {}", o_s, o_s->type());
85 return op_get(T, new_r, new_s, outer_arr, new_index);
94 auto [arr, index, x] = arg->
projs<3>();
95 w.DLOG(
"normalize_set");
96 w.DLOG(
" arr = {} : {}", arr, arr->type());
97 w.DLOG(
" index = {} : {}", index, index->type());
98 w.DLOG(
" x = {} : {}", x, x->type());
100 auto callee = c->as<
App>();
101 auto [T, r, s] = callee->args<3>();
105 w.DLOG(
" new_index = {} : {}", new_index, new_index->type());
106 w.DLOG(
" new_s = {} : {}", new_s, new_s->type());
107 w.DLOG(
" new_r = {} : {}", w.lit_nat(new_r), w.lit_nat(new_r)->type());
108 if (new_r == 0)
return x;
109 if (new_s != s || new_index != index)
return op_set(T, w.lit_nat(new_r), new_s, arr, new_index, x);
113 w.DLOG(
"set after get, try to bypass");
115 auto [inner_arr, inner_index] =
get->args<2>();
116 if (inner_arr == arr && inner_index == index) {
117 w.DLOG(
"bypass successful");
123 w.DLOG(
"set after set, try to bypass");
124 auto inner_set = x->as<
App>();
125 auto [inner_arr, inner_index, inner_x] = inner_set->args<3>();
126 auto [i_T, i_r, i_s] = inner_set->
callee()->as<
App>()->args<3>();
128 w.DLOG(
" inner_arr = {} : {}", inner_arr, inner_arr->
type());
129 w.DLOG(
" inner_index = {} : {}", inner_index, inner_index->
type());
130 w.DLOG(
" inner_x = {} : {}", inner_x, inner_x->type());
131 w.DLOG(
" i_T = {} : {}", i_T, i_T->type());
132 w.DLOG(
" i_r = {} : {}", i_r, i_r->type());
133 w.DLOG(
" i_s = {} : {}", i_s, i_s->type());
136 auto [g_arr, g_index] = inner_get->args<2>();
137 if (g_arr == arr && g_index == index) {
142 return op_set(i_T, new_r, new_s, arr, new_index, inner_x);
145 w.DLOG(
"set after set bypass not applicable: inner_arr is not get(arr, index)");
147 w.DLOG(
"no normalization applicable");
const Def * op_set(const Def *T, const Def *r, const Def *s, const Def *arr, const Def *index, const Def *x)