symbolic4
simplify.c
Go to the documentation of this file.
1 
2 /*
3 
4  Copyright (c) 2019 Hannes Eberhard
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  SOFTWARE.
23 
24  */
25 
26 #include "symbolic4.h"
27 
28 bool changed = false;
29 
30 void simplify_literal(expression* source);
31 
33 uint8_t numeric_addition(expression** result, expression* a, expression* b, bool persistent);
34 uint8_t symbolic_addition(expression** result, expression* a, expression* b, bool persistent);
35 void evaluate_addition(expression* source);
36 void simplify_addition(expression* source);
37 
38 uint8_t numeric_multiplication(expression** result, expression* a, expression* b, bool persistent);
39 uint8_t symbolic_multiplication(expression** result, expression* a, expression* b, bool persistent);
41 uint8_t expand_multiplication(expression* source);
43 
44 uint8_t expand_exponentation_base(expression* source);
46 uint8_t numeric_exponentation(expression* source);
47 uint8_t symbolic_exponentation(expression* source);
50 
52  uintmax_t gcd;
53  if (source->identifier != EXPI_LITERAL) return;
55  source->value.numeric.numerator /= gcd;
56  source->value.numeric.denominator /= gcd;
57 }
58 
60 
61  uint8_t i, j;
62  expression_identifier identifier;
63  expression* result;
64 
65  identifier = source->identifier;
66 
67  if (identifier != EXPI_ADDITION && identifier != EXPI_MULTIPLICATION) return;
68 
69  for (i = 0; i < source->child_count; i++) {
70  if (source->children[i] == NULL) continue;
71  if (source->children[i]->identifier == identifier) break; /* source has at least one child with the same identifier -> break to continue the merge process */
72  if (i == source->child_count - 1) return; /* all children of source were searched an no one had the same identifier as the source -> expressions cannot be merged -> return */
73  }
74 
75  result = new_expression(EXPT_OPERATION, identifier, 0);
76 
77  for (i = 0; i < source->child_count; i++) {
78  if (source->children[i] == NULL) continue;
79  if (source->children[i]->identifier == identifier) {
81  for (j = 0; j < source->children[i]->child_count; j++) {
82  append_child(result, copy_expression(source->children[i]->children[j]));
83  }
84  } else {
85  append_child(result, copy_expression(source->children[i]));
86  }
87  }
88 
89  replace_expression(source, result);
90 
91  changed = true;
92 
93 }
94 
95 uint8_t numeric_addition(expression** result, expression* a, expression* b, bool persistent) {
96 
97  numeric_value a_value;
98  numeric_value b_value;
99  uintmax_t temp_1;
100  uintmax_t temp_2;
101  uintmax_t temp_3;
102 
103  if (a->identifier != EXPI_LITERAL || b->identifier != EXPI_LITERAL) return RETS_UNCHANGED;
104 
105  a_value = a->value.numeric;
106  b_value = b->value.numeric;
107 
108  if ((a->sign == 1 && b->sign == 1) || (a->sign == -1 && b->sign == -1)) {
109 
110  if (multiplication(&temp_1, a_value.numerator, b_value.denominator) == RETS_ERROR) return RETS_UNCHANGED;
111  if (multiplication(&temp_2, a_value.denominator, b_value.numerator) == RETS_ERROR) return RETS_UNCHANGED;
112  if (addition(&temp_1, temp_1, temp_2) == RETS_ERROR) return RETS_UNCHANGED;
113 
114  if (multiplication(&temp_2, a_value.denominator, b_value.denominator) == RETS_ERROR) return RETS_UNCHANGED;
115 
116  *result = new_literal(a->sign, temp_1, temp_2);
117 
118  } else {
119 
120  if (multiplication(&temp_1, a_value.numerator, b_value.denominator) == RETS_ERROR) return RETS_UNCHANGED;
121  if (multiplication(&temp_2, a_value.denominator, b_value.numerator) == RETS_ERROR) return RETS_UNCHANGED;
122  if (multiplication(&temp_3, a_value.denominator, b_value.denominator) == RETS_ERROR) return RETS_UNCHANGED;
123 
124  if (temp_1 > temp_2) {
125  *result = new_literal(a->sign, temp_1 - temp_2, temp_3);
126  } else {
127  *result = new_literal(b->sign, temp_2 - temp_1, temp_3);
128  }
129 
130  }
131 
132  simplify_literal(*result);
133 
134  if (!persistent) {
135  free_expression(a, false);
136  free_expression(b, false);
137  }
138 
139  changed = true;
140 
141  return RETS_CHANGED;
142 
143 }
144 
145 uint8_t symbolic_addition(expression** result, expression* a, expression* b, bool persistent) {
146 
147  expression* a_temp;
148  expression* b_temp;
149  expression* a_factor;
150  expression* b_factor;
151  expression* temp;
152 
154  a_factor = copy_expression(a->children[0]);
155  a_temp = copy_expression(a);
156  remove_child_at_index(a_temp, 0);
157  simplify(a_temp, false);
158  } else {
159  a_temp = copy_expression(a);
160  a_factor = new_literal(1, 1, 1);
161  }
162 
164  b_factor = copy_expression(b->children[0]);
165  b_temp = copy_expression(b);
166  remove_child_at_index(b_temp, 0);
167  simplify(b_temp, false);
168  } else {
169  b_temp = copy_expression(b);
170  b_factor = new_literal(1, 1, 1);
171  }
172 
173  if (expressions_are_identical(a_temp, b_temp, true)) {
174  numeric_addition(&temp, a_factor, b_factor, false);
176  temp,
177  a_temp);
178  free_expression(b_temp, false);
179  changed = true;
180  return RETS_CHANGED;
181  } else {
182  free_expression(a_temp, false);
183  free_expression(b_temp, false);
184  free_expression(a_factor, false);
185  free_expression(b_factor, false);
186  return RETS_UNCHANGED;
187  }
188 
189 }
190 
192 
193  uint8_t i, j;
194  expression* temp_result;
195  expression* result;
196 
197  for (i = 0; i < source->child_count; i++) {
198 
199  if (source->children[i] == NULL) continue;
200 
201  if (source->children[i]->identifier == EXPI_LITERAL && literal_to_double(source->children[i]) == 0) {
202  free_expression(source->children[i], false);
203  source->children[i] = NULL;
204  }
205 
206  for (j = i + 1; j < source->child_count; j++) {
207 
208  if (source->children[i] == NULL) continue;
209  if (source->children[j] == NULL) continue;
210 
211  if (numeric_addition(&temp_result, source->children[i], source->children[j], true) == RETS_CHANGED) {
212  replace_expression(source->children[i], temp_result);
213  free_expression(source->children[j], false);
214  source->children[j] = NULL;
215  continue;
216  }
217 
218  if (symbolic_addition(&temp_result, source->children[i], source->children[j], true) == RETS_CHANGED) {
219  replace_expression(source->children[i], temp_result);
220  free_expression(source->children[j], false);
221  source->children[j] = NULL;
222  continue;
223  }
224 
225  }
226 
227  }
228 
229  remove_null_children(source);
230 
231  switch (source->child_count) {
232  case 0: result = new_literal(1, 0, 1); break;
233  case 1: result = copy_expression(source->children[0]); break;
234  default: result = copy_expression(source); break;
235  }
236 
237  replace_expression(source, result);
238 
239 }
240 
243  evaluate_addition(source);
244  if (source->child_count > 0) order_children(source);
245 }
246 
249  copy_expression(source->children[0]),
251  new_literal(-1, 1, 1),
252  copy_expression(source->children[1]))));
253  changed = true;
254 }
255 
256 uint8_t numeric_multiplication(expression** result, expression* a, expression* b, bool persistent) {
257 
258  numeric_value a_value;
259  numeric_value b_value;
260  uintmax_t temp_1;
261  uintmax_t temp_2;
262 
263  if (a->identifier != EXPI_LITERAL || b->identifier != EXPI_LITERAL) return RETS_UNCHANGED;
264 
265  a_value = a->value.numeric;
266  b_value = b->value.numeric;
267 
268  if (multiplication(&temp_1, a_value.numerator, b_value.numerator) == RETS_ERROR) return RETS_UNCHANGED;
269  if (multiplication(&temp_2, b_value.denominator, a_value.denominator) == RETS_ERROR) return RETS_UNCHANGED;
270 
271  *result = new_literal(a->sign * b->sign, temp_1, temp_2);
272  simplify_literal(*result);
273 
274  if (!persistent) {
275  free_expression(a, false);
276  free_expression(b, false);
277  }
278 
279  changed = true;
280 
281  return RETS_CHANGED;
282 
283 }
284 
285 uint8_t symbolic_multiplication(expression** result, expression* a, expression* b, bool persistent) {
286 
287  expression* a_temp;
288  expression* b_temp;
289  expression* a_exponent;
290  expression* b_exponent;
291  expression* temp;
292 
294  a_temp = copy_expression(a->children[0]);
295  a_exponent = copy_expression(a->children[1]);
296  } else {
297  a_temp = copy_expression(a);
298  a_exponent = new_literal(1, 1, 1);
299  }
300 
302  b_temp = copy_expression(b->children[0]);
303  b_exponent = copy_expression(b->children[1]);
304  } else {
305  b_temp = copy_expression(b);
306  b_exponent = new_literal(1, 1, 1);
307  }
308 
309  if (expressions_are_identical(a_temp, b_temp, true)) {
310  numeric_addition(&temp, a_exponent, b_exponent, false);
312  a_temp,
313  temp);
314  free_expression(b_temp, false);
315  changed = true;
316  return RETS_CHANGED;
317  } else {
318  free_expression(a_temp, false);
319  free_expression(b_temp, false);
320  free_expression(a_exponent, false);
321  free_expression(b_exponent, false);
322  return RETS_UNCHANGED;
323  }
324 
325 }
326 
328 
329  uint8_t i, j;
330  expression* temp_result;
331  expression* result;
332 
333  for (i = 0; i < source->child_count; i++) {
334 
335  if (source->children[i] == NULL) continue;
336 
337  if (source->children[i]->identifier == EXPI_LITERAL && literal_to_double(source->children[i]) == 0) {
338  replace_expression(source, new_literal(1, 0, 1));
339  return;
340  }
341 
342  if (source->children[i]->identifier == EXPI_LITERAL && literal_to_double(source->children[i]) == 1) {
343  free_expression(source->children[i], false);
344  source->children[i] = NULL;
345  continue;
346  }
347 
348  for (j = i + 1; j < source->child_count; j++) {
349 
350  if (source->children[i] == NULL) continue;
351  if (source->children[j] == NULL) continue;
352 
353  if (numeric_multiplication(&temp_result, source->children[i], source->children[j], true) == RETS_CHANGED) {
354  replace_expression(source->children[i], temp_result);
355  free_expression(source->children[j], false);
356  source->children[j] = NULL;
357  continue;
358  }
359 
360  if (symbolic_multiplication(&temp_result, source->children[i], source->children[j], true) == RETS_CHANGED) {
361  replace_expression(source->children[i], temp_result);
362  free_expression(source->children[j], false);
363  source->children[j] = NULL;
364  continue;
365  }
366 
367  }
368 
369  }
370 
371  remove_null_children(source);
372 
373  switch (source->child_count) {
374  case 0: result = new_literal(1, 1, 1); break;
375  case 1: result = copy_expression(source->children[0]); break;
376  default: result = copy_expression(source); break;
377  }
378 
379  replace_expression(source, result);
380 
381 }
382 
384 
385  uint8_t i, j, k, l;
387 
388  for (i = 0; i < source->child_count - 1; i++) {
389  for (j = 0; j < source->children[i]->child_count; j++) {
390  for (k = i + 1; k < source->child_count; k++) {
391  for (l = 0; l < source->children[k]->child_count; l++) {
393  copy_expression(source->children[i]->children[j]),
394  copy_expression(source->children[k]->children[l])));
395  }
396  }
397  }
398  }
399 
400  simplify(result, true);
401  replace_expression(source, result);
402 
403 }
404 
406 
407  uint8_t i;
408  expression* single_factors;
409  expression* addition_factors;
410  expression* result;
411 
412  if (source->child_count == 0) return RETS_UNCHANGED;
413 
414  for (i = 0; i < source->child_count; i++) {
415  if (source->children[i] == NULL) continue;
416  if (source->children[i]->identifier == EXPI_ADDITION) break; /* source has at least one child being an additon -> break to continue the expanding process */
417  if (i == source->child_count - 1) return RETS_UNCHANGED; /* all children of source were searched an no one had an addion as its child -> multiplication cannot be expanded -> return */
418  }
419 
420  single_factors = new_expression(EXPT_OPERATION, EXPI_MULTIPLICATION, 0);
421  addition_factors = new_expression(EXPT_OPERATION, EXPI_MULTIPLICATION, 0);
423 
424  for (i = 0; i < source->child_count; i++) {
425 
426  if (source->children[i] == NULL) continue;
427 
428  if (source->children[i]->identifier == EXPI_ADDITION) {
429  append_child(addition_factors, copy_expression(source->children[i]));
430  } else {
431  append_child(single_factors, copy_expression(source->children[i]));
432  }
433 
434  }
435 
436  if (addition_factors->child_count > 1) {
437  expand_multiplication_addition_factors(addition_factors);
438  } else {
439  replace_expression(addition_factors, copy_expression(addition_factors->children[0]));
440  }
441 
442  for (i = 0; i < addition_factors->child_count; i++) {
444  copy_expression(single_factors),
445  copy_expression(addition_factors->children[i])));
446  }
447 
448  simplify(result, true);
449  replace_expression(source, result);
450 
451  free_expression(single_factors, false);
452  free_expression(addition_factors, false);
453 
454  changed = true;
455 
456  return RETS_CHANGED;
457 
458 }
459 
462  if (expand_multiplication(source) == RETS_CHANGED) return;
463  evaluate_multiplication(source);
464  order_children(source);
465 }
466 
468 
470  copy_expression(source->children[0]),
472  copy_expression(source->children[1]),
473  new_literal(-1, 1, 1))));
474 
475  changed = true;
476 
477 }
478 
480 
481  expression* result;
482 
483 // if (!expression_is_constant(source)) return;
484 
485  if (source->children[0]->identifier == EXPI_EXPONENTATION) {
487  copy_expression(source->children[0]->children[0]),
489  copy_expression(source->children[0]->children[1]),
490  copy_expression(source->children[1])));
491  replace_expression(source, result);
492  simplify(source->children[1], true);
493  changed = true;
494  }
495 
496 }
497 
499 
500  uint8_t i;
501  expression* base = source->children[0];
502  expression* exponent = source->children[1];
503  expression* result;
504  uintmax_t* coefficients;
505 
506  if (base->identifier == EXPI_ADDITION && base->child_count == 2 && exponent->identifier == EXPI_LITERAL && exponent->value.numeric.numerator <= 10 && exponent->value.numeric.denominator == 1 && exponent->sign == 1) {
507 
509  coefficients = binomial_coefficients(exponent->value.numeric.numerator);
510 
511  for (i = 0; i <= exponent->value.numeric.numerator; i++) {
513  new_literal(1, coefficients[i], 1),
515  copy_expression(base->children[0]),
516  new_literal(1, exponent->value.numeric.numerator - i, 1)),
518  copy_expression(base->children[1]),
519  new_literal(1, i, 1))));
520  }
521 
522  smart_free(coefficients);
523  replace_expression(source, result);
524 
525  changed = true;
526 
527  return RETS_CHANGED;
528 
529  } else if (base->identifier == EXPI_MULTIPLICATION) {
530 
532 
533  for (i = 0; i < source->children[0]->child_count; i++) {
535  copy_expression(source->children[0]->children[i]),
536  copy_expression(source->children[1])));
537  }
538 
539  replace_expression(source, result);
540 
541  changed = true;
542 
543  return RETS_CHANGED;
544 
545  }
546 
547  return RETS_UNCHANGED;
548 
549 }
550 
552 
553  uint8_t i;
554  expression* result;
555 
556  if (source->children[1]->identifier != EXPI_ADDITION) return RETS_UNCHANGED;
557 
559 
560  for (i = 0; i < source->children[1]->child_count; i++) {
562  copy_expression(source->children[0]),
563  copy_expression(source->children[1]->children[i])));
564  }
565 
566  replace_expression(source, result);
567 
568  changed = true;
569 
570  return RETS_CHANGED;
571 
572 }
573 
575 
576  expression* base = source->children[0];
577  expression* exponent = source->children[1];
578 
579  if (exponent->identifier == EXPI_LITERAL && literal_to_double(exponent) == 0) {
580  replace_expression(source, new_literal(1, 1, 1));
581  return RETS_CHANGED;
582  }
583 
584  if (exponent->identifier == EXPI_LITERAL && literal_to_double(exponent) == 1) {
585  replace_expression(source, copy_expression(base));
586  return RETS_CHANGED;
587  }
588 
589  if (base->identifier == EXPI_LITERAL && literal_to_double(base) == 0) {
590  replace_expression(source, new_literal(1, 0, 1));
591  return RETS_CHANGED;
592  }
593 
594  if (base->identifier == EXPI_LITERAL && literal_to_double(base) == 1) {
595  replace_expression(source, new_literal(1, 1, 1));
596  return RETS_CHANGED;
597  }
598 
599  if (base->identifier == EXPI_LITERAL && literal_to_double(base) == -1 && exponent->identifier == EXPI_LITERAL && exponent->value.numeric.numerator % 2 == 1 && exponent->value.numeric.denominator == 1) {
600  replace_expression(source, new_literal(-1, 1, 1));
601  return RETS_CHANGED;
602  }
603 
604  return RETS_UNCHANGED;
605 
606 }
607 
609 
610  expression* base = source->children[0];
611  expression* exponent = source->children[1];
612  expression* base_result;
613  expression* factor;
614  expression* result;
615 
616  uintmax_t temp;
617 
618  if (base->identifier != EXPI_LITERAL || exponent->identifier != EXPI_LITERAL) return RETS_UNCHANGED;
619 
620  base_result = new_literal(1, 0, 1);
621  factor = new_literal(1, 1, 1);
622 
623  simplify_literal(base);
624  simplify_literal(exponent);
625 
626  if (literal_to_double(base) == -1 && exponent->value.numeric.denominator == 2) {
627 
628  if ((exponent->value.numeric.numerator - 1) % 4 == 0) {
630  } else {
632  new_literal(-1, 1, 1),
633  new_symbol(EXPI_SYMBOL, "i")));
634  }
635 
636  return RETS_CHANGED;
637 
638  }
639 
640  if (exponent->sign == -1) {
641  temp = base->value.numeric.numerator;
643  base->value.numeric.denominator = temp;
644  exponent->sign = 1;
645  }
646 
647  if (int_power(&base_result->value.numeric.numerator, base->value.numeric.numerator, exponent->value.numeric.numerator) == RETS_ERROR) return RETS_UNCHANGED;
648  if (int_power(&base_result->value.numeric.denominator, base->value.numeric.denominator, exponent->value.numeric.numerator) == RETS_ERROR) return RETS_UNCHANGED;
649 
650  int_root(&factor->value.numeric.numerator, &base_result->value.numeric.numerator, base_result->value.numeric.numerator, exponent->value.numeric.denominator);
651  int_root(&factor->value.numeric.denominator, &base_result->value.numeric.denominator, base_result->value.numeric.denominator, exponent->value.numeric.denominator);
652 
654 
655  if (base->sign == -1 && exponent->value.numeric.numerator % 2 == 1) {
657  new_literal(-1, 1, 1),
658  copy_expression(exponent)));
659 // symbolic_exponentation(result->children[result->child_count - 1]);
660  }
661 
662  if (literal_to_double(factor) == literal_to_double(base_result)) {
664  copy_expression(base_result),
665  new_literal(1, exponent->value.numeric.numerator + exponent->value.numeric.denominator, exponent->value.numeric.denominator)));
667  } else {
668  if (literal_to_double(factor) != 1) append_child(result, copy_expression(factor));
670  copy_expression(base_result),
671  copy_expression(exponent)));
672  }
673 
674  simplify_multiplication(result);
675  replace_expression(source, result);
676 
677  free_expressions(2, base_result, factor);
678 
679  return RETS_CHANGED;
680 
681 }
682 
684 
685  expression* base = source->children[0];
686  expression* exponent = source->children[1];
687 
688  if (expressions_are_identical(base, new_symbol(EXPI_SYMBOL, "i"), false) && exponent->identifier == EXPI_LITERAL) {
690  new_literal(-1, 1, 1),
692  new_literal(1, 1, 2),
693  copy_expression(exponent))));
694  simplify(source, true);
695  return RETS_CHANGED;
696  }
697 
698  return RETS_UNCHANGED;
699 
700 }
701 
703 
704  uint8_t i;
705  expression* base = source->children[0];
706  expression* exponent = source->children[1];
707  expression* temp;
708 
709  if (exponent->identifier == EXPI_LN && expressions_are_identical(base, new_symbol(EXPI_SYMBOL, "e"), false)) {
710  replace_expression(source, copy_expression(source->children[1]->children[0]));
711  return RETS_CHANGED;
712  }
713 
714  if (exponent->identifier == EXPI_LOG && exponent->child_count == 1 && expressions_are_identical(base, new_literal(1, 10, 1), false)) {
715  replace_expression(source, copy_expression(source->children[1]->children[0]));
716  return RETS_CHANGED;
717  }
718 
719  if (exponent->identifier == EXPI_LOG && exponent->child_count == 2 && expressions_are_identical(base, exponent->children[1], true)) {
720  replace_expression(source, copy_expression(source->children[1]->children[0]));
721  return RETS_CHANGED;
722  }
723 
724  if (exponent->identifier == EXPI_MULTIPLICATION) {
725  for (i = 0; i < exponent->child_count; i++) {
726  if (exponent->children[i]->identifier == EXPI_LN || exponent->children[i]->identifier == EXPI_LOG) {
727 
729  copy_expression(base),
730  copy_expression(exponent->children[i]));
731 
733  remove_child_at_index(exponent, i);
735  temp,
736  copy_expression(exponent)));
737  simplify(source, true);
738 
739  return RETS_CHANGED;
740 
741  }
742 
743  smart_free(temp);
744 
745  }
746  }
747  }
748 
749  return RETS_UNCHANGED;
750 
751 }
752 
754 
755  if (source->children[0]->identifier == EXPI_LITERAL && source->children[0]->value.numeric.numerator == 0 && source->children[1]->sign == -1) {
757  }
758 
760  if (numeric_exponentation(source) == RETS_CHANGED) return RETS_SUCCESS;
761  symbolic_exponentation(source);
762 
763  return RETS_SUCCESS;
764 
765 }
766 
768 
770  if (expand_exponentation_base(source) == RETS_CHANGED) return RETS_SUCCESS;
774 
775  return RETS_SUCCESS;
776 
777 }
778 
779 void simplify_abs(expression* source) {
780 
781  expression* result;
782 
783  if (source->child_count == 1) {
784  if (source->children[0]->identifier == EXPI_LITERAL || symbol_is_constant(source->children[0])) {
785  result = copy_expression(source->children[0]);
786  result->sign = 1;
787  replace_expression(source, result);
788  changed = true;
789  }
790  } else if (source->children[0]->identifier == EXPI_MULTIPLICATION && source->children[0]->child_count == 2 && source->children[0]->children[0]->sign == -1 && symbol_is_constant(source->children[0]->children[1])) {
791  result = copy_expression(source->children[0]);
792  result->children[0]->sign = 1;
793  replace_expression(source, result);
794  changed = true;
795  }
796 
797 }
798 
799 uint8_t evaluate_logarithm(expression** result, expression* value, expression* base) {
800 
801  if (expressions_are_identical(value, new_literal(1, 0, 1), false)) {
803  }
804 
805  if (expressions_are_identical(value, base, true)) {
806  *result = new_literal(1, 1, 1);
807  return RETS_SUCCESS;
808  }
809 
810  if (expressions_are_identical(base, new_symbol(EXPI_SYMBOL, "e"), false)) {
811  *result = new_expression(EXPT_FUNCTION, EXPI_LN, 1, copy_expression(value));
812  } else if (expressions_are_identical(base, new_literal(1, 10, 1), false)) {
813  *result = new_expression(EXPT_FUNCTION, EXPI_LOG, 1, copy_expression(value));
814  } else {
815  *result = new_expression(EXPT_FUNCTION, EXPI_LOG, 2,
816  copy_expression(value),
817  copy_expression(base));
818  }
819 
820  return RETS_SUCCESS;
821 
822 }
823 
824 uint8_t expand_logarithm(expression* source) {
825 
826  uint8_t i;
827  expression* factors;
828  expression* result;
829 
830  if (source->identifier != EXPI_LN || source->identifier != EXPI_LN) return RETS_UNCHANGED;
831 
832  if (source->children[0]->identifier == EXPI_MULTIPLICATION) {
833 
835 
836  for (i = 0; i < source->children[0]->child_count; i++) {
838  if (source->child_count == 2) {
839  append_child(result->children[i], copy_expression(source->children[1]));
840  }
841  }
842 
843  } else if (source->children[0]->identifier == EXPI_EXPONENTATION && expression_is_constant(source->children[0]->children[0]) && source->children[0]->children[0]->sign == 1) {
844 
846  copy_expression(source->children[0]->children[1]),
847  copy_expression(source));
848 
849  replace_expression(result->children[1]->children[0], copy_expression(result->children[1]->children[0]->children[0]));
850 
851  } else if (source->children[0]->identifier == EXPI_LITERAL && source->children[0]->value.numeric.denominator == 1) {
852 
854 
855  factors = prime_factors(source->children[0]->value.numeric.numerator);
856 
857  if (factors->child_count == 1 && factors->children[0]->children[1]->value.numeric.numerator == 1) return RETS_CHANGED;
858 
859  for (i = 0; i < factors->child_count; i++) {
861  copy_expression(factors->children[i]->children[1]),
862  new_expression(EXPT_FUNCTION, source->identifier, 1, copy_expression(factors->children[i]->children[0]))));
863  }
864 
865  free_expression(factors, false);
866 
867  } else {
868  return RETS_UNCHANGED;
869  }
870 
871  replace_expression(source, result);
872 
873  changed = true;
874 
875  return RETS_CHANGED;
876 
877 }
878 
879 uint8_t simplify_logarithm(expression* source) {
880 
881  expression* value;
882  expression* base;
883  expression* result;
884 
885  if (source->identifier == EXPI_LN && source->child_count == 1) {
886  base = new_symbol(EXPI_SYMBOL, "e");
887  } else if (source->identifier == EXPI_LOG && source->child_count == 1) {
888  base = new_literal(1, 10, 1);
889  } else if (source->identifier == EXPI_LOG && source->child_count == 2) {
890  base = copy_expression(source->children[1]);
891  } else {
892  return set_error(ERRD_SYNTAX, ERRI_ARGUMENTS, "");
893  }
894 
895  value = copy_expression(source->children[0]);
896 
897  ERROR_CHECK(evaluate_logarithm(&result, value, base));
898 
899  if (expand_logarithm(result) == RETS_CHANGED) {
900  replace_expression(source, result);
901  return RETS_CHANGED;
902  } else {
903  replace_expression(source, result);
904  return RETS_SUCCESS;
905  }
906 
907 }
908 
909 void simplify_sin(expression* source) {
910 
911  if (expressions_are_equivalent(source->children[0], new_literal(1, 0, 1), false)) {
912  replace_expression(source, new_literal(1, 0, 1));
914  new_literal(1, 1, 6),
915  new_symbol(EXPI_SYMBOL, "pi")), false)) {
916  replace_expression(source, new_literal(1, 1, 2));
918  new_literal(1, 1, 4),
919  new_symbol(EXPI_SYMBOL, "pi")), false)) {
922  new_literal(1, 2, 1),
923  new_literal(1, 1, 2)),
924  new_literal(1, 1, 2)));
926  new_literal(1, 1, 3),
927  new_symbol(EXPI_SYMBOL, "pi")), false)) {
930  new_literal(1, 3, 1),
931  new_literal(1, 1, 2)),
932  new_literal(1, 1, 2)));
934  new_literal(1, 1, 2),
935  new_symbol(EXPI_SYMBOL, "pi")), false)) {
936  replace_expression(source, new_literal(1, 1, 1));
937  } else {
938  return;
939  }
940 
941  changed = true;
942 
943 }
944 
945 void simplify_cos(expression* source) {
946 
947  if (expressions_are_equivalent(source->children[0], new_literal(1, 0, 1), false)) {
948  replace_expression(source, new_literal(1, 1, 1));
950  new_literal(1, 1, 6),
951  new_symbol(EXPI_SYMBOL, "pi")), false)) {
954  new_literal(1, 3, 1),
955  new_literal(1, 1, 2)),
956  new_literal(1, 1, 2)));
958  new_literal(1, 1, 4),
959  new_symbol(EXPI_SYMBOL, "pi")), false)) {
962  new_literal(1, 2, 1),
963  new_literal(1, 1, 2)),
964  new_literal(1, 1, 2)));
966  new_literal(1, 1, 3),
967  new_symbol(EXPI_SYMBOL, "pi")), false)) {
968  replace_expression(source, new_literal(1, 1, 2));
970  new_literal(1, 1, 2),
971  new_symbol(EXPI_SYMBOL, "pi")), false)) {
972  replace_expression(source, new_literal(1, 0, 1));
973  } else {
974  return;
975  }
976 
977  changed = true;
978 
979 }
980 
982 
983  if (expressions_are_equivalent(source->children[0], new_literal(1, 0, 1), false)) {
984  replace_expression(source, new_literal(1, 0, 1));
986  new_literal(1, 1, 6),
987  new_symbol(EXPI_SYMBOL, "pi")), false)) {
990  new_literal(1, 3, 1),
991  new_literal(1, 1, 2)),
992  new_literal(1, 1, 3)));
994  new_literal(1, 1, 4),
995  new_symbol(EXPI_SYMBOL, "pi")), false)) {
996  replace_expression(source, new_literal(1, 1, 1));
998  new_literal(1, 1, 3),
999  new_symbol(EXPI_SYMBOL, "pi")), false)) {
1001  new_literal(1, 3, 1),
1002  new_literal(1, 1, 2)));
1004  new_literal(1, 1, 2),
1005  new_symbol(EXPI_SYMBOL, "pi")), false)) {
1006  return set_error(ERRD_MATH, ERRI_UNDEFINED_VALUE, "tan");
1007  } else {
1008  return RETS_SUCCESS;
1009  }
1010 
1011  changed = true;
1012 
1013  return RETS_SUCCESS;
1014 
1015 }
1016 
1018 
1019  if (expressions_are_identical(source->children[0], new_literal(1, 0, 1), false)) {
1020  replace_expression(source, new_literal(1, 0, 1));
1021  } else if (expressions_are_identical(source->children[0], new_literal(1, 1, 2), false)) {
1023  new_symbol(EXPI_SYMBOL, "pi"),
1024  new_literal(1, 1, 6)));
1027  new_literal(1, 2, 1),
1028  new_literal(1, 1, 2)),
1029  new_literal(1, 1, 2)), false)) {
1031  new_symbol(EXPI_SYMBOL, "pi"),
1032  new_literal(1, 1, 4)));
1035  new_literal(1, 3, 1),
1036  new_literal(1, 1, 2)),
1037  new_literal(1, 1, 2)), false)) {
1039  new_symbol(EXPI_SYMBOL, "pi"),
1040  new_literal(1, 1, 3)));
1041  } else if (expressions_are_identical(source->children[0], new_literal(1, 1, 1), false)) {
1043  new_symbol(EXPI_SYMBOL, "pi"),
1044  new_literal(1, 1, 2)));
1045  } else {
1046  return;
1047  }
1048 
1049  changed = true;
1050 
1051 }
1052 
1054 
1055  if (expressions_are_identical(source->children[0], new_literal(1, 1, 1), false)) {
1056  replace_expression(source, new_literal(1, 1, 1));
1059  new_literal(1, 3, 1),
1060  new_literal(1, 1, 2)),
1061  new_literal(1, 1, 2)), false)) {
1063  new_symbol(EXPI_SYMBOL, "pi"),
1064  new_literal(1, 1, 6)));
1067  new_literal(1, 2, 1),
1068  new_literal(1, 1, 2)),
1069  new_literal(1, 1, 2)), false)) {
1071  new_symbol(EXPI_SYMBOL, "pi"),
1072  new_literal(1, 1, 4)));
1073  } else if (expressions_are_identical(source->children[0], new_literal(1, 1, 2), false)) {
1075  new_symbol(EXPI_SYMBOL, "pi"),
1076  new_literal(1, 1, 3)));
1077  } else if (expressions_are_identical(source->children[0], new_literal(1, 0, 1), false)) {
1078  replace_expression(source, new_literal(1, 0, 1));
1079  } else {
1080  return;
1081  }
1082 
1083  changed = true;
1084 
1085 }
1086 
1088 
1089  if (expressions_are_identical(source->children[0], new_literal(1, 0, 1), false)) {
1090  replace_expression(source, new_literal(1, 0, 1));
1093  new_literal(1, 3, 1),
1094  new_literal(1, 1, 2)),
1095  new_literal(1, 1, 3)), false)) {
1097  new_symbol(EXPI_SYMBOL, "pi"),
1098  new_literal(1, 1, 6)));
1099  } else if (expressions_are_identical(source->children[0], new_literal(1, 1, 1), false)) {
1101  new_symbol(EXPI_SYMBOL, "pi"),
1102  new_literal(1, 1, 4)));
1104  new_literal(1, 3, 1),
1105  new_literal(1, 1, 2)), false)) {
1107  new_symbol(EXPI_SYMBOL, "pi"),
1108  new_literal(1, 1, 3)));
1109  } else {
1110  return;
1111  }
1112 
1113  changed = true;
1114 
1115 }
1116 
1117 uint8_t simplify(expression* source, bool recursive) {
1118 
1119  uint8_t i;
1120 
1121  changed = false;
1122 
1123  for (i = 0; i < source->child_count && recursive; i++) {
1124  if (source->children[i] == NULL) continue;
1125  ERROR_CHECK(simplify(source->children[i], true));
1126  }
1127 
1129 
1130  switch (source->identifier) {
1131  case EXPI_LITERAL: simplify_literal(source); break;
1132  case EXPI_SYMBOL: break;
1133  case EXPI_VARIABLE: break;
1134  case EXPI_ADDITION: simplify_addition(source); break;
1135  case EXPI_SUBTRACTION: simplify_subtraction(source); break;
1136  case EXPI_MULTIPLICATION: simplify_multiplication(source); break;
1137  case EXPI_DIVISION: simplify_division(source); break;
1139  case EXPI_ABS: simplify_abs(source); break;
1140  case EXPI_LN:
1141  case EXPI_LOG: ERROR_CHECK(simplify_logarithm(source)); break;
1142  case EXPI_SIN: simplify_sin(source); break;
1143  case EXPI_COS: simplify_cos(source); break;
1144  case EXPI_TAN: ERROR_CHECK(simplify_tan(source)); break;
1145  case EXPI_ARCSIN: simplify_arcsin(source); break;
1146  case EXPI_ARCCOS: simplify_arccos(source); break;
1147  case EXPI_ARCTAN: simplify_arctan(source); break;
1148  case EXPI_POLYNOMIAL_SPARSE: break;
1149  case EXPI_POLYNOMIAL_DENSE: break;
1150  case EXPI_LIST: break;
1151  case EXPI_MATRIX: break;
1152  case EXPI_EXTENSION: break;
1153  default: break;
1154  }
1155 
1156  if (changed) ERROR_CHECK(simplify(source, true));
1157 
1158  return RETS_SUCCESS;
1159 
1160 }
1161 
1163 
1164  uint8_t i;
1165  double result = 0;
1166 
1167  for (i = 0; i < source->child_count; i++) {
1168  if (source->children[i]->identifier == EXPI_LITERAL) {
1169  result += literal_to_double(source->children[i]);
1170  free_expression(source->children[i], false);
1171  source->children[i] = NULL;
1172  }
1173  }
1174 
1175  remove_null_children(source);
1176 
1177  if (source->child_count == 0) {
1178  replace_expression(source, double_to_literal(result));
1179  } else {
1180  append_child(source, double_to_literal(result));
1181  }
1182 
1183 }
1184 
1186 
1187  uint8_t i;
1188  double result = 1;
1189 
1190  for (i = 0; i < source->child_count; i++) {
1191  if (source->children[i]->identifier == EXPI_LITERAL) {
1192  result *= literal_to_double(source->children[i]);
1193  free_expression(source->children[i], false);
1194  source->children[i] = NULL;
1195  }
1196  }
1197 
1198  remove_null_children(source);
1199 
1200  if (source->child_count == 0) {
1201  replace_expression(source, double_to_literal(result));
1202  } else {
1203  append_child(source, double_to_literal(result));
1204  }
1205 
1206 }
1207 
1209 
1210  double result;
1211 
1212  if (source->children[0]->identifier != EXPI_LITERAL || source->children[1]->identifier != EXPI_LITERAL) return;
1213 
1214  result = pow(literal_to_double(source->children[0]), literal_to_double(source->children[1]));
1215  replace_expression(source, double_to_literal(result));
1216 
1217 }
1218 
1220 
1221  double result;
1222 
1223  if (source->children[0]->identifier != EXPI_LITERAL) return;
1224 
1225  result = log(literal_to_double(source->children[0]));
1226  replace_expression(source, double_to_literal(result));
1227 
1228 }
1229 
1231 
1232  double result;
1233 
1234  if (source->children[0]->identifier != EXPI_LITERAL) return;
1235 
1236  result = log10(literal_to_double(source->children[0]));
1237 
1238  if (source->child_count == 2) {
1239  if (source->children[1]->identifier != EXPI_LITERAL) return;
1240  result /= log10(literal_to_double(source->children[1]));
1241  }
1242 
1243  replace_expression(source, double_to_literal(result));
1244 
1245 }
1246 
1248 
1249  double result;
1250 
1251  if (source->children[0]->identifier != EXPI_LITERAL) return;
1252 
1253  switch (source->identifier) {
1254  case EXPI_SIN: result = sin(literal_to_double(source->children[0])); break;
1255  case EXPI_COS: result = cos(literal_to_double(source->children[0])); break;
1256  case EXPI_TAN: result = tan(literal_to_double(source->children[0])); break;
1257  case EXPI_ARCSIN: result = asin(literal_to_double(source->children[0])); break;
1258  case EXPI_ARCCOS: result = acos(literal_to_double(source->children[0])); break;
1259  case EXPI_ARCTAN: result = atan(literal_to_double(source->children[0])); break;
1260  default: return;
1261  }
1262 
1263  replace_expression(source, double_to_literal(result));
1264 
1265 }
1266 
1267 void approximate(expression* source) {
1268 
1269  uint8_t i;
1270 
1271  for (i = 0; i < source->child_count; i++) {
1272  if (source->children[i] == 0) continue;
1273  approximate(source->children[i]);
1274  }
1275 
1276  if (expressions_are_identical(source, new_symbol(EXPI_SYMBOL, "pi"), false)) {
1277  replace_expression(source, double_to_literal(M_PI));
1278  } else if (expressions_are_identical(source, new_symbol(EXPI_SYMBOL, "e"), false)) {
1279  replace_expression(source, double_to_literal(M_E));
1280  }
1281 
1282  switch (source->identifier) {
1283  case EXPI_ADDITION: approximate_addition(source); break;
1284  case EXPI_MULTIPLICATION: approximate_multiplication(source); break;
1285  case EXPI_EXPONENTATION: approximate_exponentation(source); break;
1286  case EXPI_LN: approximate_ln(source); break;
1287  case EXPI_LOG: approximate_log(source); break;
1288  case EXPI_SIN:
1289  case EXPI_COS:
1290  case EXPI_TAN:
1291  case EXPI_ARCSIN:
1292  case EXPI_ARCCOS:
1293  case EXPI_ARCTAN: approximate_trigonometric(source); break;
1294  default: break;
1295  }
1296 
1297 }
ERRI_ARGUMENTS
Definition: foundation.h:58
EXPI_LIST
Definition: expression.h:90
remove_exponentation_identities
uint8_t remove_exponentation_identities(expression *source)
Definition: simplify.c:574
EXPT_FUNCTION
Definition: expression.h:35
approximate_trigonometric
void approximate_trigonometric(expression *source)
Definition: simplify.c:1247
numeric_value::denominator
uintmax_t denominator
Definition: expression.h:109
int_power
uint8_t int_power(uintmax_t *result, uintmax_t base, uintmax_t exponent)
Definition: math_foundation.c:142
symbolic4.h
simplify_division
void simplify_division(expression *source)
Definition: simplify.c:467
EXPI_LN
Definition: expression.h:56
ERRI_UNDEFINED_VALUE
Definition: foundation.h:60
EXPI_EXPONENTATION
Definition: expression.h:53
EXPI_ARCTAN
Definition: expression.h:63
merge_nested_exponentations
void merge_nested_exponentations(expression *source)
Definition: simplify.c:479
EXPI_POLYNOMIAL_DENSE
Definition: expression.h:89
EXPI_SYMBOL
Definition: expression.h:45
expression_identifier
expression_identifier
Definition: expression.h:40
EXPI_ABS
Definition: expression.h:55
replace_expression
void replace_expression(expression *a, expression *b)
Definition: expression.c:309
simplify_arctan
void simplify_arctan(expression *source)
Definition: simplify.c:1087
symbolic_exponentation
uint8_t symbolic_exponentation(expression *source)
Definition: simplify.c:683
expression
Definition: expression.h:112
expression::identifier
expression_identifier identifier
Definition: expression.h:115
prime_factors
expression * prime_factors(uintmax_t source)
Definition: math_foundation.c:65
EXPI_COS
Definition: expression.h:59
literal_to_double
double literal_to_double(expression *source)
Definition: expression.c:908
exponentation_remove_logarithms
return_status exponentation_remove_logarithms(expression *source)
Definition: simplify.c:702
expand_multiplication
uint8_t expand_multiplication(expression *source)
Definition: simplify.c:405
simplify_multiplication
void simplify_multiplication(expression *source)
Definition: simplify.c:460
ERRD_SYNTAX
Definition: foundation.h:36
smart_free
void smart_free(void *pointer)
Frees a pointer.
Definition: foundation.c:112
simplify_cos
void simplify_cos(expression *source)
Definition: simplify.c:945
expression::sign
int8_t sign
Definition: expression.h:117
ERROR_CHECK
#define ERROR_CHECK(F)
Check if the return status of a function is RETS_ERROR. If so, return RETS_ERROR.
Definition: foundation.h:31
EXPI_LOG
Definition: expression.h:57
approximate_multiplication
void approximate_multiplication(expression *source)
Definition: simplify.c:1185
euclidean_gcd
uintmax_t euclidean_gcd(uintmax_t a, uintmax_t b)
Computes the GCD of two integers.
Definition: math_foundation.c:51
simplify_abs
void simplify_abs(expression *source)
Definition: simplify.c:779
new_symbol
expression * new_symbol(expression_identifier identifier, const char *value)
Allocates and initializes a new symbol/variable expression.
Definition: expression.c:252
EXPI_ARCSIN
Definition: expression.h:61
expression::value
union expression::@0 value
simplify_sin
void simplify_sin(expression *source)
Definition: simplify.c:909
symbolic_multiplication
uint8_t symbolic_multiplication(expression **result, expression *a, expression *b, bool persistent)
Definition: simplify.c:285
symbolic_addition
uint8_t symbolic_addition(expression **result, expression *a, expression *b, bool persistent)
Definition: simplify.c:145
double_to_literal
expression * double_to_literal(double source)
Definition: expression.c:896
RETS_UNCHANGED
Definition: foundation.h:69
evaluate_logarithm
uint8_t evaluate_logarithm(expression **result, expression *value, expression *base)
Definition: simplify.c:799
RETS_SUCCESS
Definition: foundation.h:67
EXPI_EXTENSION
Definition: expression.h:92
order_children
void order_children(expression *source)
Definition: expression.c:769
expressions_are_identical
bool expressions_are_identical(const expression *a, expression *b, bool persistent)
Definition: expression.c:467
RETS_CHANGED
Definition: foundation.h:68
RETS_ERROR
Definition: foundation.h:66
remove_child_at_index
void remove_child_at_index(expression *source, uint8_t index)
Definition: expression.c:397
approximate_addition
void approximate_addition(expression *source)
Definition: simplify.c:1162
free_expression
void free_expression(expression *source, bool persistent)
Definition: expression.c:315
evaluate_addition
void evaluate_addition(expression *source)
Definition: simplify.c:191
numeric_addition
uint8_t numeric_addition(expression **result, expression *a, expression *b, bool persistent)
Definition: simplify.c:95
simplify_logarithm
uint8_t simplify_logarithm(expression *source)
Definition: simplify.c:879
binomial_coefficients
uintmax_t * binomial_coefficients(uint8_t n)
Definition: math_foundation.c:106
numeric_multiplication
uint8_t numeric_multiplication(expression **result, expression *a, expression *b, bool persistent)
Definition: simplify.c:256
EXPI_MULTIPLICATION
Definition: expression.h:51
EXPI_SIN
Definition: expression.h:58
set_error
uint8_t set_error(error_domain domain, error_identifier identifier, const char *body)
Sets current_error to the arguments provided.
Definition: foundation.c:152
expand_logarithm
uint8_t expand_logarithm(expression *source)
Definition: simplify.c:824
approximate
void approximate(expression *source)
Definition: simplify.c:1267
int_root
void int_root(uintmax_t *factor, uintmax_t *remainder, uintmax_t base, uintmax_t degree)
Definition: math_foundation.c:152
EXPI_POLYNOMIAL_SPARSE
Definition: expression.h:88
free_expressions
void free_expressions(uint8_t expression_count,...)
Definition: expression.c:338
multiplication
uint8_t multiplication(uintmax_t *result, uintmax_t a, uintmax_t b)
Definition: math_foundation.c:133
expand_exponentation_exponent
uint8_t expand_exponentation_exponent(expression *source)
Definition: simplify.c:551
EXPT_OPERATION
Definition: expression.h:34
any_expression_to_expression
void any_expression_to_expression(expression *source)
Definition: polynomial.c:33
approximate_exponentation
void approximate_exponentation(expression *source)
Definition: simplify.c:1208
expression::numeric
numeric_value numeric
Definition: expression.h:129
simplify_addition
void simplify_addition(expression *source)
Definition: simplify.c:241
expression_is_constant
bool expression_is_constant(const expression *source)
Definition: expression.c:593
copy_expression
expression * copy_expression(const expression *source)
Returns a deep copy of an expression.
Definition: expression.c:286
merge_additions_multiplications
void merge_additions_multiplications(expression *source)
Definition: simplify.c:59
EXPI_SUBTRACTION
Definition: expression.h:50
simplify_arccos
void simplify_arccos(expression *source)
Definition: simplify.c:1053
simplify_tan
return_status simplify_tan(expression *source)
Definition: simplify.c:981
simplify_exponentation
return_status simplify_exponentation(expression *source)
Definition: simplify.c:767
simplify
uint8_t simplify(expression *source, bool recursive)
Definition: simplify.c:1117
ERRD_MATH
Definition: foundation.h:37
expand_multiplication_addition_factors
void expand_multiplication_addition_factors(expression *source)
Definition: simplify.c:383
append_child
void append_child(expression *parent, expression *child)
Appends a child to an expression.
Definition: expression.c:383
new_expression
expression * new_expression(expression_type type, expression_identifier identifier, uint8_t child_count,...)
Allocates and initializes a new expression with the arguments provided.
Definition: expression.c:183
EXPI_TAN
Definition: expression.h:60
EXPI_ARCCOS
Definition: expression.h:62
remove_null_children
void remove_null_children(expression *source)
Definition: expression.c:403
EXPI_VARIABLE
Definition: expression.h:46
evaluate_multiplication
void evaluate_multiplication(expression *source)
Definition: simplify.c:327
EXPI_MATRIX
Definition: expression.h:91
numeric_value
Definition: expression.h:107
addition
uint8_t addition(uintmax_t *result, uintmax_t a, uintmax_t b)
Definition: math_foundation.c:124
new_literal
expression * new_literal(int8_t sign, uintmax_t numerator, uintmax_t denominator)
Allocates and initializes a new literal expression.
Definition: expression.c:225
EXPI_ADDITION
Definition: expression.h:49
expand_exponentation_base
uint8_t expand_exponentation_base(expression *source)
Definition: simplify.c:498
return_status
return_status
Definition: foundation.h:64
expressions_are_equivalent
bool expressions_are_equivalent(const expression *a, expression *b, bool persistent)
Definition: expression.c:526
changed
bool changed
Definition: simplify.c:28
evaluate_exponentation
return_status evaluate_exponentation(expression *source)
Definition: simplify.c:753
expression::child_count
uint8_t child_count
Definition: expression.h:119
expression::children
struct expression ** children
Definition: expression.h:124
simplify_arcsin
void simplify_arcsin(expression *source)
Definition: simplify.c:1017
numeric_value::numerator
uintmax_t numerator
Definition: expression.h:108
approximate_log
void approximate_log(expression *source)
Definition: simplify.c:1230
approximate_ln
void approximate_ln(expression *source)
Definition: simplify.c:1219
simplify_literal
void simplify_literal(expression *source)
Definition: simplify.c:51
symbol_is_constant
bool symbol_is_constant(const expression *source)
Definition: expression.c:611
EXPI_DIVISION
Definition: expression.h:52
numeric_exponentation
uint8_t numeric_exponentation(expression *source)
Definition: simplify.c:608
EXPI_LITERAL
Definition: expression.h:44
simplify_subtraction
void simplify_subtraction(expression *source)
Definition: simplify.c:247