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