Closed aliang8 closed 7 years ago
Cool!
const rule = defineRuleString('#a / #b * #c / #d', '#a * #c / #b * #d');
math-parser
parses a * b / c * d
as a * (b/c) * d
so this rule would need to be
const rule = defineRuleString('#a / #b * #c / #d', '(#a * #c) / (#b * #d)');
Also, we won't be able to do the evaluation step yet.
FYI, defineRule
and applyRule
don't understand the commutative property so we'll need to provide rules for 0 + #a
in addition to #a + 0
and such.
Also, we should probably have a rule for -#a * -#b
=> #a * #b
--#a
=> #a
Updated: Added MULTIPLY_NEGATIVES and NEGATION
For commutative property, will there be a general case of #a + #b
=> #b + #a
or
#a * #b
=> #b * #a
. Why do we need the identity case? Isn't it a similar approach also for associative property and distributive?
What happens when we encounter a multi-term expression like #a + #b + #c
? How will commutative property/ associative property hold then?
Not sure how useful rules for general commutative or associative properties would be. I think though that we'd probably want to simplify 1 * #a
to #a
immediately instead of doing 1 * #a
=> #a * 1
=> #a
.
Commutative implies that the terms in a multi-term expression can be re-ordered in any order. I'm don't think it's particular useful to formulate this as a rule per se, although in rules for collecting like terms we may want to reorder terms before grouping them.
Why do we need the identity case? Isn't it a similar approach also for associative property and distributive?
Not sure what you meant by this. Can you elaborate?
although in rules for collecting like terms we may want to reorder terms before grouping them.
Good point. And by the identity case I meant #a + 0
=> 0 + #a
which I don't think we need. We have REMOVE_ADDING_ZERO to take care of that. Also, we took care of 1 * #a
=> #a
with REMOVE_MULTIPLYING_BY_ONE.
Rewrite rules are indeed amazing and a joy to work with! However, before going much further defining object-level rules (which these are), both of you really should allow me to explain PRESS's approach to solving elementary algebra equations to you. PRESS is the result of 8+ years of intense research, and understanding it would enable the semantic-math system to be based on sound theory instead of on ad-hoc methods. I think the PRESS approach will also blow your mind like it did mine.
An understanding of the fundamental techniques of PRESS would enable the semantic-math system to stand on the shoulders of the PRESS giant instead of standing on its toes. Since you both already understand expression trees and rewrite rules, I don't think it would take very long to explain the fundamental techniques of PRESS to you.
@tkosan would love to hear more about PRESS.
@kevinbarabash okay, I will plan on making the initial educational materials available by this weekend. Would you prefer to discuss these materials using an issue in this project or through something like a Google Group?
I'm also interested! Let me know when this is going down.
@tkosan I think making a separate issue here would be sufficient.
// NEGATION // e.g. -(-3) -> 3 const NEGATION = defineRuleString('--#a', '#a');
// ARITHMETIC // e.g. 2/-1 -> -2 const DIVISION_BY_NEGATIVE_ONE = defineRuleString('#a / -1', '-#a');
// e.g. 2/1 -> 2 const DIVISION_BY_ONE = defineRuleString('#a / 1', '#a');
// e.g. x 0 -> 0 const MULTIPLY_BY_ZERO = defineRuleString('#a 0', '0');
// e.g. x ^ 0 -> 1 const REDUCE_EXPONENT_BY_ZERO = defineRuleString('#a ^ 0', '1');
// e.g. 0/1 -> 0 const REDUCE_ZERO_NUMERATOR = defineRuleString('0 / #a', '0');
// e.g. 2 + 0 -> 2 const REMOVE_ADDING_ZERO = defineRuleString('#a + 0', '#a');
// e.g. x ^ 1 -> x const REMOVE_EXPONENT_BY_ONE = defineRuleString('#a ^ 1', '#a');
// e.g. 1 ^ x -> 1 const REMOVE_EXPONENT_BASE_ONE = defineRuleString('1 ^ #a', '1');
// e.g. x -1 -> -x const REMOVE_MULTIPLYING_BY_NEGATIVE_ONE = defineRuleString('#a -1', '-#a');
// e.g. x 1 -> x const REMOVE_MULTIPLYING_BY_ONE = defineRuleString('#a 1', '#a');
// e.g. 2 - - 3 -> 2 + 3 const RESOLVE_DOUBLE_MINUS = defineRuleString('#a - -#b', '#a + #b');
// e.g -3 -2 -> 3 2 const MULTIPLY_NEGATIVES = defineRuleString('-#a -#b', '#a #b');
// FRACTIONS
// e.g. -2/-3 => 2/3 const CANCEL_MINUSES = defineRuleString('-#a / -#b', '#a / #b');
// e.g. 2/-3 -> -2/3 const SIMPLIFY_SIGNS = defineRuleString('#a - -#b', '#a + #b');
// MULTIPLYING FRACTIONS
// e.g. 1/2 2/3 -> 2/3 const MULTIPLY_FRACTIONS = defineRuleString('#a / #b #c / #d', '(#a #c) / (#b #d)');
// DIVISION
// e.g. 2/3/4 -> 2/(34) const SIMPLIFY_DIVISION = defineRuleString('#a / #b / #c', '#a / (#b #c)');
// e.g. x/(2/3) -> x 3/2 const MULTIPLY_BY_INVERSE = defineRuleString('#a / (#b / #c)', '#a (#c / #b)');
// ABSOLUTE // e.g. |-3| -> 3 const ABSOLUTE_VALUE = defineRuleString('|-#a|', '#a');