1 /*
2 Qalculate (library)
3
4 Copyright (C) 2003-2007, 2008, 2016 Hanna Knutsson (hanna.knutsson@protonmail.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 */
11
12 #ifndef VARIABLE_H
13 #define VARIABLE_H
14
15 #include <libqalculate/ExpressionItem.h>
16 #include <libqalculate/includes.h>
17
18 /** @file */
19
20 #define DECLARE_BUILTIN_VARIABLE(x, i) class x : public DynamicVariable { \
21 private: \
22 void calculate(MathStructure &m) const; \
23 public: \
24 x(); \
25 x(const x *variable) {set(variable);} \
26 ExpressionItem *copy() const {return new x(this);} \
27 int id() const {return i;} \
28 };
29
30 /// Type assumption.
31 /**
32 * Each type is a subset of the type above.
33 */
34 typedef enum {
35 /// Multiplication is NOT commutative; do not use
36 ASSUMPTION_TYPE_NONE = 0,
37 ASSUMPTION_TYPE_NONMATRIX = 1,
38 ASSUMPTION_TYPE_NUMBER = 2,
39 /// im(x) != 0
40 ASSUMPTION_TYPE_COMPLEX = 3,
41 ASSUMPTION_TYPE_REAL = 4,
42 ASSUMPTION_TYPE_RATIONAL = 5,
43 ASSUMPTION_TYPE_INTEGER = 6
44 } AssumptionType;
45
46 /// Signedness assumption.
47 typedef enum {
48 /// x = ?
49 ASSUMPTION_SIGN_UNKNOWN,
50 /// x > 0
51 ASSUMPTION_SIGN_POSITIVE,
52 /// x >= 0
53 ASSUMPTION_SIGN_NONNEGATIVE,
54 /// x < 0
55 ASSUMPTION_SIGN_NEGATIVE,
56 /// x <= 0
57 ASSUMPTION_SIGN_NONPOSITIVE,
58 /// x != 0
59 ASSUMPTION_SIGN_NONZERO
60 } AssumptionSign;
61
62 /// Type of variable
63 typedef enum {
64 /// class Variable
65 SUBTYPE_VARIABLE,
66 /// class UnknownVariable
67 SUBTYPE_UNKNOWN_VARIABLE,
68 /// class KnownVariable
69 SUBTYPE_KNOWN_VARIABLE
70 } VariableSubtype;
71
72 /// An assumption about an unknown mathematical value.
73 /** Assumptions have a type and a sign. The type describes the type of the value -- if it represents a number or something else, and what type of number is represented.
74 * The sign restricts the signedness of a number. The sign generally only applies the assumptions representing a number.
75 * The assumption class also includes max and min values, which however are not used anywhere yet.
76 */
77 class Assumptions {
78
79 protected:
80
81 AssumptionType i_type;
82 AssumptionSign i_sign;
83 Number *fmin, *fmax;
84 bool b_incl_min, b_incl_max;
85
86 public:
87
88 Assumptions();
89 ~Assumptions();
90
91 bool isPositive();
92 bool isNegative();
93 bool isNonNegative();
94 bool isNonPositive();
95 bool isInteger();
96 bool isNumber();
97 bool isRational();
98 bool isReal();
99 bool isComplex();
100 bool isNonZero();
101 bool isNonMatrix();
102 bool isScalar();
103
104 AssumptionType type();
105 AssumptionSign sign();
106 void setType(AssumptionType ant);
107 void setSign(AssumptionSign as);
108
109 void setMin(const Number *nmin);
110 void setIncludeEqualsMin(bool include_equals);
111 bool includeEqualsMin() const;
112 const Number *min() const;
113 void setMax(const Number *nmax);
114 void setIncludeEqualsMax(bool include_equals);
115 bool includeEqualsMax() const;
116 const Number *max() const;
117
118 };
119
120 /// Abstract base class for variables.
121 /** A variable is an alpha-numerical representation of a known or unknown value.
122 */
123 class Variable : public ExpressionItem {
124
125 public:
126
127 Variable(std::string cat_, std::string name_, std::string title_ = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
128 Variable();
129 Variable(const Variable *variable);
130 virtual ~Variable();
131 virtual ExpressionItem *copy() const = 0;
132 virtual void set(const ExpressionItem *item);
type()133 virtual int type() const {return TYPE_VARIABLE;}
134 /** Returns the subtype of the variable, corresponding to which subsubclass the object belongs to.
135 *
136 * @returns ::VariableSubtype.
137 */
subtype()138 virtual int subtype() const {return SUBTYPE_VARIABLE;}
139 /** Returns if the variable has a known value (as oppossed to assumptions).
140 *
141 * @returns true if the variable is of class KnownVariable, false if UnknownVariable.
142 */
143 virtual bool isKnown() const = 0;
144
145 /** Returns if the variable represents a positive value.
146 */
147 virtual bool representsPositive(bool = false) {return false;}
148 virtual bool representsNegative(bool = false) {return false;}
149 virtual bool representsNonNegative(bool = false) {return false;}
150 virtual bool representsNonPositive(bool = false) {return false;}
151 virtual bool representsInteger(bool = false) {return false;}
152 virtual bool representsNonInteger(bool = false) {return false;}
153 virtual bool representsFraction(bool = false) {return false;}
154 virtual bool representsNumber(bool = false) {return false;}
155 virtual bool representsRational(bool = false) {return false;}
156 virtual bool representsReal(bool = false) {return false;}
157 virtual bool representsNonComplex(bool b = false) {return representsReal(b);}
158 virtual bool representsComplex(bool = false) {return false;}
159 virtual bool representsNonZero(bool = false) {return false;}
160 virtual bool representsEven(bool = false) {return false;}
161 virtual bool representsOdd(bool = false) {return false;}
162 virtual bool representsUndefined(bool = false, bool = false, bool = false) {return false;}
representsBoolean()163 virtual bool representsBoolean() {return false;}
representsNonMatrix()164 virtual bool representsNonMatrix() {return false;}
representsScalar()165 virtual bool representsScalar() {return false;}
166
id()167 virtual int id() const {return 0;}
168
169 };
170
171 /// A variable with unknown value.
172 /** Unknown variables have an associated assumption object.
173 */
174 class UnknownVariable : public Variable {
175
176 protected:
177
178 Assumptions *o_assumption;
179 MathStructure *mstruct;
180
181 public:
182
183 /** Create an unknown.
184 *
185 * @param cat_ Category that the variable belongs to.
186 * @param name_ Initial name of the variable.
187 * @param title_ Descriptive name.
188 * @param is_local If the variable is local/user-defined or global.
189 * @param is_builtin If the variable is builtin and not modifiable.
190 * @param is_active If the variable is active and can be used in expressions.
191 */
192 UnknownVariable(std::string cat_, std::string name_, std::string title_ = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
193 /** Create an empty unknown variable.
194 */
195 UnknownVariable();
196 /** Create a copy of an unknown variable.
197 *
198 * @param variable Unknown variable to copy.
199 */
200 UnknownVariable(const UnknownVariable *variable);
201 virtual ~UnknownVariable();
202 virtual ExpressionItem *copy() const;
203 virtual void set(const ExpressionItem *item);
isKnown()204 bool isKnown() const {return false;}
205
206 /** Sets the assumptions of the unknown variable.
207 *
208 * @param ass Assumptions.
209 */
210 void setAssumptions(Assumptions *ass);
211 void setAssumptions(const MathStructure &mvar);
212 /** Returns the assumptions of the unknown variable.
213 *
214 * @returns Assumptions of the unknown variable.
215 */
216 Assumptions *assumptions();
217
218 const MathStructure &interval() const;
219 void setInterval(const MathStructure &o);
220
subtype()221 virtual int subtype() const {return SUBTYPE_UNKNOWN_VARIABLE;}
222
223 virtual bool representsPositive(bool = false);
224 virtual bool representsNegative(bool = false);
225 virtual bool representsNonNegative(bool = false);
226 virtual bool representsNonPositive(bool = false);
227 virtual bool representsInteger(bool = false);
228 virtual bool representsNumber(bool = false);
229 virtual bool representsRational(bool = false);
230 virtual bool representsReal(bool = false);
231 virtual bool representsNonComplex(bool = false);
232 virtual bool representsComplex(bool = false);
233 virtual bool representsNonZero(bool = false);
234 virtual bool representsNonMatrix();
235 virtual bool representsScalar();
236
237 };
238
239 /// A variable with a known value.
240 /** Known variables have an associated value. The value can be a simple number or a full mathematical expression. The known variable class is used both for variable values and constants.
241 *
242 * The value can be provided as an expression in the form of a text string or as a mathematical value in the form of an object of the MathStructure class.
243 * The text string is parsed when needed, which saves time when loading many variable definitions which might not be used, at least not immediately.
244 */
245 class KnownVariable : public Variable {
246
247 protected:
248
249 MathStructure *mstruct, *mstruct_alt;
250 bool b_expression;
251 int calculated_precision;
252 std::string sexpression, suncertainty, sunit;
253 bool b_relative_uncertainty;
254
255 public:
256
257 /** Create a known variable with a value.
258 *
259 * @param cat_ Category that the variable belongs to.
260 * @param name_ Initial name of the variable.
261 * @param o Value.
262 * @param title_ Descriptive name.
263 * @param is_local If the variable is local/user-defined or global.
264 * @param is_builtin If the variable is builtin and not modifiable.
265 * @param is_active If the variable is active and can be used in expressions.
266 */
267 KnownVariable(std::string cat_, std::string name_, const MathStructure &o, std::string title_ = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
268 /** Create a known variable with an text string expression.
269 *
270 * @param cat_ Category that the variable belongs to.
271 * @param name_ Initial name of the variable.
272 * @param expression_ Expression.
273 * @param title_ Descriptive name.
274 * @param is_local If the variable is local/user-defined or global.
275 * @param is_builtin If the variable is builtin and not modifiable.
276 * @param is_active If the variable is active and can be used in expressions.
277 */
278 KnownVariable(std::string cat_, std::string name_, std::string expression_, std::string title_ = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
279 /** Create an empty known variable. Primarily for internal use.
280 */
281 KnownVariable();
282 /** Create a copy of a known variable.
283 *
284 * @param variable Known variable to copy.
285 */
286 KnownVariable(const KnownVariable *variable);
287 virtual ~KnownVariable();
288
289 virtual ExpressionItem *copy() const;
290 virtual void set(const ExpressionItem *item);
isKnown()291 bool isKnown() const {return true;}
292 /** Returns if the variable has an text string expression instead of a value.
293 *
294 * @returns True if the variable has an expression instead of a value.
295 */
296 virtual bool isExpression() const;
297 /** Returns the variable's string expression or an empty string if it has not got an expression.
298 *
299 * @returns The variable's expression.
300 */
301 virtual std::string expression() const;
302 virtual std::string uncertainty(bool *is_relative = NULL) const;
303 virtual std::string unit() const;
304
subtype()305 int subtype() const {return SUBTYPE_KNOWN_VARIABLE;}
306
307 /** Sets the value of the variable. If expression is set, it is cleared.
308 *
309 * @param o Value.
310 */
311 virtual void set(const MathStructure &o);
312 /** Sets the text string expression of the variable. The value is cleared.
313 *
314 * @param expression_ Expression.
315 */
316 virtual void set(std::string expression_);
317 virtual void setUncertainty(std::string standard_uncertainty, bool is_relative = false);
318 virtual void setUnit(std::string unit_expression);
319
320 /** Returns the value of the variable. If no value is set or parsed and an expression is set, the expression is parsed and resulting value returned.
321 *
322 * @returns The value of the variable..
323 */
324 virtual const MathStructure &get();
325
326 virtual bool representsPositive(bool = false);
327 virtual bool representsNegative(bool = false);
328 virtual bool representsNonNegative(bool = false);
329 virtual bool representsNonPositive(bool = false);
330 virtual bool representsInteger(bool = false);
331 virtual bool representsNonInteger(bool = false);
332 virtual bool representsFraction(bool = false);
333 virtual bool representsNumber(bool = false);
334 virtual bool representsRational(bool = false);
335 virtual bool representsReal(bool = false);
336 virtual bool representsNonComplex(bool = false);
337 virtual bool representsComplex(bool = false);
338 virtual bool representsNonZero(bool = false);
339 virtual bool representsEven(bool = false);
340 virtual bool representsOdd(bool = false);
341 virtual bool representsUndefined(bool = false, bool = false, bool = false);
342 virtual bool representsBoolean();
343 virtual bool representsNonMatrix();
344 virtual bool representsScalar();
345
id()346 virtual int id() const {return 0;}
347
348 };
349
350 /// Abstract base class for variables with a value which is recalculated when the precision has changed.
351 /**
352 */
353 class DynamicVariable : public KnownVariable {
354
355 protected:
356
357 virtual void calculate(MathStructure &m) const = 0;
358 bool always_recalculate;
359
360 public:
361
362 DynamicVariable(std::string cat_, std::string name_, std::string title_ = "", bool is_local = false, bool is_builtin = true, bool is_active = true);
363 DynamicVariable(const DynamicVariable *variable);
364 DynamicVariable();
365 virtual ~DynamicVariable();
366
367 ExpressionItem *copy() const = 0;
368 void set(const ExpressionItem *item);
369
370 const MathStructure &get();
371
372 void set(const MathStructure &o);
373 void set(std::string expression_);
374
375 /** Returns the precision of the calculated value.
376 *
377 * @returns Precision of the calculated value or zero if the value has not yet been calculated.
378 */
379 int calculatedPrecision() const;
380
381 virtual bool representsPositive(bool = false) {return true;}
382 virtual bool representsNegative(bool = false) {return false;}
383 virtual bool representsNonNegative(bool = false) {return true;}
384 virtual bool representsNonPositive(bool = false) {return false;}
385 virtual bool representsInteger(bool = false) {return false;}
386 virtual bool representsNonInteger(bool = false) {return true;}
387 virtual bool representsNumber(bool = false) {return true;}
388 virtual bool representsRational(bool = false) {return false;}
389 virtual bool representsReal(bool = false) {return true;}
390 virtual bool representsComplex(bool = false) {return false;}
391 virtual bool representsNonZero(bool = false) {return true;}
392 virtual bool representsEven(bool = false) {return false;}
393 virtual bool representsOdd(bool = false) {return false;}
394 virtual bool representsUndefined(bool = false, bool = false, bool = false) {return false;}
representsBoolean()395 virtual bool representsBoolean() {return false;}
representsNonMatrix()396 virtual bool representsNonMatrix() {return true;}
representsScalar()397 virtual bool representsScalar() {return true;}
398
399 };
400
401 enum {
402 VARIABLE_ID_E = 100,
403 VARIABLE_ID_PI = 101,
404 VARIABLE_ID_EULER = 102,
405 VARIABLE_ID_CATALAN = 103,
406 VARIABLE_ID_PRECISION = 140,
407 VARIABLE_ID_TODAY = 161,
408 VARIABLE_ID_TOMORROW = 162,
409 VARIABLE_ID_YESTERDAY = 163,
410 VARIABLE_ID_NOW = 164,
411 VARIABLE_ID_UPTIME = 201
412 };
413
414 /// Dynamic variable for Pi
DECLARE_BUILTIN_VARIABLE(PiVariable,VARIABLE_ID_PI)415 DECLARE_BUILTIN_VARIABLE(PiVariable, VARIABLE_ID_PI)
416 /// Dynamic variable for e, the base of natural logarithms
417 DECLARE_BUILTIN_VARIABLE(EVariable, VARIABLE_ID_E)
418 /// Dynamic variable for Euler's constant
419 DECLARE_BUILTIN_VARIABLE(EulerVariable, VARIABLE_ID_EULER)
420 /// Dynamic variable for Catalan's constant
421 DECLARE_BUILTIN_VARIABLE(CatalanVariable, VARIABLE_ID_CATALAN)
422
423 /// Dynamic variable for current precision
424 class PrecisionVariable : public DynamicVariable {
425 private:
426 void calculate(MathStructure &m) const;
427 public:
428 PrecisionVariable();
429 PrecisionVariable(const PrecisionVariable *variable) {set(variable);}
430 ExpressionItem *copy() const {return new PrecisionVariable(this);}
431 bool representsInteger(bool = false) {return true;}
432 bool representsNonInteger(bool = false) {return false;}
433 int id() const {return VARIABLE_ID_PRECISION;}
434 };
435
436 class TodayVariable : public DynamicVariable {
437 private:
438 void calculate(MathStructure &m) const;
439 public:
440 TodayVariable();
TodayVariable(const TodayVariable * variable)441 TodayVariable(const TodayVariable *variable) {set(variable);}
copy()442 ExpressionItem *copy() const {return new TodayVariable(this);}
443 virtual bool representsPositive(bool = false) {return false;}
444 virtual bool representsNonNegative(bool = false) {return false;}
445 virtual bool representsNonInteger(bool = false) {return false;}
446 virtual bool representsNumber(bool b = false) {return b;}
447 virtual bool representsReal(bool b = false) {return b;}
448 virtual bool representsNonZero(bool b = false) {return b;}
id()449 int id() const {return VARIABLE_ID_TODAY;}
450 };
451 class TomorrowVariable : public DynamicVariable {
452 private:
453 void calculate(MathStructure &m) const;
454 public:
455 TomorrowVariable();
TomorrowVariable(const TomorrowVariable * variable)456 TomorrowVariable(const TomorrowVariable *variable) {set(variable);}
copy()457 ExpressionItem *copy() const {return new TomorrowVariable(this);}
458 virtual bool representsPositive(bool = false) {return false;}
459 virtual bool representsNonNegative(bool = false) {return false;}
460 virtual bool representsNonInteger(bool = false) {return false;}
461 virtual bool representsNumber(bool b = false) {return b;}
462 virtual bool representsReal(bool b = false) {return b;}
463 virtual bool representsNonZero(bool b = false) {return b;}
id()464 int id() const {return VARIABLE_ID_TOMORROW;}
465 };
466 class YesterdayVariable : public DynamicVariable {
467 private:
468 void calculate(MathStructure &m) const;
469 public:
470 YesterdayVariable();
YesterdayVariable(const YesterdayVariable * variable)471 YesterdayVariable(const YesterdayVariable *variable) {set(variable);}
copy()472 ExpressionItem *copy() const {return new YesterdayVariable(this);}
473 virtual bool representsPositive(bool = false) {return false;}
474 virtual bool representsNonNegative(bool = false) {return false;}
475 virtual bool representsNonInteger(bool = false) {return false;}
476 virtual bool representsNumber(bool b = false) {return b;}
477 virtual bool representsReal(bool b = false) {return b;}
478 virtual bool representsNonZero(bool b = false) {return b;}
id()479 int id() const {return VARIABLE_ID_YESTERDAY;}
480 };
481 class NowVariable : public DynamicVariable {
482 private:
483 void calculate(MathStructure &m) const;
484 public:
485 NowVariable();
NowVariable(const NowVariable * variable)486 NowVariable(const NowVariable *variable) {set(variable);}
copy()487 ExpressionItem *copy() const {return new NowVariable(this);}
488 virtual bool representsPositive(bool = false) {return false;}
489 virtual bool representsNonNegative(bool = false) {return false;}
490 virtual bool representsNonInteger(bool = false) {return false;}
491 virtual bool representsNumber(bool b = false) {return b;}
492 virtual bool representsReal(bool b = false) {return b;}
493 virtual bool representsNonZero(bool b = false) {return b;}
id()494 int id() const {return VARIABLE_ID_NOW;}
495 };
496 class UptimeVariable : public DynamicVariable {
497 private:
498 void calculate(MathStructure &m) const;
499 public:
500 UptimeVariable();
501 UptimeVariable(const UptimeVariable *variable);
502 ExpressionItem *copy() const;
id()503 int id() const {return VARIABLE_ID_UPTIME;}
504 };
505
506 #endif
507