mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[poincare] Clean the simplification folder
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
SFLAGS += -Ipoincare/include
|
||||
|
||||
include poincare/src/simplify/Makefile
|
||||
include poincare/src/simplification/Makefile
|
||||
|
||||
objs += $(addprefix poincare/src/,\
|
||||
absolute_value.o\
|
||||
|
||||
@@ -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 \
|
||||
)
|
||||
@@ -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
|
||||
|
||||
}
|
||||
1
poincare/src/simplification/handwritten_rules.txt
Normal file
1
poincare/src/simplification/handwritten_rules.txt
Normal file
@@ -0,0 +1 @@
|
||||
Addition(Integer.a,Integer.b) -> IntegerAddition
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
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() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 <poincare/expression.h>
|
||||
#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
|
||||
21
poincare/src/simplification/selector/same_as_selector.h
Normal file
21
poincare/src/simplification/selector/same_as_selector.h
Normal file
@@ -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
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
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 {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 <poincare/expression.h>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,10 +1,11 @@
|
||||
#include "merge_addition.h"
|
||||
#include "merge_addition_transform.h"
|
||||
#include <assert.h>
|
||||
#include <poincare/addition.h>
|
||||
|
||||
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 {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
69
poincare/src/simplification/transform/reduce_fractions.cpp
Normal file
69
poincare/src/simplification/transform/reduce_fractions.cpp
Normal file
@@ -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();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "subtraction_transform.h"
|
||||
#include <assert.h>
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/subtraction.h>
|
||||
#include <utility>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
namespace Simplification {
|
||||
|
||||
class Transform {
|
||||
public:
|
||||
virtual void apply(Expression * root, Expression * captures[]) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,90 +0,0 @@
|
||||
#include "expression_builder.h"
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/integer.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/symbol.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
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; i<m_numberOfChildren; i++) {
|
||||
ExpressionBuilder * child = this->child(i);
|
||||
if (child->m_action == ExpressionBuilder::Action::BringUpWildcard) {
|
||||
for (int j=0; j<matches[child->m_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 && index<m_numberOfChildren);
|
||||
if (index == 0) {
|
||||
return (this+1); // Pointer arithmetics
|
||||
} else {
|
||||
ExpressionBuilder * previousChild = this->child(index-1);
|
||||
return previousChild+previousChild->m_numberOfChildren+1; // Pointer arithm.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#include "expression_match.h"
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
}
|
||||
|
||||
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<numberOfExpressions; i++) {
|
||||
m_expressions[i] = expressions[i];
|
||||
}
|
||||
}
|
||||
|
||||
ExpressionMatch::~ExpressionMatch() {
|
||||
if (m_numberOfExpressions != 0) {
|
||||
free(m_expressions);
|
||||
}
|
||||
}
|
||||
|
||||
const Expression * ExpressionMatch::expression(int i) {
|
||||
assert(i < m_numberOfExpressions);
|
||||
return m_expressions[i];
|
||||
}
|
||||
|
||||
int ExpressionMatch::numberOfExpressions() {
|
||||
return m_numberOfExpressions;
|
||||
}
|
||||
|
||||
ExpressionMatch& ExpressionMatch::operator=(ExpressionMatch&& other) {
|
||||
m_numberOfExpressions = other.m_numberOfExpressions;
|
||||
// Here we make sure that the memory containing the expressions is not freed
|
||||
// in order to avoid a double free
|
||||
other.m_numberOfExpressions = 0;
|
||||
m_expressions = other.m_expressions;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
}
|
||||
|
||||
#include <poincare/integer.h>
|
||||
#include <poincare/symbol.h>
|
||||
#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; i<m_numberOfChildren; i++) {
|
||||
ExpressionSelector * childSelector = child(i);
|
||||
const Expression * childExpression = e->operand(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_numberOfChildren<kUnmatched);
|
||||
for (int i(0); i<e->numberOfOperands(); 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; i<e->numberOfOperands(); 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); i<numberOfChildren; i++) {
|
||||
int numberOfChildMatches = child(i)->match(
|
||||
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); i<e->numberOfOperands(); 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; i<e->numberOfOperands(); 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; j<e->numberOfOperands(); 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 && index<m_numberOfChildren);
|
||||
if (index == 0) {
|
||||
return (this+1); // Pointer arithmetics
|
||||
} else {
|
||||
ExpressionSelector * previousChild = this->child(index-1);
|
||||
return previousChild+previousChild->m_numberOfChildren+1; // Pointer arithm.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#ifndef POINCARE_SIMPLIFY_SIMPLIFICATION_H
|
||||
#define POINCARE_SIMPLIFY_SIMPLIFICATION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#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
|
||||
@@ -1,33 +0,0 @@
|
||||
#include "simplification_generator.h"
|
||||
#include <poincare/integer.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
Expression * SimplificationGenerator::AddIntegers(Expression ** parameters, int numberOfParameters) {
|
||||
Integer * result = new Integer((native_int_t)0);
|
||||
for (int i=0; i<numberOfParameters; i++) {
|
||||
assert(parameters[i]->type() == 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; i<numberOfParameters; i++) {
|
||||
assert(parameters[i]->type() == 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef POINCARE_SIMPLIFY_SIMPLIFICATION_GENERATOR_H
|
||||
#define POINCARE_SIMPLIFY_SIMPLIFICATION_GENERATOR_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class SimplificationGenerator {
|
||||
public:
|
||||
static Expression * AddIntegers(Expression ** parameters, int numberOfParameters);
|
||||
static Expression * MultiplyIntegers(Expression ** parameters, int numberOfParameters);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user