37 const std::unordered_map<std::string,
dimension<T>>& global_parameters
39 std::unordered_set<std::shared_ptr<dimension_impl<T>>> deps{};
43 for (
const auto& param: head->expr().
parameters()) {
44 if (head->context_->contains(param.name)) {
45 auto& param_dim = head->context_->operator[](param.name);
46 deps.insert(param_dim.impl());
47 }
else if (global_parameters.contains(param.name)) {
48 auto& param_dim = global_parameters.at(param.name);
49 deps.insert(param_dim.impl());
51 LOG::print{FATAL}(
"Missing expression parameter: {}", param.name);
55 for (
const auto& dependency: deps) {
56 if (dependency == start) {
60 if (
find_cycle(cycle, start, dependency, global_parameters)) {
72 const std::unordered_map<std::string,
dimension<T>>& parameters
77 std::deque<typename expression::node_t::sptr> stack{};
78 std::stack<std::pair<typename expression::node_t::sptr, std::deque<T>>> result_stack{};
79 stack.emplace_back(expr.
tree());
85 while (!stack.empty()) {
86 auto top = stack.back();
88 result_stack.top().second.push_back(T{});
95 result_stack.top().second.push_back(top->const_value);
99 result_stack.top().second.push_back(top->dimension->value_);
103 if (dim->context_->contains(top->parameter.name)) {
104 auto& d = (*dim->context_)[top->parameter.name];
105 result_stack.top().second.push_back((*dim->context_)[top->parameter.name].value());
107 }
else if (parameters.contains(top->parameter.name)) {
108 result_stack.top().second.push_back(parameters.at(top->parameter.name).value());
112 }(
"Missing parameter while evaluating expression: {}", top->parameter.name);
120 if (result_stack.top().first != top) {
121 result_stack.emplace(top, std::deque<T>{});
122 for (
auto it = top->children.rbegin(); it != top->children.rend(); ++it) {
123 stack.emplace_back(*it);
126 auto res = result_stack.top().second;
127 T accumulator{res.front()};
130 for (
auto it = std::next(res.begin()); it != res.end(); ++it) {
131 accumulator.value += (*it).template as<screen::pixel>().value;
135 for (
auto it = std::next(res.begin()); it != res.end(); ++it) {
136 accumulator.value -= (*it).template as<screen::pixel>().value;
140 for (
auto it = std::next(res.begin()); it != res.end(); ++it) {
141 accumulator.value *= (*it).template as<screen::pixel>().value;
145 for (
auto it = std::next(res.begin()); it != res.end(); ++it) {
146 accumulator.value /= (*it).template as<screen::pixel>().value;
153 result_stack.top().second.push_back(accumulator);
159 (
"Expression node has invalid operator {}",
static_cast<std::size_t
>(top->op));
164 if (result_stack.size() == 1 && result_stack.top().first ==
nullptr
165 && result_stack.top().second.size() == 1) {
166 dim->value_ = result_stack.top().second.front();
167 dim->unknown_ =
false;
171 }(
"Something went wrong while evaluating an expression, result_stack invalid: {}",
181 std::unordered_set<typename dimension_impl<T>::sptr> visited{};
182 std::deque<typename dimension_impl<T>::sptr> stack{};
183 std::vector<cycle_t<T>> cycles{};
184 stack.emplace_back(dim);
186 while (!stack.empty()) {
187 auto top = stack.back();
189 if (not top->is_unknown()) {
195 std::unordered_set<std::shared_ptr<dimension_impl<T>>> deps{};
197 for (
const auto& dep: top->expr().dependencies()) {
200 for (
const auto& param: top->expr().parameters()) {
201 if (top->context_->contains(param.name)) {
202 auto& param_dim = top->context_->operator[](param.name);
203 deps.insert(param_dim.impl());
204 }
else if (parameters.contains(param.name)) {
205 auto& param_dim = parameters.at(param.name);
206 deps.insert(param_dim.impl());
208 LOG::print{FATAL}(
"Missing expression parameter: {}", param.name);
213 if (top->is_unknown()) {
219 bool work_to_do =
false;
221 for (
auto it = deps.begin(); it != deps.end(); ++it) {
223 if (not dep->is_unknown())
225 if (visited.contains(dep)) {
235 if (!
find_cycle(cycle, dep, dep, parameters)) {
236 LOG::print{FATAL}(
"Cycle detection gave a false positive.");
238 LOG::print{ERROR}(
"Dependency cycle in dimensions:");
240 for (
const auto& v: cycle.dimensions) {
241 LOG::print{ERROR}(
" {}: {}::{} = {}", i++, v->context_->get_name(), v->name_, v->expr().to_string());
244 cycles.emplace_back(cycle);
246 stack.emplace_back(dep);
252 if (top->is_unknown()) {
bool find_cycle(cycle_t< T > &cycle, typename dimension_impl< T >::sptr start, typename dimension_impl< T >::sptr head, const std::unordered_map< std::string, dimension< T > > &global_parameters)