diff --git a/poincare/Makefile b/poincare/Makefile index 510fa79fc..4a86645b6 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -1,6 +1,6 @@ SFLAGS += -Ipoincare/include -include poincare/src/simplify/Makefile +include poincare/src/simplification/Makefile objs += $(addprefix poincare/src/,\ absolute_value.o\ diff --git a/poincare/src/simplify/Makefile b/poincare/src/simplification/Makefile similarity index 56% rename from poincare/src/simplify/Makefile rename to poincare/src/simplification/Makefile index c3aa10fa4..c9aff3430 100644 --- a/poincare/src/simplify/Makefile +++ b/poincare/src/simplification/Makefile @@ -1,6 +1,6 @@ #include poincare/src/simplify/rules_generation/Makefile -dir=poincare/src/simplify +dir=poincare/src/simplification $(dir)/rules.cpp: $(RULEGEN) $(dir)/rules.pr @echo "RULEGEN $@" @@ -9,11 +9,10 @@ $(dir)/rules.cpp: $(RULEGEN) $(dir)/rules.pr products += $(dir)/rules.cpp objs += $(addprefix $(dir)/,\ - combination.o \ - expression.o \ + expression_simplify.o \ rule.o \ - integer_addition.o \ - merge_addition.o \ - type_selector.o \ - selector.o \ + selector/combination.o \ + selector/selector.o \ + selector/type_selector.o \ + transform/merge_addition_transform.o \ ) diff --git a/poincare/src/simplify/README.md b/poincare/src/simplification/README.md similarity index 100% rename from poincare/src/simplify/README.md rename to poincare/src/simplification/README.md diff --git a/poincare/src/simplify/expression.cpp b/poincare/src/simplification/expression_simplify.cpp similarity index 74% rename from poincare/src/simplify/expression.cpp rename to poincare/src/simplification/expression_simplify.cpp index 3f1ceb5a7..1dc146883 100644 --- a/poincare/src/simplify/expression.cpp +++ b/poincare/src/simplification/expression_simplify.cpp @@ -35,8 +35,8 @@ void Expression::simplify(Expression ** e) { root.sort(); // Only unconditional simplify int ruleIndex = 0; - while (ruleIndex < DemoRuleSet.numberOfRules()) { - const Rule * rule = DemoRuleSet.ruleAtIndex(ruleIndex++); + while (ruleIndex < Simplification::DemoRuleSet.numberOfRules()) { + const Simplification::Rule * rule = Simplification::DemoRuleSet.ruleAtIndex(ruleIndex++); if (rule->apply(&root)) { root.sort(); std::cout << "-----" << std::endl; @@ -48,22 +48,4 @@ void Expression::simplify(Expression ** e) { *e = (Expression *)(root.operand(0)); } -#if 0 -Expression * Expression::simplify() { - sort(); - // Only unconditional simplify - int ruleIndex = 0; - while (ruleIndex < DemoRuleSet.numberOfRules()) { - const Rule * rule = DemoRuleSet.ruleAtIndex(ruleIndex++); - if (rule->apply(this)) { - this->sort(); - std::cout << "-----" << std::endl; - print_expression(this, 0); - std::cout << "-----" << std::endl; - ruleIndex = 0; - } - } -} -#endif - } diff --git a/poincare/src/simplification/handwritten_rules.txt b/poincare/src/simplification/handwritten_rules.txt new file mode 100644 index 000000000..c30a268f2 --- /dev/null +++ b/poincare/src/simplification/handwritten_rules.txt @@ -0,0 +1 @@ +Addition(Integer.a,Integer.b) -> IntegerAddition diff --git a/poincare/src/simplify/rule.cpp b/poincare/src/simplification/rule.cpp similarity index 96% rename from poincare/src/simplify/rule.cpp rename to poincare/src/simplification/rule.cpp index 463636000..3c0b9fae8 100644 --- a/poincare/src/simplify/rule.cpp +++ b/poincare/src/simplification/rule.cpp @@ -1,6 +1,7 @@ #include "rule.h" namespace Poincare { +namespace Simplification { bool Rule::apply(Expression * e) const { if (immediateApply(e)) { @@ -28,3 +29,4 @@ bool Rule::immediateApply(Expression * e) const { } } +} diff --git a/poincare/src/simplify/rule.h b/poincare/src/simplification/rule.h similarity index 64% rename from poincare/src/simplify/rule.h rename to poincare/src/simplification/rule.h index f5e82c1c6..8e0bf0bc0 100644 --- a/poincare/src/simplify/rule.h +++ b/poincare/src/simplification/rule.h @@ -1,10 +1,11 @@ -#ifndef POINCARE_SIMPLIFY_RULE_H -#define POINCARE_SIMPLIFY_RULE_H +#ifndef POINCARE_SIMPLIFICATION_RULE_H +#define POINCARE_SIMPLIFICATION_RULE_H -#include "selector.h" -#include "transform.h" +#include "selector/selector.h" +#include "transform/transform.h" namespace Poincare { +namespace Simplification { class Rule { public: @@ -18,6 +19,7 @@ private: const Transform * m_transform; }; +} } #endif diff --git a/poincare/src/simplify/rules.h b/poincare/src/simplification/rules.h similarity index 65% rename from poincare/src/simplify/rules.h rename to poincare/src/simplification/rules.h index 13a07203c..d1056f406 100644 --- a/poincare/src/simplify/rules.h +++ b/poincare/src/simplification/rules.h @@ -1,5 +1,5 @@ -#ifndef POINCARE_SIMPLIFY_RULES_H -#define POINCARE_SIMPLIFY_RULES_H +#ifndef POINCARE_SIMPLIFICATION_RULES_H +#define POINCARE_SIMPLIFICATION_RULES_H #include "simplification.h" diff --git a/poincare/src/simplify/rules.pr b/poincare/src/simplification/rules.pr similarity index 100% rename from poincare/src/simplify/rules.pr rename to poincare/src/simplification/rules.pr diff --git a/poincare/src/simplify/rules_generation/Makefile b/poincare/src/simplification/rules_generation/Makefile similarity index 100% rename from poincare/src/simplify/rules_generation/Makefile rename to poincare/src/simplification/rules_generation/Makefile diff --git a/poincare/src/simplify/rules_generation/node.cpp b/poincare/src/simplification/rules_generation/node.cpp similarity index 100% rename from poincare/src/simplify/rules_generation/node.cpp rename to poincare/src/simplification/rules_generation/node.cpp diff --git a/poincare/src/simplify/rules_generation/node.h b/poincare/src/simplification/rules_generation/node.h similarity index 90% rename from poincare/src/simplify/rules_generation/node.h rename to poincare/src/simplification/rules_generation/node.h index 08d8d1ee5..9f7a7884e 100644 --- a/poincare/src/simplify/rules_generation/node.h +++ b/poincare/src/simplification/rules_generation/node.h @@ -1,5 +1,5 @@ -#ifndef POINCARE_SIMPLIFY_RULES_GENERATION_NODE_H -#define POINCARE_SIMPLIFY_RULES_GENERATION_NODE_H +#ifndef POINCARE_SIMPLIFICATION_RULES_GENERATION_NODE_H +#define POINCARE_SIMPLIFICATION_RULES_GENERATION_NODE_H class Rule; diff --git a/poincare/src/simplify/rules_generation/rule.cpp b/poincare/src/simplification/rules_generation/rule.cpp similarity index 100% rename from poincare/src/simplify/rules_generation/rule.cpp rename to poincare/src/simplification/rules_generation/rule.cpp diff --git a/poincare/src/simplify/rules_generation/rule.h b/poincare/src/simplification/rules_generation/rule.h similarity index 65% rename from poincare/src/simplify/rules_generation/rule.h rename to poincare/src/simplification/rules_generation/rule.h index f6c57ae6f..daa6372fc 100644 --- a/poincare/src/simplify/rules_generation/rule.h +++ b/poincare/src/simplification/rules_generation/rule.h @@ -1,5 +1,5 @@ -#ifndef POINCARE_SIMPLIFY_RULES_GENERATION_RULE_H -#define POINCARE_SIMPLIFY_RULES_GENERATION_RULE_H +#ifndef POINCARE_SIMPLIFICATION_RULES_GENERATION_RULE_H +#define POINCARE_SIMPLIFICATION_RULES_GENERATION_RULE_H #include "node.h" diff --git a/poincare/src/simplify/rules_generation/rules_lexer.l b/poincare/src/simplification/rules_generation/rules_lexer.l similarity index 100% rename from poincare/src/simplify/rules_generation/rules_lexer.l rename to poincare/src/simplification/rules_generation/rules_lexer.l diff --git a/poincare/src/simplify/rules_generation/rules_parser.y b/poincare/src/simplification/rules_generation/rules_parser.y similarity index 100% rename from poincare/src/simplify/rules_generation/rules_parser.y rename to poincare/src/simplification/rules_generation/rules_parser.y diff --git a/poincare/src/simplify/ruleset.h b/poincare/src/simplification/ruleset.h similarity index 85% rename from poincare/src/simplify/ruleset.h rename to poincare/src/simplification/ruleset.h index 5de527adf..2bd56fd60 100644 --- a/poincare/src/simplify/ruleset.h +++ b/poincare/src/simplification/ruleset.h @@ -1,13 +1,12 @@ -#ifndef POINCARE_SIMPLIFY_RULESET_H -#define POINCARE_SIMPLIFY_RULESET_H +#ifndef POINCARE_SIMPLIFICATION_RULESET_H +#define POINCARE_SIMPLIFICATION_RULESET_H #include "rule.h" -#include "type_selector.h" -#include "integer_addition.h" -#include "merge_addition.h" -#include "transform/subtraction_transform.h" +#include "selector/type_selector.h" +#include "transform/merge_addition_transform.h" namespace Poincare { +namespace Simplification { class RuleSet { public: @@ -21,6 +20,7 @@ private: int m_numberOfRules; }; +#if 0 //R0: Int + Int -> AdditionDeInt constexpr TypeSelector r0s0(Expression::Type::Integer, 0); constexpr TypeSelector r0s1(Expression::Type::Integer, 1); @@ -28,6 +28,7 @@ constexpr const Selector * r0s2c[] = {&r0s0, &r0s1}; constexpr TypeSelector r0s2(Expression::Type::Addition, 2, r0s2c, 2); constexpr IntegerAddition r0t; constexpr Rule r0(&r0s2, &r0t); +#endif #if 0 @@ -65,14 +66,15 @@ constexpr Rule r0(&r0s2, &r0t); constexpr TypeSelector r1s0(Expression::Type::Addition, 0); constexpr const Selector * r1s1c[] = {&r1s0}; constexpr TypeSelector r1s1(Expression::Type::Addition, 1, r1s1c, 1); -constexpr MergeAddition r1t; +constexpr MergeAdditionTransform r1t; constexpr Rule r1(&r1s1, &r1t); // RuleSet //constexpr Rule rules[2] = {R3::rule, r1, r0, R2::rule}; -constexpr Rule rules[2] = {r1, r0}; -constexpr RuleSet DemoRuleSet(rules, 2); +constexpr Rule rules[1] = {r1}; +constexpr RuleSet DemoRuleSet(rules, 1); +} } #endif diff --git a/poincare/src/simplify/any_selector.h b/poincare/src/simplification/selector/any_selector.h similarity index 61% rename from poincare/src/simplify/any_selector.h rename to poincare/src/simplification/selector/any_selector.h index cf38c5756..fb4c8f379 100644 --- a/poincare/src/simplify/any_selector.h +++ b/poincare/src/simplification/selector/any_selector.h @@ -1,9 +1,10 @@ -#ifndef POINCARE_SIMPLIFY_ANY_SELECTOR_H -#define POINCARE_SIMPLIFY_ANY_SELECTOR_H +#ifndef POINCARE_SIMPLIFICATION_SELECTOR_ANY_SELECTOR_H +#define POINCARE_SIMPLIFICATION_SELECTOR_ANY_SELECTOR_H #include "selector.h" namespace Poincare { +namespace Simplification { class AnySelector : public Selector { public: @@ -11,6 +12,7 @@ public: bool acceptsLocationInCombination(const Combination * combination, int location) const override; }; +} } #endif diff --git a/poincare/src/simplify/combination.cpp b/poincare/src/simplification/selector/combination.cpp similarity index 98% rename from poincare/src/simplify/combination.cpp rename to poincare/src/simplification/selector/combination.cpp index 47a8ea2f9..4ef7c8925 100644 --- a/poincare/src/simplify/combination.cpp +++ b/poincare/src/simplification/selector/combination.cpp @@ -2,6 +2,7 @@ #include namespace Poincare { +namespace Simplification { Combination::Combination(const Selector * const * selectors, int numberOfSelectors, const Expression * rootExpression) : m_selectors(selectors), @@ -64,3 +65,4 @@ bool Combination::next() { } } +} diff --git a/poincare/src/simplify/combination.h b/poincare/src/simplification/selector/combination.h similarity index 89% rename from poincare/src/simplify/combination.h rename to poincare/src/simplification/selector/combination.h index ac3e83828..68462b843 100644 --- a/poincare/src/simplify/combination.h +++ b/poincare/src/simplification/selector/combination.h @@ -1,10 +1,11 @@ -#ifndef POINCARE_SIMPLIFY_COMBINATION_H -#define POINCARE_SIMPLIFY_COMBINATION_H +#ifndef POINCARE_SIMPLIFICATION_SELECTOR_COMBINATION_H +#define POINCARE_SIMPLIFICATION_SELECTOR_COMBINATION_H #include #include "selector.h" namespace Poincare { +namespace Simplification { /* Combination is the association of two tables: a selectors table and an expressions * table. @@ -35,6 +36,7 @@ private: bool m_firstIteration; }; +} } #endif diff --git a/poincare/src/simplification/selector/same_as_selector.h b/poincare/src/simplification/selector/same_as_selector.h new file mode 100644 index 000000000..9dfe7d750 --- /dev/null +++ b/poincare/src/simplification/selector/same_as_selector.h @@ -0,0 +1,21 @@ +#ifndef POINCARE_SIMPLIFICATION_SAME_AS_SELECTOR_H +#define POINCARE_SIMPLIFICATION_SAME_AS_SELECTOR_H + +#include "selector.h" + +namespace Poincare { +namespace Simplification { + +class SameAsSelector : public Selector { +public: + constexpr SameAsSelector(int originalIndex, int captureIndex = -1, Selector ** children = nullptr, int numberOfChildren = 0) : + Selector(captureIndex, children, numberOfChildren), m_originalIndex(originalIndex) {} + bool acceptsLocationInCombination(const Combination * combination, int location) const override; +private: + int m_originalIndex; +}; + +} +} + +#endif diff --git a/poincare/src/simplify/selector.cpp b/poincare/src/simplification/selector/selector.cpp similarity index 98% rename from poincare/src/simplify/selector.cpp rename to poincare/src/simplification/selector/selector.cpp index 607d35b2d..0943c6b5e 100644 --- a/poincare/src/simplify/selector.cpp +++ b/poincare/src/simplification/selector/selector.cpp @@ -3,6 +3,7 @@ #include namespace Poincare { +namespace Simplification { bool Selector::match(const Expression * e, Expression ** captures) const { // Si pour commencer, e ne correspond pas mon petit test moi perso, c'est mort! @@ -48,3 +49,4 @@ bool Selector::match(const Expression * e, Expression ** captures) const { } } +} diff --git a/poincare/src/simplify/selector.h b/poincare/src/simplification/selector/selector.h similarity index 70% rename from poincare/src/simplify/selector.h rename to poincare/src/simplification/selector/selector.h index c4bea6651..c559c0750 100644 --- a/poincare/src/simplify/selector.h +++ b/poincare/src/simplification/selector/selector.h @@ -1,21 +1,17 @@ -#ifndef POINCARE_SIMPLIFY_SELECTOR_H -#define POINCARE_SIMPLIFY_SELECTOR_H +#ifndef POINCARE_SIMPLIFICATION_SELECTOR_SELECTOR_H +#define POINCARE_SIMPLIFICATION_SELECTOR_SELECTOR_H #include namespace Poincare { +namespace Simplification { class Combination; class Selector { public: constexpr Selector(int captureIndex = -1, const Selector * const * children = nullptr, int numberOfChildren = 0) : - m_captureIndex(captureIndex), - m_children(children), - m_numberOfChildren(numberOfChildren) - { - }; - + m_captureIndex(captureIndex), m_children(children), m_numberOfChildren(numberOfChildren) {} virtual bool acceptsLocationInCombination(const Combination * combination, int location) const = 0; virtual bool immediateMatch(const Expression * e) const = 0; bool match(const Expression * e, Expression ** captures) const; @@ -25,6 +21,7 @@ private: int m_numberOfChildren; }; +} } #endif diff --git a/poincare/src/simplification/selector/type_and_value_selector.h b/poincare/src/simplification/selector/type_and_value_selector.h new file mode 100644 index 000000000..cb667149e --- /dev/null +++ b/poincare/src/simplification/selector/type_and_value_selector.h @@ -0,0 +1,21 @@ +#ifndef POINCARE_SIMPLIFICATION_SELECTOR_TYPE_AND_VALUE_SELECTOR_H +#define POINCARE_SIMPLIFICATION_SELECTOR_TYPE_AND_VALUE_SELECTOR_H + +#include "selector.h" + +namespace Poincare { +namespace Simplification { + +class TypeAndValueSelector : public Selector { +public: + constexpr TypeAndValueSelector(Expression::Type type, int value, int captureIndex = -1, Selector ** children = nullptr, int numberOfChildren = 0) : Selector(captureIndex, children, numberOfChildren), m_type(type), m_value(value) { } + bool acceptsLocationInCombination(const Combination * combination, int location) const override; +private: + Expression::Type m_type; + int m_value; +}; + +} +} + +#endif diff --git a/poincare/src/simplify/type_selector.cpp b/poincare/src/simplification/selector/type_selector.cpp similarity index 96% rename from poincare/src/simplify/type_selector.cpp rename to poincare/src/simplification/selector/type_selector.cpp index fed3aa384..0b83864e0 100644 --- a/poincare/src/simplify/type_selector.cpp +++ b/poincare/src/simplification/selector/type_selector.cpp @@ -2,6 +2,7 @@ #include "combination.h" namespace Poincare { +namespace Simplification { bool TypeSelector::immediateMatch(const Expression * e) const { return (e->type() == m_type); @@ -22,3 +23,4 @@ bool TypeSelector::acceptsLocationInCombination(const Combination * combination, } } +} diff --git a/poincare/src/simplify/type_selector.h b/poincare/src/simplification/selector/type_selector.h similarity index 67% rename from poincare/src/simplify/type_selector.h rename to poincare/src/simplification/selector/type_selector.h index 7b2b8d248..9caf9b704 100644 --- a/poincare/src/simplify/type_selector.h +++ b/poincare/src/simplification/selector/type_selector.h @@ -1,21 +1,22 @@ -#ifndef POINCARE_SIMPLIFY_TYPE_SELECTOR_H -#define POINCARE_SIMPLIFY_TYPE_SELECTOR_H +#ifndef POINCARE_SIMPLIFICATION_SELECTOR_TYPE_SELECTOR_H +#define POINCARE_SIMPLIFICATION_SELECTOR_TYPE_SELECTOR_H #include "selector.h" namespace Poincare { +namespace Simplification { class TypeSelector : public Selector { public: constexpr TypeSelector(Expression::Type type, int captureIndex = -1, const Selector * const * children = nullptr, int numberOfChildren = 0) : - Selector(captureIndex, children, numberOfChildren), - m_type(type) {}; + Selector(captureIndex, children, numberOfChildren), m_type(type) {} bool immediateMatch(const Expression * e) const override; bool acceptsLocationInCombination(const Combination * combination, int location) const override; private: Expression::Type m_type; }; +} } #endif diff --git a/poincare/src/simplify/integer_addition.cpp b/poincare/src/simplification/transform/integer_addition.cpp similarity index 100% rename from poincare/src/simplify/integer_addition.cpp rename to poincare/src/simplification/transform/integer_addition.cpp diff --git a/poincare/src/simplify/integer_addition.h b/poincare/src/simplification/transform/integer_addition.h similarity index 59% rename from poincare/src/simplify/integer_addition.h rename to poincare/src/simplification/transform/integer_addition.h index 59c0eab10..82813bfba 100644 --- a/poincare/src/simplify/integer_addition.h +++ b/poincare/src/simplification/transform/integer_addition.h @@ -1,9 +1,10 @@ -#ifndef POINCARE_SIMPLIFY_INTEGER_ADDITION_H -#define POINCARE_SIMPLIFY_INTEGER_ADDITION_H +#ifndef POINCARE_SIMPLIFICATION_TRANSFORM_INTEGER_ADDITION_H +#define POINCARE_SIMPLIFICATION_TRANSFORM_INTEGER_ADDITION_H #include "transform.h" namespace Poincare { +namespace Simplification { class IntegerAddition : public Transform { public: @@ -11,6 +12,7 @@ public: void apply(Expression * root, Expression * captures[]) const override; }; +} } #endif diff --git a/poincare/src/simplification/transform/integer_pair_transform.h b/poincare/src/simplification/transform/integer_pair_transform.h new file mode 100644 index 000000000..82c03cdef --- /dev/null +++ b/poincare/src/simplification/transform/integer_pair_transform.h @@ -0,0 +1,17 @@ +#ifndef POINCARE_SIMPLIFICATION_INTEGER_PAIR_TRANSFORM_H +#define POINCARE_SIMPLIFICATION_INTEGER_PAIR_TRANSFORM_H + +#include "transform.h" + +namespace Poincare { + +class IntegerPairTransform : public Transform { +public: + constexpr IntegerPairTransform() {}; + void apply(Expression * root, Expression * captures[]) const override; + virtual Integer process(const Integer & a, const Integer & b) const = 0; +}; + +} + +#endif diff --git a/poincare/src/simplify/merge_addition.cpp b/poincare/src/simplification/transform/merge_addition_transform.cpp similarity index 74% rename from poincare/src/simplify/merge_addition.cpp rename to poincare/src/simplification/transform/merge_addition_transform.cpp index d4bd2b3d9..0f60d66f2 100644 --- a/poincare/src/simplify/merge_addition.cpp +++ b/poincare/src/simplification/transform/merge_addition_transform.cpp @@ -1,10 +1,11 @@ -#include "merge_addition.h" +#include "merge_addition_transform.h" #include #include namespace Poincare { +namespace Simplification { -void MergeAddition::apply(Expression * root, Expression * captures[]) const { +void MergeAdditionTransform::apply(Expression * root, Expression * captures[]) const { assert(captures[0]->type() == Expression::Type::Addition); assert(captures[1]->type() == Expression::Type::Addition); assert(captures[1] == root); @@ -18,3 +19,4 @@ void MergeAddition::apply(Expression * root, Expression * captures[]) const { } } +} diff --git a/poincare/src/simplification/transform/merge_addition_transform.h b/poincare/src/simplification/transform/merge_addition_transform.h new file mode 100644 index 000000000..badafb5c3 --- /dev/null +++ b/poincare/src/simplification/transform/merge_addition_transform.h @@ -0,0 +1,18 @@ +#ifndef POINCARE_SIMPLIFICATION_TRANSFORM_MERGE_ADDITION_TRANSFORM_H +#define POINCARE_SIMPLIFICATION_TRANSFORM_MERGE_ADDITION_TRANSFORM_H + +#include "transform.h" + +namespace Poincare { +namespace Simplification { + +class MergeAdditionTransform : public Transform { +public: + constexpr MergeAdditionTransform() {}; + void apply(Expression * root, Expression * captures[]) const override; +}; + +} +} + +#endif diff --git a/poincare/src/simplification/transform/reduce_fractions.cpp b/poincare/src/simplification/transform/reduce_fractions.cpp new file mode 100644 index 000000000..0833ee309 --- /dev/null +++ b/poincare/src/simplification/transform/reduce_fractions.cpp @@ -0,0 +1,69 @@ +// Match a pattern Int*Int^-1 +// can match pow(6,-1)*ln(x)*4. We want 2/3.ln(x). +bool SimplificationIntegerFraction(Multiplication * multiplication, Integer * numerator, Power * power, Integer * denominator) { + Integer gcd = Arithmetic::GCD(*numerator, *denominator); + if (gcd.isEqualTo(Integer(1))) { + return false; + } + IntegerDivision numeratorDivision(*numerator, gcd); + assert(numeratorDivision.remainder().isEqualTo(Integer(0))); + IntegerDivision denominatorDivision(*denominator, gcd); + assert(denominatorDivision.remainder().isEqualTo(Integer(0))); + + multiplication->replaceOperand(numerator, numeratorDivision.quotient().clone()); + power->replaceOperand(denominator, denominatorDivision.quotient().clone()); + + return true; +} + +bool SimplificationIntegerAddition(Addition * addition, Integer * first, Integer * second) { + Integer result = Integer::Addition(*first, *second); + if (addition->numberOfOperands() == 2) { + addition->parent()->replaceOperand(addition, result.clone()); + } else { + assert(addition->numberOfOperands() > 2); + addition->replaceOperand(first, result.clone()); + addition->removeOperand(second); + } + return true; +} + +// cos(pi*3*x) +void SimplificationCosineIntegerPi(Cosine * cosine, Multiplication * multiplication, Integer * integer) { + if (multiplication->numberOfChildren() != 2) { + // We only handle cases with cos(Integer*Pi) + return false; + } +} + +// OK, on fait une classe Start qui hérite de Expression +// +Expression * simplify() { +} + + +class Start : StaticHierarchy<1> { +public: + Start(Expression * e) : StaticHierarchy<1>({e}, false); + void simplify(); +}; + +void maFonction() { +} + +class SimplifiableExpression : public Expression { + +}; + +void autreFonction() { + Expression * e = Parse("1+2+3"); + Expresion * simplified = e->simplify(); +} + +class Expression { + void simplify() { + assert(type() == Start); + //Expression * start = new Start(this); + //return start->simplify()->firstChild(); + } +}; diff --git a/poincare/src/simplification/transform/subtraction_transform.cpp b/poincare/src/simplification/transform/subtraction_transform.cpp new file mode 100644 index 000000000..684dfa158 --- /dev/null +++ b/poincare/src/simplification/transform/subtraction_transform.cpp @@ -0,0 +1,40 @@ +#include "subtraction_transform.h" +#include +#include +#include +#include +#include + +namespace Poincare { + +void SubtractionTransform::apply(Expression * root, Expression * captures[]) const { + assert(captures[0]->type() == Expression::Type::Subtraction); + assert(captures[0] == root); + + Subtraction * s = (subtraction *)(root); + + Expression * operands[] = { + new Integer(-1), + s->operands(1) + }; + + Multiplication * m = new Multiplication(operands, 2, false); + + Addition * a = new Addition( + s->parent()->replaceOperand(s, + + Integer resultOnStack = i1->add(*i2); + Integer * r = new Integer(std::move(resultOnStack)); + //r->add(resultOnStack); + // FIXME: Beeeeuargl + + if (a->numberOfOperands() == 2) { + ((Hierarchy *)a->parent())->replaceOperand(a, r); + } else { + assert(a->numberOfOperands() > 2); + a->replaceOperand(i1, r); + a->removeOperand(i2); + } +} + +} diff --git a/poincare/src/simplification/transform/subtraction_transform.h b/poincare/src/simplification/transform/subtraction_transform.h new file mode 100644 index 000000000..49e498674 --- /dev/null +++ b/poincare/src/simplification/transform/subtraction_transform.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_SIMPLIFICATION_TRANSFORM_SUBTRACTION_TRANSFORM_H +#define POINCARE_SIMPLIFICATION_TRANSFORM_SUBTRACTION_TRANSFORM_H + +#include "../transform.h" + +namespace Poincare { + +class SubtractionTransform : public Transform { +public: + constexpr SubtractionTransform() {}; + void apply(Expression * root, Expression * captures[]) const override; +}; + +} + +#endif diff --git a/poincare/src/simplify/transform.h b/poincare/src/simplification/transform/transform.h similarity index 55% rename from poincare/src/simplify/transform.h rename to poincare/src/simplification/transform/transform.h index 53d80e4e3..05802154a 100644 --- a/poincare/src/simplify/transform.h +++ b/poincare/src/simplification/transform/transform.h @@ -1,15 +1,17 @@ -#ifndef POINCARE_SIMPLIFY_TRANSFORM_H -#define POINCARE_SIMPLIFY_TRANSFORM_H +#ifndef POINCARE_SIMPLIFICATION_TRANSFORM_TRANSFORM_H +#define POINCARE_SIMPLIFICATION_TRANSFORM_TRANSFORM_H #include namespace Poincare { +namespace Simplification { class Transform { public: virtual void apply(Expression * root, Expression * captures[]) const = 0; }; +} } #endif diff --git a/poincare/src/simplify/expression_builder.cpp b/poincare/src/simplify/expression_builder.cpp deleted file mode 100644 index 06d8975dd..000000000 --- a/poincare/src/simplify/expression_builder.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "expression_builder.h" -#include -#include -#include -#include -extern "C" { -#include -} - -namespace Poincare { - -Expression * ExpressionBuilder::build(ExpressionMatch matches[]) { - Expression * children_expressions[255]; // FIXME: <- The sized can be given by the compiler - //Expression * children_expressions = malloc; - // That malloc can be avoided: we can give an upper bound - // Afer we've finished processing the rules - // That upper bound is likely to be very small (3, currently) - int numberOfChildrenExpressions = 0; - - for (int i=0; ichild(i); - if (child->m_action == ExpressionBuilder::Action::BringUpWildcard) { - for (int j=0; jm_matchIndex].numberOfExpressions(); j++) { - children_expressions[numberOfChildrenExpressions++] = - matches[child->m_matchIndex].expression(j)->clone(); - } - } else { - children_expressions[numberOfChildrenExpressions++] = child->build(matches); - } - } - - Expression * result = nullptr; - switch(m_action) { - case ExpressionBuilder::Action::BuildFromType: - switch(m_expressionType) { - case Expression::Type::Addition: - /* The children do not need to be cloned as they already have been - * before. */ - result = new Addition(children_expressions, false); - break; - case Expression::Type::Multiplication: - /* The children do not need to be cloned as they already have been - * before. */ - result = new Multiplication(children_expressions, false); - break; - default: - assert(false); - break; - } - break; - case ExpressionBuilder::Action::BuildFromTypeAndValue: - switch(m_expressionType) { - case Expression::Type::Integer: - result = new Integer(m_integerValue); - break; - case Expression::Type::Symbol: - result = new Symbol(m_symbolName); - break; - default: - assert(false); - break; - } - break; - case ExpressionBuilder::Action::BringUpWildcard: - // Build should never be called on BringUpWildcard action directly - assert(false); - break; - case ExpressionBuilder::Action::Clone: - // It only makes sense to clone if the match has a single expression! - assert(matches[m_matchIndex].numberOfExpressions() == 1); - result = matches[m_matchIndex].expression(0)->clone(); - break; - case ExpressionBuilder::Action::CallExternalGenerator: - result = m_generator(children_expressions, numberOfChildrenExpressions); - break; - } - return result; -} - -ExpressionBuilder * ExpressionBuilder::child(int index) { - assert(index>=0 && indexchild(index-1); - return previousChild+previousChild->m_numberOfChildren+1; // Pointer arithm. - } -} - -} diff --git a/poincare/src/simplify/expression_match.cpp b/poincare/src/simplify/expression_match.cpp deleted file mode 100644 index a0ba47ee4..000000000 --- a/poincare/src/simplify/expression_match.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "expression_match.h" - -extern "C" { -#include -#include -} - -namespace Poincare { - -ExpressionMatch::ExpressionMatch() { - m_numberOfExpressions = 0; - m_expressions = nullptr; -} - -ExpressionMatch::ExpressionMatch(const Expression ** expressions, int numberOfExpressions) { - m_numberOfExpressions = numberOfExpressions; - m_expressions = (const Expression**) malloc(m_numberOfExpressions * sizeof(Expression*)); - for (int i(0); i -#include -} - -#include -#include -#include "expression_selector.h" - -namespace Poincare { - -const uint8_t kUnmatched = 0xff; - -int ExpressionSelector::numberOfNonWildcardChildren() { - bool hasWildcard = child(m_numberOfChildren-1)->m_match == ExpressionSelector::Match::Wildcard; - int numberOfChildren = m_numberOfChildren; - if (hasWildcard) { - numberOfChildren--; - } - return numberOfChildren; -} - -int ExpressionSelector::match(const Expression * e, ExpressionMatch * matches) { - return this->match(e, matches, 0); -} - -int ExpressionSelector::match(const Expression * e, ExpressionMatch * matches, int offset) { - int numberOfMatches = 0; - - // Does the current node match? - switch(m_match) { - case ExpressionSelector::Match::Any: - // Yes, it always does! - break; - case ExpressionSelector::Match::Type: - if (e->type() != m_expressionType) { - return 0; - } - break; - case ExpressionSelector::Match::TypeAndValue: - if (e->type() != m_expressionType) { - return 0; - } - switch(e->type()) { - case Expression::Type::Integer: - { - Integer integer = Integer(m_integerValue); - if (!e->valueEquals(&integer)) { - return 0; - } - } - break; - case Expression::Type::Symbol: - { - Symbol symbol = Symbol(m_symbolName); - if (!e->valueEquals(&symbol)) { - return 0; - } - } - break; - default: - // Symbol and Integer are the only expressions which should be matched - // with a value. - assert(false); - break; - } - break; - case ExpressionSelector::Match::Wildcard: - /* This should not happen as a wildcard should be matched _before_ */ - assert(false); - break; - case ExpressionSelector::Match::SameAs: - /* Here we assume that the match can only have a single child, as we - * don't want to match on wildcards. */ - assert(matches[m_integerValue].numberOfExpressions() == 1); - if (!e->isEquivalentTo((Expression *)matches[m_sameAsPosition].expression(0))) { - return 0; - } - break; - } - - // The current node does match. Let's add it to our matches - matches[offset + numberOfMatches++] = ExpressionMatch(&e, 1); - - if (m_numberOfChildren != 0) { - int numberOfChildMatches = 0; - if (!e->isCommutative()) { - numberOfChildMatches = sequentialMatch(e, matches, offset+numberOfMatches); - } else { - numberOfChildMatches = commutativeMatch(e, matches, offset+numberOfMatches); - } - // We check whether the children matched or not. - if (numberOfChildMatches == 0) { - return 0; - } else { - numberOfMatches += numberOfChildMatches; - } - } - - return numberOfMatches; -} - -/* This tries to match the children selector sequentialy */ -int ExpressionSelector::sequentialMatch(const Expression * e, - ExpressionMatch * matches, int offset) { - int numberOfMatches = 0; - for (int i=0; ioperand(i); - - if (childSelector->m_match == ExpressionSelector::Match::Wildcard) { - assert(false); // There should not be a wildcard for non commutative op. - } else { - int numberOfChildMatches = childSelector->match( - childExpression, - matches, - offset+numberOfMatches); - if (numberOfChildMatches == 0) { - return 0; - } else { - numberOfMatches += numberOfChildMatches; - } - } - } - return numberOfMatches; -} - -/* This iterates over the combinations of possible matches in the children of - * a selector and then writes the output ExpressionMatch to matches just like - * match would do. - */ -int ExpressionSelector::commutativeMatch(const Expression * e, ExpressionMatch * matches, int offset) { - // If we have more children to match than the expression has, we cannot match. - if (e->numberOfOperands() < m_numberOfChildren) { - return 0; - } - - bool hasWildcard = child(m_numberOfChildren-1)->m_match == ExpressionSelector::Match::Wildcard; - uint8_t * selectorMatched = (uint8_t *)malloc(e->numberOfOperands()*sizeof(uint8_t)); - - /* Initialize the selectors matched to unmatched (0xff), here we assume that - * we never have more than 255 direct children selector. */ - assert(this->m_numberOfChildrennumberOfOperands(); i++) { - selectorMatched[i] = kUnmatched; - } - - /* TODO: This one's size can be determined by the compiler as this is the - * maximum number of direct children selectors. */ - uint8_t expressionMatched[5]; - - /* If we have a wildcard we do not want to try to match it to an expression - * yet. */ - int numberOfChildren = this->numberOfNonWildcardChildren(); - - if (!canCommutativelyMatch(e, matches, selectorMatched, numberOfChildren, offset)) { - free(selectorMatched); - return 0; - } - - /* Note that we need this indirection because the order in which the selectors - * are defined is significant. - * - * We can see that in the following example: - * Here we try to match: - * + - * / \ - * + w - * / - * w - * Onto: - * + - * / \ - * 4 + - * / \ - * 2 3 - * - * Since + is commutative they do match which is nice. - * The issue here is that the matches are expected in a certain order by the - * builder, here the order expected is: - * 0 - * / \ - * 1 3 - * / - * 2 - * But The nodes of the expressions are matched in this order: - * 0 - * / \ - * 1 2 - * \ - * 3 - * Which is not what we want, thus remembering which selector matched which - * expression allows us to put the match in the proper order. - * We got an expression -> selector relationship, here we are just inversting - * it to get the selector -> expression relationship that we want. */ - for (int i = 0; inumberOfOperands(); i++) { - if (selectorMatched[i] != kUnmatched) { - expressionMatched[selectorMatched[i]] = i; - } - } - - /* Here we recursively write the matches of each selector in the matches - * table. - * - * Using the example in the previous comment we would write - * | + | + | (Integer(2),Integer(3)) | Integer(4) | - * - * The pointer arithmetic with numberOfMatches, allows us to know how many - * matches a selector has written. - * Using the previous example, the part with - * + - * | - * w - * would write two matches: - * + and (Integer(2), Integer(3)) - * whereas: - * w - * would only write one: - * Integer(4) */ - int numberOfMatches = 0; - for (int i(0); imatch( - e->operand(expressionMatched[i]), - matches, - offset + numberOfMatches); - assert(numberOfChildMatches > 0); - numberOfMatches += numberOfChildMatches; - } - - if (hasWildcard) { - /* We allocate a table of Expression* the size of the number of unmatched - * operands. */ - const Expression ** local_expr = (const Expression**) malloc((e->numberOfOperands() - numberOfChildren) * sizeof(Expression*)); - int j = 0; - for (int i(0); inumberOfOperands(); i++) { - // if the expression was not matched, give it to the wildcard. - if (selectorMatched[i] == kUnmatched) { - local_expr[j++] = e->operand(i); - } - } - matches[offset + numberOfMatches++] = ExpressionMatch(local_expr, j); - free(local_expr); - } - - free(selectorMatched); - return numberOfMatches; -} - -/* This helper function finds whether there is a commutative match or not. - * The output is the selector matched for each expression, written in the - * selectorMatched table. - * The matches table will be written to, but will not overwrite any previous - * data so this is ok. - * leftToMatch tells it how many selectors still have to be matched. - * Implementation detail: selectors are matched in ascending order. - */ -bool ExpressionSelector::canCommutativelyMatch(const Expression * e, - ExpressionMatch * matches, - uint8_t * selectorMatched, - int leftToMatch, - int offset) { - bool hasWildcard = child(m_numberOfChildren-1)->m_match == ExpressionSelector::Match::Wildcard; - - // This part is used to make sure that we stop once we matched everything. - if (leftToMatch == 0) { - if (hasWildcard) { - return true; - } else { - /* We check that we matched all the children expressions. - * This can happen if the selector does not have a wildcard and we matched all - * the selectors, but there are still unmatched children expression. - * An example is the expression: - * + - * / | \ - * 1 2 3 - * Which would otherwise be matched by - * + - * / \ - * / \ - * Int Int - */ - int matchedChildren = 0; - for (int i = 0; inumberOfOperands(); i++) { - if (selectorMatched[i] != kUnmatched) { - matchedChildren++; - } - } - if (matchedChildren == e->numberOfOperands()) { - return true; - } else { - return false; - } - } - } - - // We try to match the i-th child selector. - int i = numberOfNonWildcardChildren() - leftToMatch; - for (int j = 0; jnumberOfOperands(); j++) { - // If the child has already been matched, we skip it. - if (selectorMatched[j] != kUnmatched) { - continue; - } - int numberOfMatches = child(i)->match(e->operand(j), matches, offset); - if (numberOfMatches) { - // We managed to match this selector. - selectorMatched[j] = i; - /* We check that we can match the rest in this configuration, if so we - * are good. */ - if (this->canCommutativelyMatch(e, matches, selectorMatched, leftToMatch - 1, offset + numberOfMatches)) { - return true; - } - // Otherwise we backtrack. - selectorMatched[j] = kUnmatched; - } - } - - return false; -} - -/* Extrude in a class impossible otherwise ExpressionBuilder is not aggregate - * and cannot be initialized statically. */ -ExpressionSelector * ExpressionSelector::child(int index) { - assert(index>=0 && indexchild(index-1); - return previousChild+previousChild->m_numberOfChildren+1; // Pointer arithm. - } -} - -} diff --git a/poincare/src/simplify/merge_addition.h b/poincare/src/simplify/merge_addition.h deleted file mode 100644 index a8df9676f..000000000 --- a/poincare/src/simplify/merge_addition.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_MERGE_ADDITION_H -#define POINCARE_SIMPLIFY_MERGE_ADDITION_H - -#include "transform.h" - -namespace Poincare { - -class MergeAddition : public Transform { -public: - constexpr MergeAddition() {}; - void apply(Expression * root, Expression * captures[]) const override; -}; - -} - -#endif diff --git a/poincare/src/simplify/same_as_selector.h b/poincare/src/simplify/same_as_selector.h deleted file mode 100644 index 16ade44ad..000000000 --- a/poincare/src/simplify/same_as_selector.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_SAME_AS_SELECTOR_H -#define POINCARE_SIMPLIFY_SAME_AS_SELECTOR_H - -#include "selector.h" - - namespace Poincare { - -class SameAsSelector : public Selector { -public: - constexpr SameAsSelector(int originalIndex, int captureIndex = -1, Selector ** children = nullptr, int numberOfChildren = 0); - bool acceptsLocationInCombination(const Combination * combination, int location) const override; -private: - int m_originalIndex; -}; - -constexpr SameAsSelector::SameAsSelector(int originalIndex, int captureIndex, Selector ** children, int numberOfChildren) : - Selector(captureIndex, children, numberOfChildren), - m_originalIndex(originalIndex) -{ -} - -} - -#endif diff --git a/poincare/src/simplify/simplification.cpp b/poincare/src/simplify/simplification.cpp deleted file mode 100644 index f751b62c2..000000000 --- a/poincare/src/simplify/simplification.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "simplification.h" - -namespace Poincare { - -Expression * Simplification::simplify(Expression * expression) const { - ExpressionMatch matches[255]; // FIXME: The size ca be given by our compiler - if (m_selector->match(expression, matches)) { - return m_builder->build(matches); - } else { - return nullptr; - } -} - -} diff --git a/poincare/src/simplify/simplification.h b/poincare/src/simplify/simplification.h deleted file mode 100644 index d17598dbe..000000000 --- a/poincare/src/simplify/simplification.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_SIMPLIFICATION_H -#define POINCARE_SIMPLIFY_SIMPLIFICATION_H - -#include -#include "expression_selector.h" -#include "expression_builder.h" - -namespace Poincare { - -class Simplification { -public: - constexpr Simplification(ExpressionSelector * m_selector, ExpressionBuilder * m_builder); - Expression * simplify(Expression * expression) const; -private: - ExpressionSelector * m_selector; - ExpressionBuilder * m_builder; -}; - -constexpr Simplification::Simplification( - ExpressionSelector * selector, - ExpressionBuilder * builder) - : - m_selector(selector), - m_builder(builder) { -} - -} - -#endif diff --git a/poincare/src/simplify/simplification_generator.cpp b/poincare/src/simplify/simplification_generator.cpp deleted file mode 100644 index 5f58accd7..000000000 --- a/poincare/src/simplify/simplification_generator.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "simplification_generator.h" -#include -extern "C" { -#include -} - -namespace Poincare { - -Expression * SimplificationGenerator::AddIntegers(Expression ** parameters, int numberOfParameters) { - Integer * result = new Integer((native_int_t)0); - for (int i=0; itype() == Expression::Type::Integer); - *result = result->add(*(Integer *)parameters[i]); - /* Note We have to delete the parameters as they have been cloned before and - * we are the last ones to use them here. */ - delete parameters[i]; - } - return result; -} - -Expression * SimplificationGenerator::MultiplyIntegers(Expression ** parameters, int numberOfParameters) { - Integer * result = new Integer((native_int_t)1); - for (int i=0; itype() == Expression::Type::Integer); - *result = result->multiply_by(*(Integer *)parameters[i]); - /* Note We have to delete the parameters as they have been cloned before and - * we are the last ones to use them here. */ - delete parameters[i]; - } - return result; -} - -} diff --git a/poincare/src/simplify/simplification_generator.h b/poincare/src/simplify/simplification_generator.h deleted file mode 100644 index e2f62e9fc..000000000 --- a/poincare/src/simplify/simplification_generator.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_SIMPLIFICATION_GENERATOR_H -#define POINCARE_SIMPLIFY_SIMPLIFICATION_GENERATOR_H - -#include - -namespace Poincare { - -class SimplificationGenerator { -public: - static Expression * AddIntegers(Expression ** parameters, int numberOfParameters); - static Expression * MultiplyIntegers(Expression ** parameters, int numberOfParameters); -}; - -} - -#endif diff --git a/poincare/src/simplify/type_and_value_selector.h b/poincare/src/simplify/type_and_value_selector.h deleted file mode 100644 index dc75f3a2d..000000000 --- a/poincare/src/simplify/type_and_value_selector.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef POINCARE_SIMPLIFY_TYPE_AND_VALUE_SELECTOR_H -#define POINCARE_SIMPLIFY_TYPE_AND_VALUE_SELECTOR_H - -#include "selector.h" - - namespace Poincare { - -class TypeAndValueSelector : public Selector { -public: - constexpr TypeAndValueSelector(Expression::Type type, int value, int captureIndex = -1, Selector ** children = nullptr, int numberOfChildren = 0); - bool acceptsLocationInCombination(const Combination * combination, int location) const override; -private: - Expression::Type m_type; - int m_value; -}; - -constexpr TypeAndValueSelector::TypeAndValueSelector(Expression::Type type, int value, int captureIndex, Selector ** children, int numberOfChildren) : - Selector(captureIndex, children, numberOfChildren), - m_type(type), - m_value(value) -{ -} - -} - -#endif