[Git] Fix conflicts

This commit is contained in:
Quentin
2020-04-01 00:17:17 +02:00
14 changed files with 104 additions and 44 deletions

View File

@@ -374,7 +374,7 @@ void CurveView::drawLabelsAndGraduations(KDContext * ctx, KDRect rect, Axis axis
position = positionLabel(horizontalCoordinate, labelPosition, textSize, RelativePosition::Before, RelativePosition::None);
if (floatingLabels == FloatingPosition::Min) {
position = KDPoint(k_labelMargin, position.y());
} else if (floatingLabels == FloatingPosition::Min) {
} else if (floatingLabels == FloatingPosition::Max) {
position = KDPoint(Ion::Display::Width - textSize.width() - k_labelMargin, position.y());
}
}

View File

@@ -211,7 +211,16 @@ EquationStore::Error EquationStore::privateExactSolve(Poincare::Context * contex
// Step 3. Polynomial & Monovariable?
assert(numberOfVariables == 1 && numberOfDefinedModels() == 1);
Expression polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients];
int degree = modelForRecord(definedRecordAtIndex(0))->standardForm(context, replaceFunctionsButNotSymbols).getPolynomialReducedCoefficients(m_variables[0], polynomialCoefficients, context, updatedComplexFormat(context), preferences->angleUnit(), replaceFunctionsButNotSymbols ? ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions : ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
int degree = modelForRecord(definedRecordAtIndex(0))->standardForm(context, replaceFunctionsButNotSymbols)
.getPolynomialReducedCoefficients(
m_variables[0],
polynomialCoefficients,
context,
updatedComplexFormat(context),
preferences->angleUnit(),
replaceFunctionsButNotSymbols ?
ExpressionNode::SymbolicComputation::ReplaceDefinedFunctionsWithDefinitions :
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition);
if (degree == 2) {
// Polynomial degree <= 2
m_type = Type::PolynomialMonovariable;
@@ -262,7 +271,9 @@ EquationStore::Error EquationStore::resolveLinearSystem(Expression exactSolution
Preferences::AngleUnit angleUnit = Preferences::sharedPreferences()->angleUnit();
// n unknown variables
int n = 0;
while (m_variables[n][0] != 0) { n++; }
while (n < Expression::k_maxNumberOfVariables && m_variables[n][0] != 0) {
n++;
}
int m = numberOfDefinedModels(); // m equations
/* Create the matrix (A | b) for the equation Ax=b */
Matrix Ab = Matrix::Builder();

View File

@@ -76,6 +76,7 @@ class Expression : public TreeHandle {
friend class NthRoot;
friend class Number;
friend class Opposite;
friend class ParameteredExpression;
friend class Parenthesis;
friend class PermuteCoefficient;
friend class Power;
@@ -347,8 +348,8 @@ protected:
Expression defaultReplaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression expression);
/* 'deepReplaceReplaceableSymbols' returns an uninitialized expression if it
* is circularly defined. Same convention as for 'ExpressionWithoutSymbols'.*/
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) { return node()->deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly); }
Expression defaultReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly);
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) { return node()->deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount); }
Expression defaultReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
/* Simplification */
void beautifyAndApproximateScalar(Expression * simplifiedExpression, Expression * approximateExpression, ExpressionNode::ReductionContext userReductionContext, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit);

View File

@@ -172,7 +172,7 @@ public:
/*!*/ virtual Expression setSign(Sign s, ReductionContext reductionContext);
virtual int polynomialDegree(Context * context, const char * symbolName) const;
/*!*/ virtual int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
/*!*/ virtual Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly);
/*!*/ virtual Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
typedef bool (*isVariableTest)(const char * c, Poincare::Context * context);
virtual int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const;
virtual float characteristicXRange(Context * context, Preferences::AngleUnit angleUnit) const;

View File

@@ -41,7 +41,7 @@ private:
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) override;
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) override;
LayoutShape leftLayoutShape() const override { return strlen(m_name) > 1 ? LayoutShape::MoreLetters : LayoutShape::OneLetter; };
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
@@ -60,7 +60,7 @@ public:
// Simplification
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly);
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
};
}

View File

@@ -14,6 +14,8 @@ public:
// Expression
bool isParameteredExpression() const override { return true; }
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) override;
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) override;
// Expression properties
int getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const override;
};
@@ -36,6 +38,8 @@ public:
* f(X)=diff(cos(x),x,X), X being an unknown. ReplaceUnknownInExpression does
* that. */
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression);
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
Symbol parameter();
protected:
ParameteredExpression(const ParameteredExpressionNode * node) : Expression(node) {}
};

View File

@@ -34,7 +34,7 @@ public:
/* Simplification */
Expression shallowReduce(ReductionContext reductionContext) override;
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) override;
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) override;
LayoutShape leftLayoutShape() const override;
/* Approximation */
@@ -71,7 +71,7 @@ public:
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression);
int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const;
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly);
Expression deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount);
private:
SymbolNode * node() const { return static_cast<SymbolNode *>(Expression::node()); }
};

View File

