@@ -158,177 +158,3 @@ void Formula::collectEntries(const Expression& e, Formula& target) {
158158 collectEntries (*c, target);
159159 }
160160}
161-
162- void Formula::resolveIdentities () {
163- auto copy = entries;
164- for (auto & e : copy) {
165- if (ExpressionUtil::isSimpleFunction (e.first ) &&
166- ExpressionUtil::isSimpleFunction (e.second ) &&
167- copy.find (e.second ) != copy.end ()) {
168- entries.erase (e.first );
169- replaceName (e.second .name , e.first .name );
170- }
171- }
172- }
173-
174- void replaceFunction (Expression& target, const std::string& func,
175- const Expression& param, const Expression& val) {
176- // bottom-up
177- for (const auto & c : target.children ) {
178- replaceFunction (*c, func, param, val);
179- }
180- ExpressionUtil::normalize (target);
181- if (target.type != Expression::Type::FUNCTION ||
182- target.children .size () != 1 || target.name != func) {
183- return ;
184- }
185- auto updated = val;
186- updated.replaceAll (param, *target.children .front ());
187- ExpressionUtil::normalize (updated);
188- target = updated;
189- }
190-
191- void Formula::resolveSimpleFunctions () {
192- // collect function definitions
193- std::set<std::string> simple_funcs;
194- std::map<std::string, Expression> params, defs;
195- for (auto & e : entries) {
196- if (ExpressionUtil::isSimpleFunction (e.first )) {
197- simple_funcs.insert (e.first .name );
198- params[e.first .name ] = *e.first .children .front ();
199- defs[e.first .name ] = e.second ;
200- }
201- }
202- // filter out non-simple functions
203- auto deps = getFunctionDeps (false , false );
204- for (auto & e : entries) {
205- if (e.first .type != Expression::Type::FUNCTION) {
206- continue ; // should not happen
207- }
208- auto f = e.first .name ;
209- bool is_simple = true ;
210- if (!ExpressionUtil::isSimpleFunction (e.first )) {
211- is_simple = false ;
212- }
213- for (auto it : deps) {
214- if (it.first == f && containsFunctionDef (it.second )) {
215- is_simple = false ;
216- break ;
217- }
218- }
219- if (!is_simple) {
220- simple_funcs.erase (e.first .name );
221- }
222- }
223- // perform replacements
224- for (const auto & f : simple_funcs) {
225- for (auto & e : entries) {
226- replaceFunction (e.second , f, params[f], defs[f]);
227- }
228- }
229- }
230-
231- void Formula::resolveSimpleRecursions () {
232- // collect functions
233- std::set<std::string> funcs;
234- for (auto & e : entries) {
235- if (ExpressionUtil::isSimpleFunction (e.first )) {
236- funcs.insert (e.first .name );
237- }
238- }
239- // collect and check their slopes and offsets
240- std::map<std::string, Number> slopes, offsets;
241- std::map<std::string, Expression> params;
242- std::map<Number, Number> constants;
243- for (auto & f : funcs) {
244- constants.clear ();
245- bool found_slope = false ;
246- Number slope = 0 ;
247- for (auto & e : entries) {
248- if (e.first .type != Expression::Type::FUNCTION) {
249- continue ;
250- }
251- if (e.first .name != f) {
252- continue ;
253- }
254- auto arg_type = e.first .children .front ()->type ;
255- if (arg_type == Expression::Type::CONSTANT) {
256- if (e.second .type != Expression::Type::CONSTANT) {
257- constants.clear ();
258- break ;
259- }
260- constants[e.first .children .front ()->value ] = e.second .value ;
261- } else if (arg_type == Expression::Type::PARAMETER) {
262- params[f] = *e.first .children .front ();
263- auto val = e.second ;
264- if (val.type != Expression::Type::SUM) {
265- found_slope = false ;
266- break ;
267- }
268- if (val.children .size () != 2 ) {
269- found_slope = false ;
270- break ;
271- }
272- if (val.children .at (1 )->type != Expression::Type::CONSTANT) {
273- found_slope = false ;
274- break ;
275- }
276- Expression predecessor (
277- Expression::Type::SUM, " " ,
278- {params[f],
279- Expression (Expression::Type::CONSTANT, " " , Number (-1 ))});
280- Expression prevTerm (Expression::Type::FUNCTION, f, {predecessor});
281- if (*val.children .at (0 ) != prevTerm) {
282- found_slope = false ;
283- break ;
284- }
285- slope = val.children .at (1 )->value ;
286- found_slope = true ;
287- } else {
288- found_slope = false ;
289- break ;
290- }
291- }
292- if (!found_slope || constants.find (Number::ZERO) == constants.end ()) {
293- continue ;
294- }
295- auto offset = constants.at (Number::ZERO);
296- for (const auto & c : constants) {
297- auto expected_val = slope;
298- expected_val *= c.first ;
299- expected_val += offset;
300- if (c.second != expected_val) {
301- found_slope = false ;
302- break ;
303- }
304- }
305- if (found_slope) {
306- slopes[f] = slope;
307- offsets[f] = offset;
308- }
309- }
310- for (auto & f : funcs) {
311- if (slopes.find (f) == slopes.end ()) {
312- continue ;
313- }
314- // remove function
315- auto it = entries.begin ();
316- while (it != entries.end ()) {
317- if (it->first .name == f) {
318- it = entries.erase (it);
319- } else {
320- it++;
321- }
322- }
323- // add simple function
324- Expression prod (
325- Expression::Type::PRODUCT, " " ,
326- {Expression (Expression::Type::CONSTANT, " " , slopes[f]), params[f]});
327- Expression sum (
328- Expression::Type::SUM, " " ,
329- {Expression (Expression::Type::CONSTANT, " " , offsets[f]), prod});
330- ExpressionUtil::normalize (sum);
331- Expression func (Expression::Type::FUNCTION, f, {params[f]});
332- entries[func] = sum;
333- }
334- }
0 commit comments