mirror of
https://gitlab.com/c3d/db48x.git
synced 2024-09-29 05:36:58 +02:00
types: Reimplement a range-based type checking
Reimplement a range-based type-checking that does not require a memory access and a bitmap check every time a type is checked. This brings the `NQueens` execution time on DM42 from 1215 to 1175, which is about 3%. Fixes: #532 Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
parent
8fd3220f44
commit
044352cc4c
13 changed files with 97 additions and 327 deletions
|
@ -12,6 +12,7 @@ all times in milliseconds, best of 5 runs, on USB power, with presumably no GC.
|
|||
|
||||
| Version | Time | PGM Size | QSPI Size | Note |
|
||||
|---------|---------|-----------|-----------|-------------------------|
|
||||
| 0.4.9+ | 1175 | | | Range-based type checks |
|
||||
| 0.4.9+ | 1215 | | | Remove busy animation |
|
||||
| 0.4.9 | 1447 | 646028 | 1531868 | No LastArgs in progs |
|
||||
| 0.4.8 | 1401 | 633932 | 1531868 | |
|
||||
|
|
|
@ -2704,6 +2704,7 @@ all times in milliseconds, best of 5 runs, on USB power, with presumably no GC.
|
|||
|
||||
| Version | Time | PGM Size | QSPI Size | Note |
|
||||
|---------|---------|-----------|-----------|-------------------------|
|
||||
| 0.4.9+ | 1175 | | | Range-based type checks |
|
||||
| 0.4.9+ | 1215 | | | Remove busy animation |
|
||||
| 0.4.9 | 1447 | 646028 | 1531868 | No LastArgs in progs |
|
||||
| 0.4.8 | 1401 | 633932 | 1531868 | |
|
||||
|
|
|
@ -2704,6 +2704,7 @@ all times in milliseconds, best of 5 runs, on USB power, with presumably no GC.
|
|||
|
||||
| Version | Time | PGM Size | QSPI Size | Note |
|
||||
|---------|---------|-----------|-----------|-------------------------|
|
||||
| 0.4.9+ | 1175 | | | Range-based type checks |
|
||||
| 0.4.9+ | 1215 | | | Remove busy animation |
|
||||
| 0.4.9 | 1447 | 646028 | 1531868 | No LastArgs in progs |
|
||||
| 0.4.8 | 1401 | 633932 | 1531868 | |
|
||||
|
|
|
@ -289,14 +289,13 @@ bool algebraic::complex_promotion(algebraic_g &x, object::id type)
|
|||
x = polar_p(z->as_polar());
|
||||
return x.Safe();
|
||||
}
|
||||
else if (is_strictly_symbolic(xt))
|
||||
else if (is_symbolic(xt))
|
||||
{
|
||||
// Assume a symbolic value is complex for now
|
||||
// TODO: Implement `REALASSUME`
|
||||
return false;
|
||||
}
|
||||
else if (is_integer(xt) || is_real(xt) || is_symbolic(xt) ||
|
||||
is_algebraic(xt))
|
||||
else if (is_symbolic_arg(xt) || is_algebraic(xt))
|
||||
{
|
||||
algebraic_g zero = algebraic_p(integer::make(0));
|
||||
if (type == ID_polar)
|
||||
|
|
|
@ -314,7 +314,7 @@ algebraic_p arithmetic::non_numeric<sub>(algebraic_r x, algebraic_r y)
|
|||
return x;
|
||||
if (x->is_same_as(y)) // X - X = 0
|
||||
return integer::make(0);
|
||||
if (x->is_zero(false) && y->is_strictly_symbolic())
|
||||
if (x->is_zero(false) && y->is_symbolic())
|
||||
return neg::run(y); // 0 - X = -X
|
||||
}
|
||||
|
||||
|
@ -459,7 +459,7 @@ algebraic_p arithmetic::non_numeric<mul>(algebraic_r x, algebraic_r y)
|
|||
if (y->type() == ID_ImaginaryUnit)
|
||||
if (x->is_real())
|
||||
return rectangular::make(integer::make(0), x);
|
||||
if (x->is_strictly_symbolic() && x->is_same_as(y))
|
||||
if (x->is_symbolic() && x->is_same_as(y))
|
||||
return sq::run(x); // X * X = X²
|
||||
}
|
||||
|
||||
|
@ -602,7 +602,7 @@ algebraic_p arithmetic::non_numeric<struct div>(algebraic_r x, algebraic_r y)
|
|||
}
|
||||
if (y->is_one(false)) // X / 1 = X
|
||||
return x;
|
||||
if (x->is_one(false) && y->is_strictly_symbolic())
|
||||
if (x->is_one(false) && y->is_symbolic())
|
||||
return inv::run(y); // 1 / X = X⁻¹
|
||||
if (x->is_same_as(y))
|
||||
return integer::make(1); // X / X = 1
|
||||
|
@ -917,7 +917,7 @@ algebraic_p arithmetic::non_numeric<struct pow>(algebraic_r x, algebraic_r y)
|
|||
}
|
||||
|
||||
// Do not expand X^3 or integers when y>=0
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
return expression::make(ID_pow, x, y);
|
||||
|
||||
// Deal with X^N where N is a positive integer
|
||||
|
@ -1306,7 +1306,7 @@ algebraic_p arithmetic::evaluate(id op,
|
|||
if (!x.Safe() || !y.Safe())
|
||||
return nullptr;
|
||||
|
||||
if (x->is_symbolic() && y->is_symbolic())
|
||||
if (x->is_symbolic_arg() && y->is_symbolic_arg())
|
||||
{
|
||||
x = expression::make(op, x, y);
|
||||
return x;
|
||||
|
|
|
@ -843,7 +843,7 @@ RENDER_BODY(polar)
|
|||
m->render(r);
|
||||
r.put(unicode(ANGLE_MARK));
|
||||
a->render(r);
|
||||
if (!a->is_strictly_symbolic())
|
||||
if (!a->is_symbolic())
|
||||
{
|
||||
switch(Settings.angle_mode)
|
||||
{
|
||||
|
@ -877,8 +877,8 @@ COMMAND_BODY(RealToComplex)
|
|||
object_g im = rt.stack(0);
|
||||
if (!re || !im)
|
||||
return ERROR;
|
||||
if (!(re->is_real() || re->is_strictly_symbolic()) ||
|
||||
!(im->is_real() || im->is_strictly_symbolic()))
|
||||
if (!(re->is_real() || re->is_symbolic()) ||
|
||||
!(im->is_real() || im->is_symbolic()))
|
||||
{
|
||||
rt.type_error();
|
||||
return ERROR;
|
||||
|
@ -998,7 +998,7 @@ COMPLEX_BODY(sqrt)
|
|||
algebraic_g im = sqrt::run((znorm - a) / two);
|
||||
if (b->is_negative(false))
|
||||
im = neg::run(im);
|
||||
else if (b->is_strictly_symbolic())
|
||||
else if (b->is_symbolic())
|
||||
im = sign::run(im) * im;
|
||||
return rectangular::make(re, im);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ bool function::should_be_symbolic(id type)
|
|||
// Check if we should treat the type symbolically
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
return is_strictly_symbolic(type);
|
||||
return is_symbolic(type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -510,7 +510,7 @@ FUNCTION_BODY(inv)
|
|||
{
|
||||
if (!x.Safe())
|
||||
return nullptr;
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
return symbolic(ID_inv, x);
|
||||
else if (x->type() == ID_array)
|
||||
return array_p(x.Safe())->invert();
|
||||
|
@ -544,7 +544,7 @@ FUNCTION_BODY(neg)
|
|||
v = neg::run(v);
|
||||
return unit::simple(v, u);
|
||||
}
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
return symbolic(ID_neg, x);
|
||||
algebraic_g zero = rt.make<integer>(ID_integer, 0);
|
||||
return zero - x;
|
||||
|
@ -558,7 +558,7 @@ FUNCTION_BODY(sq)
|
|||
{
|
||||
if (!x.Safe())
|
||||
return nullptr;
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
if (!Settings.auto_simplify || x->type() != ID_ImaginaryUnit)
|
||||
return expression::make(ID_sq, x);
|
||||
return x * x;
|
||||
|
@ -582,7 +582,7 @@ FUNCTION_BODY(cubed)
|
|||
{
|
||||
if (!x.Safe())
|
||||
return nullptr;
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
if (!Settings.auto_simplify || x->type() != ID_ImaginaryUnit)
|
||||
return expression::make(ID_cubed, x);
|
||||
return x * x * x;
|
||||
|
@ -637,7 +637,7 @@ FUNCTION_BODY(fact)
|
|||
if (!x.Safe())
|
||||
return nullptr;
|
||||
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
return expression::make(ID_fact, x);
|
||||
|
||||
if (integer_p ival = x->as<integer>())
|
||||
|
|
|
@ -82,8 +82,10 @@ FLAGS(is_real, bignum, decimal128)
|
|||
FLAGS(is_complex, rectangular, polar)
|
||||
FLAGS(is_command, Drop, Unimplemented)
|
||||
FLAGS(is_symbolic, local, expression, pi, ImaginaryUnit)
|
||||
FLAGS(is_algebraic, add, ToFraction)
|
||||
FLAGS(is_algebraic_fn, add, ToFraction)
|
||||
FLAGS(is_immediate, MainMenu, SelfInsert)
|
||||
FLAGS(is_unit, unit, unit)
|
||||
FLAGS(is_plot, Function, Parametric)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ object::result list::list_parse(id type,
|
|||
}
|
||||
|
||||
// TODO: A symbol could be a function, need to deal with that
|
||||
if (is_algebraic_function(type))
|
||||
if (is_algebraic_fn(type))
|
||||
{
|
||||
prefix = obj;
|
||||
obj = nullptr;
|
||||
|
|
|
@ -82,32 +82,6 @@ RECORDER(object_errors, 16, "Runtime errors on objects");
|
|||
RECORDER(assert_error, 16, "Assertion failures");
|
||||
|
||||
|
||||
template <typename first, typename last, typename ...rest>
|
||||
struct handler_flag
|
||||
{
|
||||
static constexpr bool set(object::id id)
|
||||
{
|
||||
return (id >= first::static_id && id <= last::static_id)
|
||||
|| handler_flag<rest...>::set(id);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename first, typename last>
|
||||
struct handler_flag<first, last>
|
||||
{
|
||||
static constexpr bool set(object::id id)
|
||||
{
|
||||
return id >= first::static_id && id <= last::static_id;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define ID(id)
|
||||
#define FLAGS(name, ...) \
|
||||
static constexpr auto name = handler_flag<__VA_ARGS__>();
|
||||
#include "ids.tbl"
|
||||
|
||||
|
||||
const object::dispatch object::handler[NUM_IDS] =
|
||||
// ----------------------------------------------------------------------------
|
||||
// Table of handlers for each object type
|
||||
|
@ -131,18 +105,6 @@ const object::dispatch object::handler[NUM_IDS] =
|
|||
.menu_marker = (menu_marker_fn) id::do_menu_marker, \
|
||||
.arity = id::ARITY, \
|
||||
.precedence = id::PRECEDENCE, \
|
||||
.is_type = ::is_type.set(ID_##id), \
|
||||
.is_integer = ::is_integer.set(ID_##id), \
|
||||
.is_based = ::is_based.set(ID_##id), \
|
||||
.is_bignum = ::is_bignum.set(ID_##id), \
|
||||
.is_fraction = ::is_fraction.set(ID_##id), \
|
||||
.is_real = ::is_real.set(ID_##id), \
|
||||
.is_decimal = ::is_decimal.set(ID_##id), \
|
||||
.is_complex = ::is_complex.set(ID_##id), \
|
||||
.is_command = ::is_command.set(ID_##id), \
|
||||
.is_symbolic = ::is_symbolic.set(ID_##id), \
|
||||
.is_algebraic = ::is_algebraic.set(ID_##id), \
|
||||
.is_immediate = ::is_immediate.set(ID_##id), \
|
||||
},
|
||||
#include "ids.tbl"
|
||||
};
|
||||
|
|
322
src/object.h
322
src/object.h
|
@ -207,18 +207,6 @@ struct object
|
|||
menu_marker_fn menu_marker; // Show marker
|
||||
uint arity; // Number of input arguments
|
||||
uint precedence; // Precedence in equations
|
||||
bool is_type :1; // Is a data type
|
||||
bool is_integer :1; // Is an integer type
|
||||
bool is_based :1; // Is a based integer type
|
||||
bool is_bignum :1; // Is a bignum type
|
||||
bool is_fraction :1; // Is a fraction type
|
||||
bool is_real :1; // Is a real type (excludes based ints)
|
||||
bool is_decimal :1; // Is a decimal type
|
||||
bool is_complex :1; // Is a complex (but not real) type
|
||||
bool is_command :1; // Is an RPL command
|
||||
bool is_symbolic :1; // Is a symbol or an equation
|
||||
bool is_algebraic :1; // Algebraic functions (in equations)
|
||||
bool is_immediate :1; // Commands that execute immediately
|
||||
};
|
||||
|
||||
|
||||
|
@ -493,76 +481,73 @@ struct object
|
|||
//
|
||||
// ========================================================================
|
||||
|
||||
static bool is_type(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is for an RPL data type
|
||||
// -------------------------------------------------------------------------
|
||||
struct id_map
|
||||
// ------------------------------------------------------------------------
|
||||
// Used to isolate the type range checking names
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_type;
|
||||
enum ids
|
||||
// --------------------------------------------------------------------
|
||||
// Createa a local name matching the class name
|
||||
// --------------------------------------------------------------------
|
||||
{
|
||||
#define ID(i) i,
|
||||
#include "ids.tbl"
|
||||
NUM_IDS
|
||||
};
|
||||
|
||||
|
||||
template <ids first, ids last>
|
||||
static INLINE bool in_range(id ty)
|
||||
// --------------------------------------------------------------------
|
||||
// Check if a given type is in the given range
|
||||
// --------------------------------------------------------------------
|
||||
{
|
||||
return ids(ty) >= first && ids(ty) <= last;
|
||||
}
|
||||
|
||||
|
||||
bool is_type() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is an integer
|
||||
// -------------------------------------------------------------------------
|
||||
template <ids first, ids last, ids more, ids ...rest>
|
||||
static INLINE bool in_range(id ty)
|
||||
// --------------------------------------------------------------------
|
||||
// Check if a given type is in the given ranges
|
||||
// --------------------------------------------------------------------
|
||||
{
|
||||
return is_type(type());
|
||||
return (ids(ty) >= first && ids(ty) <= last)
|
||||
|| in_range<more, rest...>(ty);
|
||||
}
|
||||
|
||||
|
||||
static bool is_integer(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is an integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_integer;
|
||||
#define ID(x)
|
||||
#define FLAGS(name, ...) \
|
||||
static INLINE bool name(id ty) \
|
||||
/* ------------------------------------------------------- */ \
|
||||
/* Range-based type checking (faster than memory reads) */ \
|
||||
/* ------------------------------------------------------- */ \
|
||||
{ \
|
||||
return in_range<__VA_ARGS__>(ty); \
|
||||
}
|
||||
#include "ids.tbl"
|
||||
|
||||
};
|
||||
|
||||
bool is_integer() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is an integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_integer(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_based(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a based integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_based;
|
||||
}
|
||||
|
||||
|
||||
bool is_based() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is a based integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_based(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_bignum(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a big integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_bignum;
|
||||
}
|
||||
|
||||
|
||||
bool is_bignum() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is a big integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_bignum(type());
|
||||
#define ID(x)
|
||||
#define FLAGS(name, ...) \
|
||||
static INLINE bool name(id ty) \
|
||||
/* ------------------------------------------------------- */ \
|
||||
/* Range-based type checking (faster than memory reads) */ \
|
||||
/* ------------------------------------------------------- */ \
|
||||
{ \
|
||||
return id_map::name(ty); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
INLINE bool name() const \
|
||||
/* ------------------------------------------------------- */ \
|
||||
/* Range-based type checking (faster than memory reads) */ \
|
||||
/* ------------------------------------------------------- */ \
|
||||
{ \
|
||||
return id_map::name(type()); \
|
||||
}
|
||||
#include "ids.tbl"
|
||||
|
||||
|
||||
bool is_big() const;
|
||||
|
@ -571,31 +556,12 @@ struct object
|
|||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
static bool is_fraction(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a fraction
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_fraction;
|
||||
}
|
||||
|
||||
|
||||
bool is_fraction() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is an integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_fraction(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_fractionable(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a fraction or a non-based integer
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_fraction ||
|
||||
(handler[ty].is_integer && handler[ty].is_real);
|
||||
return is_fraction(ty) || (is_integer(ty) && is_real(ty));
|
||||
}
|
||||
|
||||
|
||||
|
@ -608,114 +574,6 @@ struct object
|
|||
}
|
||||
|
||||
|
||||
static bool is_decimal(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a decimal
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_decimal;
|
||||
}
|
||||
|
||||
|
||||
bool is_decimal() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is a decimal
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_decimal(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_real(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a real number
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_real;
|
||||
}
|
||||
|
||||
|
||||
bool is_real() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is a real number
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_real(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_complex(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a complex number
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_complex;
|
||||
}
|
||||
|
||||
|
||||
bool is_complex() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is a complex number
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_complex(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_unit(id ty)
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if a type is a unit object
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return ty == ID_unit;
|
||||
}
|
||||
|
||||
|
||||
bool is_unit() const
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if an object is a unit object
|
||||
// -------------------------------------------------------------------------
|
||||
{
|
||||
return is_unit(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_command(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if a type denotes a command
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_command;
|
||||
}
|
||||
|
||||
|
||||
bool is_command() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if an object is a command
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_command(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_immediate(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if a type denotes an immediate command (e.g. menus)
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_immediate;
|
||||
}
|
||||
|
||||
|
||||
bool is_immediate() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if an object is an immediate command (e.g. menus)
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_immediate(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_algebraic_number(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if something is a number (real or complex)
|
||||
|
@ -734,57 +592,21 @@ struct object
|
|||
}
|
||||
|
||||
|
||||
static bool is_symbolic(id ty)
|
||||
static bool is_symbolic_arg(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if a type denotes a symbolic argument (symbol, equation, number)
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_symbolic || is_algebraic_number(ty);
|
||||
return is_symbolic(ty) || is_algebraic_number(ty);
|
||||
}
|
||||
|
||||
|
||||
bool is_symbolic() const
|
||||
bool is_symbolic_arg() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if an object is a symbolic argument
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_symbolic(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_strictly_symbolic(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if a type denotes a symbol or equation
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_symbolic;
|
||||
}
|
||||
|
||||
|
||||
bool is_strictly_symbolic() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if an object is a symbol or equation
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_strictly_symbolic(type());
|
||||
}
|
||||
|
||||
|
||||
static bool is_algebraic_function(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if a type denotes an algebraic function
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return handler[ty].is_algebraic;
|
||||
}
|
||||
|
||||
|
||||
bool is_algebraic_function() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if an object is an algebraic function
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_algebraic_function(type());
|
||||
return is_symbolic_arg(type());
|
||||
}
|
||||
|
||||
|
||||
|
@ -793,7 +615,7 @@ struct object
|
|||
// Check if a type denotes an algebraic value or function
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_algebraic_function(ty) || is_symbolic(ty);
|
||||
return is_algebraic_fn(ty) || is_symbolic_arg(ty);
|
||||
}
|
||||
|
||||
|
||||
|
@ -817,24 +639,6 @@ struct object
|
|||
}
|
||||
|
||||
|
||||
static bool is_plot(id ty)
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if a type name denotes a plot type
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return ty >= ID_Function && ty <= ID_Parametric;
|
||||
}
|
||||
|
||||
|
||||
bool is_plot() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Check if an object is a plot type
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
return is_plot(type());
|
||||
}
|
||||
|
||||
|
||||
uint arity() const
|
||||
// ------------------------------------------------------------------------
|
||||
// Return the arity for arithmetic operators
|
||||
|
|
|
@ -256,7 +256,7 @@ algebraic_p solve(object_g eq, symbol_g name, object_g guess)
|
|||
}
|
||||
|
||||
// Check if there are unresolved symbols
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
{
|
||||
rt.invalid_function_error();
|
||||
return x;
|
||||
|
|
|
@ -867,7 +867,7 @@ FUNCTION_BODY(UVal)
|
|||
{
|
||||
if (!x.Safe())
|
||||
return nullptr;
|
||||
if (x->is_strictly_symbolic())
|
||||
if (x->is_symbolic())
|
||||
return symbolic(ID_UVal, x);
|
||||
if (unit_p u = x->as<unit>())
|
||||
return u->value();
|
||||
|
|
Loading…
Reference in a new issue