mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Context::expressionForSymbol takes a boolean notifying that
we want a copy or not
This commit is contained in:
@@ -9,7 +9,7 @@ using namespace Shared;
|
||||
|
||||
namespace Regression {
|
||||
|
||||
const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & symbol) {
|
||||
const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
|
||||
if (symbol.type() == ExpressionNode::Type::Symbol && Symbol::isRegressionSymbol(symbol.name())) {
|
||||
const char * seriesName = symbol.name();
|
||||
assert(strlen(seriesName) == 2);
|
||||
@@ -24,7 +24,7 @@ const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & s
|
||||
assert(m_seriesPairIndex < m_store->numberOfPairsOfSeries(series));
|
||||
return Float<double>(m_store->get(series, storeI, m_seriesPairIndex));
|
||||
} else {
|
||||
return m_parentContext->expressionForSymbol(symbol);
|
||||
return m_parentContext->expressionForSymbol(symbol, clone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Regression {
|
||||
class RegressionContext : public Shared::StoreContext {
|
||||
public:
|
||||
using Shared::StoreContext::StoreContext;
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ CacheContext<T>::CacheContext(Context * parentContext) :
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const Expression CacheContext<T>::expressionForSymbol(const SymbolAbstract & symbol) {
|
||||
const Expression CacheContext<T>::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
|
||||
// [u|v](n(+1)?)
|
||||
if (symbol.type() == ExpressionNode::Type::Symbol
|
||||
&& (symbol.name()[0] == SequenceStore::k_sequenceNames[0][0] || symbol.name()[0] == SequenceStore::k_sequenceNames[1][0])
|
||||
@@ -24,7 +24,7 @@ const Expression CacheContext<T>::expressionForSymbol(const SymbolAbstract & sym
|
||||
Symbol s = const_cast<Symbol &>(static_cast<const Symbol &>(symbol));
|
||||
return Float<T>(m_values[nameIndexForSymbol(s)][rankIndexForSymbol(s)]);
|
||||
}
|
||||
return VariableContext::expressionForSymbol(symbol);
|
||||
return VariableContext::expressionForSymbol(symbol, clone);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -13,7 +13,7 @@ template<typename T>
|
||||
class CacheContext : public Poincare::VariableContext {
|
||||
public:
|
||||
CacheContext(Poincare::Context * parentContext);
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
|
||||
void setValueForSymbol(T value, const Poincare::Symbol & symbol);
|
||||
private:
|
||||
int nameIndexForSymbol(const Poincare::Symbol & symbol);
|
||||
|
||||
@@ -45,8 +45,8 @@ public:
|
||||
* context respective methods. Indeed, special chars like n, u(n), u(n+1),
|
||||
* v(n), v(n+1) are taken into accound only when evaluating sequences which
|
||||
* is done in another context. */
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override {
|
||||
return m_parentContext->expressionForSymbol(symbol);
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override {
|
||||
return m_parentContext->expressionForSymbol(symbol, clone);
|
||||
}
|
||||
void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override {
|
||||
m_parentContext->setExpressionForSymbol(expression, symbol, context);
|
||||
|
||||
@@ -60,7 +60,7 @@ void GlobalContext::DestroyRecordsBaseNamedWithoutExtension(const char * baseNam
|
||||
}
|
||||
}
|
||||
|
||||
const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbol) {
|
||||
const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
|
||||
Ion::Storage::Record r = SymbolAbstractRecordWithBaseName(symbol.name());
|
||||
return ExpressionForSymbolAndRecord(symbol, r);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
/* Expression for symbol
|
||||
* The expression recorded in global context is already an expression.
|
||||
* Otherwise, we would need the context and the angle unit to evaluate it */
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
|
||||
void setExpressionForSymbol(
|
||||
const Poincare::Expression & expression,
|
||||
const Poincare::SymbolAbstract & symbol,
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace Shared;
|
||||
|
||||
namespace Statistics {
|
||||
|
||||
const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & symbol) {
|
||||
const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
|
||||
if (symbol.type() == ExpressionNode::Type::Symbol && Symbol::isSeriesSymbol(symbol.name())) {
|
||||
const char * seriesName = symbol.name();
|
||||
assert(strlen(seriesName) == 2);
|
||||
@@ -24,7 +24,7 @@ const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & s
|
||||
assert(m_seriesPairIndex < m_store->numberOfPairsOfSeries(series));
|
||||
return Float<double>(m_store->get(series, storeI, m_seriesPairIndex));
|
||||
} else {
|
||||
return m_parentContext->expressionForSymbol(symbol);
|
||||
return m_parentContext->expressionForSymbol(symbol, clone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Statistics {
|
||||
class StatisticsContext : public Shared::StoreContext {
|
||||
public:
|
||||
using Shared::StoreContext::StoreContext;
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ class SymbolAbstract;
|
||||
|
||||
class Context {
|
||||
public:
|
||||
virtual const Expression expressionForSymbol(const SymbolAbstract & symbol) = 0;
|
||||
virtual const Expression expressionForSymbol(const SymbolAbstract & symbol, bool clone) = 0;
|
||||
virtual void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
Expression replaceReplaceableSymbols(Context & context);
|
||||
private:
|
||||
SymbolNode * node() const { return static_cast<SymbolNode *>(Expression::node()); }
|
||||
Expression expand(Context & context) const;
|
||||
Expression expand(Context & context, bool cloneContextValue) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
static size_t TruncateExtension(char * dst, const char * src, size_t len);
|
||||
static bool ValidInContext(SymbolAbstract & s, Context * context) {
|
||||
// Retrive from context the expression corresponding to s
|
||||
Expression f = context ? context->expressionForSymbol(s) : Expression();
|
||||
Expression f = context ? context->expressionForSymbol(s, false) : Expression();
|
||||
return f.isUninitialized() || f.type() == s.type();
|
||||
}
|
||||
constexpr static size_t k_maxNameSize = 8;
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
|
||||
// Context
|
||||
void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) override;
|
||||
const Expression expressionForSymbol(const SymbolAbstract & symbol) override;
|
||||
const Expression expressionForSymbol(const SymbolAbstract & symbol, bool clone) override;
|
||||
|
||||
private:
|
||||
const char * m_name;
|
||||
|
||||
@@ -227,9 +227,9 @@ bool Expression::hasReplaceableSymbols(Context & context) const {
|
||||
return recursivelyMatches([](const Expression e, Context & context, bool replaceSymbols) {
|
||||
return (e.type() == ExpressionNode::Type::Symbol
|
||||
&& !static_cast<const Symbol &>(e).isSystemSymbol()
|
||||
&& !context.expressionForSymbol(static_cast<const Symbol &>(e)).isUninitialized())
|
||||
&& !context.expressionForSymbol(static_cast<const Symbol &>(e), false).isUninitialized())
|
||||
|| (e.type() == ExpressionNode::Type::Function
|
||||
&& !context.expressionForSymbol(static_cast<const Function &>(e)).isUninitialized());
|
||||
&& !context.expressionForSymbol(static_cast<const Function &>(e), false).isUninitialized());
|
||||
}, context, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ Expression Function::shallowReduce(Context & context, Preferences::AngleUnit ang
|
||||
}
|
||||
|
||||
Expression Function::replaceReplaceableSymbols(Context & context) {
|
||||
Expression e = context.expressionForSymbol(*this);
|
||||
Expression e = context.expressionForSymbol(*this, true);
|
||||
if (e.isUninitialized()) {
|
||||
return *this;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ Expression Function::replaceReplaceableSymbols(Context & context) {
|
||||
}
|
||||
|
||||
Expression Function::expand(Context & context) const {
|
||||
Expression e = context.expressionForSymbol(*this);
|
||||
Expression e = context.expressionForSymbol(*this, true);
|
||||
e = ExpressionWithoutSymbols(e, context);
|
||||
if (!e.isUninitialized()) {
|
||||
e = e.replaceSymbolWithExpression(Symbol(Symbol::SpecialSymbols::UnknownX), childAtIndex(0));
|
||||
@@ -155,7 +155,7 @@ VariableContext Function::unknownXContext(Context & parentContext) const {
|
||||
/* If the parentContext already has an expression for UnknownX, we have to
|
||||
* replace in childAtIndex(0) any occurence of UnknownX by its value in
|
||||
* parentContext. That way, we handle: evaluatin f(x-1) with x = 2 & f:x->x^2 */
|
||||
Expression unknownXValue = parentContext.expressionForSymbol(unknownXSymbol);
|
||||
Expression unknownXValue = parentContext.expressionForSymbol(unknownXSymbol, true);
|
||||
if (!unknownXValue.isUninitialized()) {
|
||||
xContext = static_cast<VariableContext &>(parentContext); // copy the parentContext
|
||||
child.replaceSymbolWithExpression(unknownXSymbol, unknownXValue);
|
||||
|
||||
@@ -47,7 +47,7 @@ Evaluation<T> StoreNode::templatedApproximate(Context& context, Preferences::Ang
|
||||
Store s(this);
|
||||
assert(!s.value().isUninitialized());
|
||||
context.setExpressionForSymbol(s.value(), s.symbol(), context);
|
||||
Expression e = context.expressionForSymbol(s.symbol());
|
||||
Expression e = context.expressionForSymbol(s.symbol(), false);
|
||||
if (e.isUninitialized()) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
@@ -68,7 +68,7 @@ Expression Store::shallowReduce(Context & context, Preferences::AngleUnit angleU
|
||||
}
|
||||
assert(!finalValue.isUninitialized());
|
||||
context.setExpressionForSymbol(finalValue, symbol(), context);
|
||||
Expression e = context.expressionForSymbol(symbol());
|
||||
Expression e = context.expressionForSymbol(symbol(), true);
|
||||
if (e.isUninitialized()) {
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ constexpr char Symbol::k_ans[];
|
||||
|
||||
/*ExpressionNode::Sign SymbolNode::sign() const {
|
||||
TODO: Maybe, we will want to know that from a context given in parameter:
|
||||
if (context.expressionForSymbol(this) != nullptr) {
|
||||
return context.expressionForSymbol(this)->sign(context);
|
||||
if (context.expressionForSymbol(this, false) != nullptr) {
|
||||
return context.expressionForSymbol(this, false)->sign(context);
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -126,7 +126,7 @@ Expression SymbolNode::replaceReplaceableSymbols(Context & context) {
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T> SymbolNode::templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
Expression e = Symbol(this).expand(context);
|
||||
Expression e = Symbol(this).expand(context, false);
|
||||
if (e.isUninitialized()) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
@@ -156,7 +156,7 @@ bool Symbol::isRegressionSymbol(const char * c) {
|
||||
}
|
||||
|
||||
bool Symbol::matches(ExpressionTest test, Context & context) const {
|
||||
Expression e = expand(context);
|
||||
Expression e = expand(context, false);
|
||||
return !e.isUninitialized() && test(e, context, true);
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ Expression Symbol::shallowReduce(Context & context, Preferences::AngleUnit angle
|
||||
if (!replaceSymbols) {
|
||||
return *this;
|
||||
}
|
||||
Expression result = expand(context);
|
||||
Expression result = expand(context, true);
|
||||
if (result.isUninitialized()) {
|
||||
return *this;
|
||||
}
|
||||
@@ -200,7 +200,7 @@ Expression Symbol::replaceReplaceableSymbols(Context & context) {
|
||||
if (isSystemSymbol()) {
|
||||
return *this;
|
||||
}
|
||||
Expression e = context.expressionForSymbol(*this);
|
||||
Expression e = context.expressionForSymbol(*this, true);
|
||||
if (e.isUninitialized()) {
|
||||
return *this;
|
||||
}
|
||||
@@ -208,10 +208,10 @@ Expression Symbol::replaceReplaceableSymbols(Context & context) {
|
||||
return e;
|
||||
}
|
||||
|
||||
Expression Symbol::expand(Context & context) const {
|
||||
Expression Symbol::expand(Context & context, bool clone) const {
|
||||
/* Replace all the symbols iteratively. This prevents a memory failure when
|
||||
* symbols are defined circularly. */
|
||||
Expression e = context.expressionForSymbol(*this);
|
||||
Expression e = context.expressionForSymbol(*this, clone);
|
||||
return ExpressionWithoutSymbols(e, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ void VariableContext::setExpressionForSymbol(const Expression & expression, cons
|
||||
}
|
||||
}
|
||||
|
||||
const Expression VariableContext::expressionForSymbol(const SymbolAbstract & symbol) {
|
||||
const Expression VariableContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
|
||||
if (strcmp(symbol.name(), m_name) == 0) {
|
||||
return m_value.clone();
|
||||
return clone ? m_value.clone() : m_value;
|
||||
} else {
|
||||
return m_parentContext->expressionForSymbol(symbol);
|
||||
return m_parentContext->expressionForSymbol(symbol, clone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user