@@ -66,6 +66,7 @@ class SymbolAbstract : public Expression {
friend class SymbolAbstractNode;
public:
const char * name() const { return node()->name(); }
bool hasSameNameAs(const SymbolAbstract & other) const;
static size_t TruncateExtension(char * dst, const char * src, size_t len);
static bool matches(const SymbolAbstract & symbol, ExpressionTest test, Context * context);
constexpr static size_t k_maxNameSize = 8;

View File

@@ -394,10 +394,10 @@ void Expression::defaultSetChildrenInPlace(Expression other) {
}
}
Expression Expression::defaultReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) {
Expression Expression::defaultReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
int nbChildren = numberOfChildren();
for (int i = 0; i < nbChildren; i++) {
Expression c = childAtIndex(i).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly);
Expression c = childAtIndex(i).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount);
if (c.isUninitialized()) { // the expression is circularly defined, escape
return Expression();
}
@@ -746,7 +746,7 @@ Expression Expression::ExpressionWithoutSymbols(Expression e, Context * context,
break;
}
didReplace = false;
e = e.deepReplaceReplaceableSymbols(context, &didReplace, replaceFunctionsOnly);
e = e.deepReplaceReplaceableSymbols(context, &didReplace, replaceFunctionsOnly, 0);
if (e.isUninitialized()) { // the expression is circularly defined, escape
replacementCount = k_maxSymbolReplacementsCount;
}

View File

@@ -36,8 +36,8 @@ int ExpressionNode::getPolynomialCoefficients(Context * context, const char * sy
return Expression(this).defaultGetPolynomialCoefficients(context, symbolName, coefficients);
}
Expression ExpressionNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) {
return Expression(this).defaultReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly);
Expression ExpressionNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
return Expression(this).defaultReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount);
}
int ExpressionNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const {

View File

@@ -65,8 +65,8 @@ Expression FunctionNode::shallowReduce(ReductionContext reductionContext) {
return Function(this).shallowReduce(reductionContext); // This uses Symbol::shallowReduce
}
Expression FunctionNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) {
return Function(this).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly);
Expression FunctionNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
return Function(this).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount);
}
Evaluation<float> FunctionNode::approximate(SinglePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
@@ -102,7 +102,7 @@ Function Function::Builder(const char * name, size_t length, Expression child) {
Expression Function::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) {
// Replace the symbol in the child
childAtIndex(0).replaceSymbolWithExpression(symbol, expression);
if (symbol.type() == ExpressionNode::Type::Function && strcmp(name(), symbol.name()) == 0) {
if (symbol.type() == ExpressionNode::Type::Function && hasSameNameAs(symbol)) {
Expression value = expression.clone();
Expression p = parent();
if (!p.isUninitialized() && p.node()->childAtIndexNeedsUserParentheses(value, p.indexOfChild(*this))) {
@@ -133,13 +133,15 @@ Expression Function::shallowReduce(ExpressionNode::ReductionContext reductionCon
return result.deepReduce(reductionContext);
}
Expression Function::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) {
// Replace replaceable symbols in child
Expression self = defaultReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly);
if (self.isUninitialized()) { // if the child is circularly defined, escape
return self;
Expression Function::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
{
// Replace replaceable symbols in child
Expression self = defaultReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly ,parameteredAncestorsCount);
if (self.isUninitialized()) { // if the child is circularly defined, escape
return self;
}
assert(*this == self);
}
assert(*this == self);
Expression e = context->expressionForSymbolAbstract(*this, false);
if (e.isUninitialized()) {
return *this;

View File

@@ -9,6 +9,10 @@ Expression ParameteredExpressionNode::replaceSymbolWithExpression(const SymbolAb
return ParameteredExpression(this).replaceSymbolWithExpression(symbol, expression);
}
Expression ParameteredExpressionNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
return ParameteredExpression(this).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount);
}
int ParameteredExpressionNode::getVariables(Context * context, isVariableTest isVariable, char * variables, int maxSizeVariable, int nextVariableIndex) const {
int numberOfVariables = childAtIndex(ParameteredExpression::ParameteredChildIndex())->getVariables(context, isVariable, variables, maxSizeVariable, nextVariableIndex);
// Handle exception
@@ -17,11 +21,9 @@ int ParameteredExpressionNode::getVariables(Context * context, isVariableTest is
}
/* Remove the parameter symbol from the list of variable if it was added at
* the previous line */
// Get the parameter symbol
assert(childAtIndex(ParameteredExpression::ParameterChildIndex())->type() == ExpressionNode::Type::Symbol);
SymbolNode * parameterChild = static_cast<SymbolNode *>(childAtIndex(ParameteredExpression::ParameterChildIndex()));
const char * parameterName = ParameteredExpression(this).parameter().name();
for (int i = nextVariableIndex; i < numberOfVariables; i++) {
if (strcmp(parameterChild->name(), &variables[i]) == 0) {
if (strcmp(parameterName, &variables[i]) == 0) {
variables[i] = 0;
numberOfVariables--;
break;
@@ -42,11 +44,7 @@ int ParameteredExpressionNode::getVariables(Context * context, isVariableTest is
}
Expression ParameteredExpression::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) {
Expression c = childAtIndex(ParameterChildIndex());
assert(c.type() == ExpressionNode::Type::Symbol);
Symbol& parameterChild = static_cast<Symbol &>(c);
if (symbol.type() != ExpressionNode::Type::Symbol ||
strcmp(symbol.name(), parameterChild.name()) != 0) {
if (symbol.type() != ExpressionNode::Type::Symbol || !parameter().hasSameNameAs(symbol)) {
// If the symbol is not the parameter, replace normally
return defaultReplaceSymbolWithExpression(symbol, expression);
}
@@ -62,4 +60,31 @@ Expression ParameteredExpression::replaceSymbolWithExpression(const SymbolAbstra
return *this;
}
Expression ParameteredExpression::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
/* All children replaceable symbols should be replaced apart from symbols that
* are parameters in parametered expressions.*/
int childrenCount = numberOfChildren();
for (int i = 0; i < childrenCount; i++) {
if (i == ParameterChildIndex()) {
// Do not replace symbols in the parameter child
continue;
}
/* In the parametered child, increase the parametered ancestors count so
* that when replacing symbols, the expressions check that the symbols are
* not the parametered symbols. */
bool shouldIncreaseParameteredAncestorsCount = i == ParameteredChildIndex();
Expression c = childAtIndex(i).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount + (shouldIncreaseParameteredAncestorsCount ? 1 : 0));
if (c.isUninitialized()) { // the expression is circularly defined, escape
return Expression();
}
}
return *this;
}
Symbol ParameteredExpression::parameter() {
Expression e = childAtIndex(ParameteredExpression::ParameterChildIndex());
assert(e.type() == ExpressionNode::Type::Symbol);
return static_cast<Symbol&>(e);
}
}

View File

@@ -94,8 +94,8 @@ Expression SymbolNode::shallowReduce(ReductionContext reductionContext) {
return Symbol(this).shallowReduce(reductionContext);
}
Expression SymbolNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) {
return Symbol(this).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly);
Expression SymbolNode::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
return Symbol(this).deepReplaceReplaceableSymbols(context, didReplace, replaceFunctionsOnly, parameteredAncestorsCount);
}
ExpressionNode::LayoutShape SymbolNode::leftLayoutShape() const {
@@ -169,13 +169,10 @@ Expression Symbol::shallowReduce(ExpressionNode::ReductionContext reductionConte
// The symbol is a paremetered expression's parameter
return *this;
}
if (index == ParameteredExpression::ParameteredChildIndex()) {
assert(p.childAtIndex(ParameteredExpression::ParameterChildIndex()).type() == ExpressionNode::Type::Symbol);
Expression untypedParameter = p.childAtIndex(ParameteredExpression::ParameterChildIndex());
Symbol parameter = static_cast<Symbol &>(untypedParameter);
if (strcmp(parameter.name(), name()) == 0) {
return *this;
}
if (index == ParameteredExpression::ParameteredChildIndex()
&& hasSameNameAs(static_cast<ParameteredExpression&>(p).parameter()))
{
return *this;
}
}
current = p;
@@ -196,7 +193,7 @@ Expression Symbol::shallowReduce(ExpressionNode::ReductionContext reductionConte
}
Expression Symbol::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) {
if (symbol.type() == ExpressionNode::Type::Symbol && strcmp(name(), symbol.name()) == 0) {
if (symbol.type() == ExpressionNode::Type::Symbol && hasSameNameAs(symbol)) {
Expression value = expression.clone();
Expression p = parent();
if (!p.isUninitialized() && p.node()->childAtIndexNeedsUserParentheses(value, p.indexOfChild(*this))) {
@@ -218,10 +215,25 @@ int Symbol::getPolynomialCoefficients(Context * context, const char * symbolName
return 0;
}
Expression Symbol::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly) {
Expression Symbol::deepReplaceReplaceableSymbols(Context * context, bool * didReplace, bool replaceFunctionsOnly, int parameteredAncestorsCount) {
if (replaceFunctionsOnly || isSystemSymbol()) {
return *this;
}
// Check that this is not a parameter in a parametered expression
Expression ancestor = *this;
while (parameteredAncestorsCount > 0) {
ancestor = ancestor.parent();
assert(!ancestor.isUninitialized());
if (ancestor.isParameteredExpression()) {
parameteredAncestorsCount--;
Symbol ancestorParameter = static_cast<ParameteredExpression&>(ancestor).parameter();
if (hasSameNameAs(ancestorParameter)) {
return *this;
}
}
}
Expression e = context->expressionForSymbolAbstract(*this, true);
if (e.isUninitialized()) {
return *this;

View File

@@ -53,6 +53,10 @@ T SymbolAbstract::Builder(const char * name, int length) {
return static_cast<T &>(h);
}
bool SymbolAbstract::hasSameNameAs(const SymbolAbstract & other) const {
return strcmp(other.name(), name()) == 0;
}
size_t SymbolAbstract::TruncateExtension(char * dst, const char * src, size_t len) {
return UTF8Helper::CopyUntilCodePoint(dst, len, src, '.');
}