pimath 0.1.39 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/pimath.js +3127 -2865
  2. package/dist/pimath.js.map +1 -1
  3. package/package.json +16 -12
  4. package/src/algebra/equation.ts +558 -0
  5. package/src/algebra/equationSolver.ts +488 -0
  6. package/src/algebra/factor.ts +338 -0
  7. package/src/algebra/index.ts +11 -0
  8. package/src/algebra/linearSystem.ts +439 -0
  9. package/src/algebra/logicalset.ts +255 -0
  10. package/src/algebra/matrix.ts +474 -0
  11. package/src/algebra/monom.ts +977 -0
  12. package/src/algebra/operations.ts +23 -0
  13. package/src/algebra/polyFactor.ts +668 -0
  14. package/src/algebra/polynom.ts +1247 -0
  15. package/src/analyze/index.ts +4 -0
  16. package/src/analyze/solution.ts +178 -0
  17. package/src/analyze/tableOfSigns.ts +30 -0
  18. package/src/coefficients/fraction.ts +718 -0
  19. package/src/coefficients/index.ts +4 -0
  20. package/src/coefficients/root.ts +346 -0
  21. package/src/geometry/TupleN.ts +128 -0
  22. package/src/geometry/circle.ts +456 -0
  23. package/src/geometry/geomMath.ts +71 -0
  24. package/src/geometry/index.ts +11 -0
  25. package/src/geometry/line.ts +653 -0
  26. package/src/geometry/line3.ts +211 -0
  27. package/src/geometry/plane3.ts +179 -0
  28. package/src/geometry/point.ts +104 -0
  29. package/src/geometry/sphere3.ts +214 -0
  30. package/src/geometry/triangle.ts +482 -0
  31. package/src/geometry/vector.ts +225 -0
  32. package/src/helpers.ts +35 -0
  33. package/src/index.ts +61 -0
  34. package/src/numeric.ts +196 -0
  35. package/src/pimath.interface.ts +162 -0
  36. package/src/randomization/algebra/rndEquation.ts +41 -0
  37. package/src/randomization/algebra/rndMonom.ts +39 -0
  38. package/src/randomization/algebra/rndPolynom.ts +100 -0
  39. package/src/randomization/coefficient/rndFraction.ts +38 -0
  40. package/src/randomization/geometry/rndCircle.ts +27 -0
  41. package/src/randomization/geometry/rndLine.ts +35 -0
  42. package/src/randomization/geometry/rndLine3.ts +27 -0
  43. package/src/randomization/geometry/rndVector.ts +63 -0
  44. package/src/randomization/random.ts +89 -0
  45. package/src/randomization/rndHelpers.ts +102 -0
  46. package/src/randomization/rndTypes.ts +67 -0
  47. package/types/algebra/equation.d.ts +18 -17
  48. package/types/algebra/equation.d.ts.map +1 -1
  49. package/types/algebra/equationSolver.d.ts +7 -3
  50. package/types/algebra/equationSolver.d.ts.map +1 -1
  51. package/types/algebra/factor.d.ts +1 -1
  52. package/types/algebra/factor.d.ts.map +1 -1
  53. package/types/algebra/linearSystem.d.ts +23 -6
  54. package/types/algebra/linearSystem.d.ts.map +1 -1
  55. package/types/algebra/logicalset.d.ts +1 -1
  56. package/types/algebra/logicalset.d.ts.map +1 -1
  57. package/types/algebra/monom.d.ts +1 -6
  58. package/types/algebra/monom.d.ts.map +1 -1
  59. package/types/algebra/operations.d.ts.map +1 -1
  60. package/types/algebra/polyFactor.d.ts +9 -4
  61. package/types/algebra/polyFactor.d.ts.map +1 -1
  62. package/types/algebra/polynom.d.ts +10 -7
  63. package/types/algebra/polynom.d.ts.map +1 -1
  64. package/types/analyze/index.d.ts +2 -0
  65. package/types/analyze/index.d.ts.map +1 -0
  66. package/types/analyze/solution.d.ts +27 -0
  67. package/types/analyze/solution.d.ts.map +1 -0
  68. package/types/analyze/tableOfSigns.d.ts +9 -0
  69. package/types/analyze/tableOfSigns.d.ts.map +1 -0
  70. package/types/coefficients/fraction.d.ts +14 -12
  71. package/types/coefficients/fraction.d.ts.map +1 -1
  72. package/types/coefficients/index.d.ts +1 -1
  73. package/types/coefficients/index.d.ts.map +1 -1
  74. package/types/coefficients/root.d.ts +41 -0
  75. package/types/coefficients/root.d.ts.map +1 -0
  76. package/types/geometry/TupleAbstract.d.ts +22 -0
  77. package/types/geometry/TupleAbstract.d.ts.map +1 -0
  78. package/types/geometry/TupleN.d.ts +24 -0
  79. package/types/geometry/TupleN.d.ts.map +1 -0
  80. package/types/geometry/circle.d.ts +26 -17
  81. package/types/geometry/circle.d.ts.map +1 -1
  82. package/types/geometry/geomMath.d.ts +2 -1
  83. package/types/geometry/geomMath.d.ts.map +1 -1
  84. package/types/geometry/index.d.ts.map +1 -1
  85. package/types/geometry/line.d.ts +21 -30
  86. package/types/geometry/line.d.ts.map +1 -1
  87. package/types/geometry/line3.d.ts +19 -19
  88. package/types/geometry/line3.d.ts.map +1 -1
  89. package/types/geometry/matrix.d.ts +11 -11
  90. package/types/geometry/plane3.d.ts +9 -9
  91. package/types/geometry/plane3.d.ts.map +1 -1
  92. package/types/geometry/point.d.ts +12 -7
  93. package/types/geometry/point.d.ts.map +1 -1
  94. package/types/geometry/triangle.d.ts +68 -23
  95. package/types/geometry/triangle.d.ts.map +1 -1
  96. package/types/geometry/vector.d.ts +24 -44
  97. package/types/geometry/vector.d.ts.map +1 -1
  98. package/types/helpers.d.ts +1 -0
  99. package/types/helpers.d.ts.map +1 -1
  100. package/types/index.d.ts +6 -4
  101. package/types/index.d.ts.map +1 -1
  102. package/types/numeric.d.ts +2 -0
  103. package/types/numeric.d.ts.map +1 -1
  104. package/types/pimath.interface.d.ts +38 -44
  105. package/types/pimath.interface.d.ts.map +1 -1
  106. package/types/randomization/algebra/rndPolynom.d.ts.map +1 -1
  107. package/types/randomization/coefficient/rndFraction.d.ts +1 -1
  108. package/types/randomization/coefficient/rndFraction.d.ts.map +1 -1
  109. package/types/randomization/geometry/rndLine.d.ts.map +1 -1
  110. package/types/randomization/random.d.ts +3 -2
  111. package/types/randomization/random.d.ts.map +1 -1
  112. package/types/randomization/rndTypes.d.ts +15 -10
  113. package/types/randomization/rndTypes.d.ts.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pimath",
3
- "version": "0.1.39",
3
+ "version": "0.2.0",
4
4
  "description": "A math library for teacher :)",
5
5
  "type": "module",
6
6
  "main": "dist/pimath.js",
@@ -13,9 +13,11 @@
13
13
  "require": "./dist/pimath.js"
14
14
  }
15
15
  },
16
+ "./types/index.d.ts": "./types/index.d.ts",
16
17
  "files": [
17
18
  "dist",
18
- "types"
19
+ "types",
20
+ "src"
19
21
  ],
20
22
  "scripts": {
21
23
  "dev": "vite serve",
@@ -36,20 +38,22 @@
36
38
  "url": "git+https://github.com/basilgass/PiMath.git"
37
39
  },
38
40
  "devDependencies": {
39
- "autoprefixer": "^10.4.22",
40
- "dependency-cruiser": "^17.3.2",
41
- "eslint": "^9.39.1",
42
- "globals": "^16.5.0",
43
- "postcss": "^8.5.6",
44
- "tailwindcss": "^3.4.18",
41
+ "@tailwindcss/vite": "^4.1.18",
42
+ "@vitejs/plugin-vue": "^6.0.4",
43
+ "autoprefixer": "^10.4.24",
44
+ "dependency-cruiser": "^17.3.8",
45
+ "eslint": "^9.39.2",
46
+ "globals": "^17.3.0",
47
+ "tailwindcss": "^4.1.18",
45
48
  "ts-loader": "^9.5.4",
46
49
  "ts-node": "^10.9.2",
47
- "typedoc": "^0.28.15",
50
+ "typedoc": "^0.28.16",
48
51
  "typescript": "^5.9.3",
49
- "typescript-eslint": "^8.49.0",
50
- "vite": "^7.2.7",
52
+ "typescript-eslint": "^8.54.0",
53
+ "vite": "^7.3.1",
51
54
  "vite-plugin-dts": "^4.5.4",
52
- "vitest": "^4.0.15"
55
+ "vitest": "^4.0.18",
56
+ "vue-router": "^5.0.2"
53
57
  },
54
58
  "dependencies": {
55
59
  "piexpression": "^0.1.3"
@@ -0,0 +1,558 @@
1
+ import type {
2
+ EQUATION_SIGN,
3
+ IAlgebra,
4
+ IEquation,
5
+ InputAlgebra,
6
+ InputValue,
7
+ IPiMathObject,
8
+ literalType
9
+ } from "../pimath.interface"
10
+ import {Fraction} from "../coefficients/fraction"
11
+ import {Numeric} from "../numeric"
12
+ import {EquationSolver} from "./equationSolver"
13
+ import {Monom} from "./monom"
14
+ import {Polynom} from "./polynom"
15
+ import type {Solution} from "../analyze/solution"
16
+
17
+ export class Equation implements
18
+ IPiMathObject<Equation>,
19
+ IEquation<Equation>,
20
+ IAlgebra<Equation> {
21
+
22
+ // Left part of the equation
23
+ #left: Polynom
24
+ // Right part of the equation
25
+ #right: Polynom
26
+ // Signe of the equation
27
+ #sign: EQUATION_SIGN
28
+
29
+
30
+ constructor(equation: InputAlgebra<Polynom> | Equation)
31
+ constructor(left: InputAlgebra<Polynom>, right: InputAlgebra<Polynom>, sign?: EQUATION_SIGN)
32
+ constructor(left?: InputAlgebra<Polynom> | Equation, right?: InputAlgebra<Polynom>, sign?: EQUATION_SIGN) {
33
+ // Default equation
34
+ this.#left = new Polynom().zero()
35
+ this.#right = new Polynom().zero()
36
+ this.#sign = '='
37
+
38
+ // Only one value, it's an equation
39
+ if (left !== undefined && right === undefined) {
40
+ if (left instanceof Equation) {
41
+ return left.clone()
42
+ } else if (typeof left === 'string') {
43
+ // Parse the equation as a string.
44
+ this.parse(left)
45
+ }
46
+
47
+ } else if (left !== undefined && right !== undefined) {
48
+ // Two values, it's an equation with left and right polynoms.
49
+ this.left = new Polynom(left as InputAlgebra<Polynom>)
50
+ this.right = new Polynom(right)
51
+ }
52
+
53
+ if (sign !== undefined) {
54
+ this.sign = sign
55
+ }
56
+
57
+ return this
58
+ }
59
+
60
+ // ------------------------------------------
61
+ public parse = (equationString: string): this => {
62
+ // Find the string separator
63
+ const strSign: string | false = this.#findSign(equationString)
64
+
65
+ if (strSign === false) {
66
+ throw new Error('The equation is not valid (no sign found)')
67
+ }
68
+
69
+ // The StrSign is found
70
+ const pStr: string[] = equationString.split(strSign)
71
+
72
+ return this.create(new Polynom(pStr[0]), new Polynom(pStr[1]), this.#formatSign(strSign))
73
+ }
74
+
75
+ public clone = (): Equation => {
76
+ return new Equation(this.#left.clone(), this.#right.clone(), this.#sign)
77
+ }
78
+
79
+ public get tex(): string {
80
+ return `${this.#left.tex}${this.signAsTex}${this.#right.tex}`
81
+ }
82
+
83
+ public get display(): string {
84
+ return `${this.#left.display}${this.signAsTex}${this.#right.display}`
85
+ }
86
+
87
+ public static isEquationString(equationString: string): boolean {
88
+ // The equation sign can be one of the following:
89
+ // =, <, >, <=, >=
90
+
91
+ return equationString.includes('=') ||
92
+ equationString.includes('<') ||
93
+ equationString.includes('>') ||
94
+ equationString.includes('<=') ||
95
+ equationString.includes('>=')
96
+ }
97
+
98
+ public static makeSolutionsUnique(solutions: Solution[], sorted?: boolean): Solution[] {
99
+ const solutionAsTex: string[] = [],
100
+ uniqueSolutions = solutions.filter(sol => {
101
+ if (!solutionAsTex.includes(sol.tex)) {
102
+ solutionAsTex.push(sol.tex)
103
+ return true
104
+ } else {
105
+ return false
106
+ }
107
+ })
108
+
109
+ if (sorted === true) {
110
+ uniqueSolutions.sort((a, b) => a.value - b.value)
111
+ }
112
+
113
+ return uniqueSolutions
114
+ }
115
+
116
+ /**
117
+ * Add a value to the equation
118
+ * if value is an equation, add the left part to the left part of the equation
119
+ * and the right part to the right part of the equation
120
+ * if value is a string, try to create an equation
121
+ * if it fails, create a polynom and add it to the left and right part of the equation
122
+ * @param value | Polynom | Monom | Fraction | string | monom
123
+ */
124
+ public add(value: InputValue<Equation | Polynom>): this {
125
+
126
+ if (value instanceof Equation) {
127
+ // add the left part of the equation
128
+ this.#left.add(value.left)
129
+ // add the right part of the equation
130
+ this.#right.add(value.right)
131
+
132
+ return this
133
+ }
134
+
135
+ if (typeof value === 'string' &&
136
+ !Equation.isEquationString(value)) {
137
+
138
+ return this.add(new Equation(value))
139
+ }
140
+
141
+ const p = new Polynom(value)
142
+ this.#left.add(p)
143
+ this.#right.add(p)
144
+
145
+ return this
146
+ }
147
+
148
+ public create = (left: Polynom, right: Polynom, sign?: string): this => {
149
+ this.#left = left
150
+ this.#right = right
151
+ this.#sign = this.#formatSign(sign ?? "=")
152
+ return this
153
+ }
154
+
155
+ /**
156
+ * Get the degree of the equation
157
+ * @param letter
158
+ */
159
+ public degree = (letter?: string): Fraction => {
160
+ return Fraction.max(this.#left.degree(letter), this.#right.degree(letter))
161
+ }
162
+
163
+ /**
164
+ * divide an equation by a given value (transformed as a fraction)
165
+ *
166
+ * ```
167
+ * 8x+10=6x \vert 2
168
+ * 4x+5=3x
169
+ * ```
170
+ *
171
+ * |>Alternatively with $3x-4$ maybe it's working ?
172
+ * $$\frac{3x}{5}$$
173
+ *
174
+ * @param value
175
+ * @returns {Equation}
176
+ */
177
+ public divide = (value: InputValue<Fraction>): this => {
178
+ // Make sure we have a fraction.
179
+ const F: Fraction = new Fraction(value)
180
+
181
+ if (F.isZero()) {
182
+ return this
183
+ } else {
184
+ return this.multiply(F.inverse())
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Create an Equation using two polynoms.
190
+ * Markdown *support* is cool
191
+ * @param values
192
+ * @param asNumeric
193
+ */
194
+ public evaluate(values: InputValue<Fraction> | literalType<number | Fraction>, asNumeric?: boolean ): boolean {
195
+ // Evaluate the left and right part of the equation.
196
+ // compare the results.
197
+
198
+ // Evaluate the left and right part of the equation.
199
+ const left = this.#left.evaluate(values, asNumeric),
200
+ right = this.#right.evaluate(values, asNumeric)
201
+
202
+ // compare the results.
203
+ if (asNumeric) {
204
+ return left === right
205
+ }
206
+
207
+ return (left as Fraction).isEqual(right as Fraction)
208
+ }
209
+
210
+ // -----------------------------------------------
211
+
212
+ /**
213
+ * Determine if the equation contains a variable.
214
+ * @param letter
215
+ */
216
+ public hasVariable = (letter: string): boolean => {
217
+ return this.variables.includes(letter)
218
+ }
219
+
220
+ public isEqual(value: InputValue<Equation>): boolean {
221
+ const equ = new Equation(value)
222
+ return equ.left.isEqual(this.#left) && equ.right.isEqual(this.#right)
223
+ }
224
+
225
+ // -----------------------------------------------
226
+ // Equations operations
227
+
228
+ // Equations helpers
229
+ public isEqualTo = (equ: Equation): boolean => {
230
+ const p1 = equ.clone().moveLeft().left,
231
+ p2 = this.clone().moveLeft().left
232
+
233
+ // They are the same.
234
+ return p1.isEqual(p2) || p1.isOppositeAt(p2)
235
+ }
236
+
237
+ public isLinearTo = (equ: Equation): boolean => {
238
+ // Move all left.
239
+ const p1 = equ.clone().moveLeft().simplify().left,
240
+ p2 = this.clone().moveLeft().simplify().left
241
+
242
+ // They are the same.
243
+ return p1.isEqual(p2) || p1.isOppositeAt(p2)
244
+ }
245
+
246
+ /**
247
+ * Determine if the equation contains more than one letter/variable.
248
+ */
249
+ public isMultiVariable = (): boolean => {
250
+ return this.#left.isMultiVariable || this.#right.isMultiVariable
251
+ }
252
+
253
+ /**
254
+ * Reorder the polynom to have only one letter on the left, the rest on the right.
255
+ * @param letter
256
+ */
257
+ public isolate = (letter?: string): this | false => {
258
+ // Determine if we can isolate the variables.
259
+
260
+ // Both part of the equations must be of the first degree.
261
+ if (!this.degree(letter).isOne()) {
262
+ return false
263
+ }
264
+
265
+ // Modify the equation to isolate the asked variable.
266
+ if (this.isMultiVariable()) {
267
+ return false
268
+ }
269
+
270
+ // Isolate the letter.
271
+ let mMove: Monom
272
+ // Start by moving everything to the left.
273
+ this.#left.subtract(this.#right)
274
+ this.#right.zero()
275
+ const values = [...this.#left.monoms]
276
+ for (const m of values) {
277
+ if (!m.hasVariable(letter)) {
278
+ mMove = m.clone()
279
+ this.#left.subtract(mMove)
280
+ this.#right.subtract(mMove)
281
+ }
282
+ }
283
+
284
+ // In theory, we should have only one item on the left.
285
+ if (this.#left.length !== 1) {
286
+ return false
287
+ }
288
+
289
+ const cMove: Fraction = this.#left.monoms[0].coefficient.clone()
290
+ this.#left.divide(cMove)
291
+ this.#right.divide(cMove)
292
+ return this
293
+ }
294
+
295
+ // Getter and setter
296
+ public get left(): Polynom {
297
+ return this.#left
298
+ }
299
+
300
+ public set left(value: Polynom) {
301
+ this.#left = value
302
+ }
303
+
304
+ // -----------------------------------------------
305
+ public letters = (): string[] => {
306
+ return [...new Set([...this.#left.letters(), ...this.#right.letters()])]
307
+ }
308
+
309
+ // -----------------------------------------------
310
+ /**
311
+ * Reorder will move all monoms containing a letter on the left, all the other on the right.
312
+ */
313
+ public moveLeft = (): this => {
314
+ this.#left.subtract(this.#right)
315
+ this.#right.zero()
316
+ return this
317
+ }
318
+
319
+ /**
320
+ * Multiple an equation by a fraction value.
321
+ * @param value
322
+ */
323
+ public multiply = (value: InputValue<Fraction>): this => {
324
+ // Make sure we have a fraction.
325
+ const F: Fraction = new Fraction(value)
326
+
327
+ // Multiply each part of the equation by the fraction
328
+ this.#left.multiply(F)
329
+ this.#right.multiply(F)
330
+
331
+ // The sign of the inequality must be changed.
332
+ if (this.#sign !== '=' && F.sign() === -1) {
333
+ this.#reverseSign()
334
+ }
335
+
336
+ return this
337
+ }
338
+
339
+ public get numberOfVars(): number {
340
+ return this.variables.length
341
+ }
342
+
343
+ public opposite = (): this => {
344
+ this.#left = this.#left.opposite()
345
+ this.#right = this.#right.opposite()
346
+ return this
347
+ }
348
+
349
+ public pow(value: number): this {
350
+ this.#left.pow(value)
351
+ this.#right.pow(value)
352
+ return this
353
+ }
354
+
355
+ public reduce(): this {
356
+ // reduce means moving everything to the left
357
+ // remove the fractions
358
+ // simplify the equation
359
+ // reorder the equation
360
+ // start with a positive left part
361
+
362
+ // Move all left. The right part is now zero.
363
+ this.moveLeft()
364
+
365
+ // Reduce the equation: simplify and reorder.
366
+ this.#left.reduce()
367
+
368
+ // Simplify the equation.
369
+ this.simplify()
370
+
371
+ // Make sure the first part is positive.
372
+ if (this.#left.monoms[0].coefficient.isNegative()) {
373
+ this.multiply(-1)
374
+ }
375
+
376
+ return this
377
+ }
378
+
379
+ public reorder = (allLeft?: boolean): this => {
380
+ // Move all monoms of degree greater than 0 to the left.
381
+ // and all zero degree monoms to the right.
382
+ this.#left.subtract(this.#right)
383
+ this.#right.zero()
384
+ this.#left.reorder()
385
+
386
+ // we have all left (so equal zero) : it's done !
387
+ if (allLeft) {
388
+ return this
389
+ }
390
+
391
+ // Fetch all zero degree monoms.
392
+ this.#left.monoms
393
+ .filter(m => m.degree().isZero())
394
+ .forEach(m => {
395
+ const move = m.clone()
396
+ this.#left.subtract(move)
397
+ this.#right.subtract(move)
398
+ })
399
+
400
+ // Reorder the left and right polynoms
401
+ this.#left.reorder()
402
+ this.#right.reorder()
403
+ return this
404
+ }
405
+
406
+ // ------------------------------------------
407
+ public replaceBy = (letter: string, P: Polynom): this => {
408
+ this.#left.replaceBy(letter, P)
409
+ this.#right.replaceBy(letter, P)
410
+ return this
411
+ }
412
+
413
+ public get right(): Polynom {
414
+ return this.#right
415
+ }
416
+
417
+ public set right(value: Polynom) {
418
+ this.#right = value
419
+ }
420
+
421
+ // ------------------------------------------
422
+ public get sign(): string {
423
+ return this.#sign
424
+ }
425
+
426
+ public set sign(value: string) {
427
+ // Set the sign value as formatted.
428
+ this.#sign = this.#formatSign(value)
429
+ }
430
+
431
+ public get signAsTex(): string {
432
+ if (this.#sign === '>=') {
433
+ return '\\geq'
434
+ }
435
+
436
+ if (this.#sign === '<=') {
437
+ return '\\leq'
438
+ }
439
+
440
+ return this.#sign
441
+ }
442
+
443
+ /**
444
+ * Multiply by the lcm denominator and divide by the gcm numerators.
445
+ */
446
+ public simplify = (): this => {
447
+ this.multiply(Numeric.lcm(...this.#left.getDenominators(), ...this.#right.getDenominators()))
448
+ this.divide(Numeric.gcd(...this.#left.getNumerators(), ...this.#right.getNumerators()))
449
+ return this
450
+ }
451
+
452
+ // -----------------------------------------------
453
+ public solve = (): Solution[] => {
454
+ const solver = new EquationSolver(this.clone())
455
+ return solver.solve()
456
+ }
457
+
458
+ public split(): [Polynom, Polynom] {
459
+ return [this.#left.clone(), this.#right.clone()]
460
+ }
461
+
462
+ public subtract(value: InputValue<Equation | Polynom>): this {
463
+ if (value instanceof Equation) {
464
+ this.#left.subtract(value.left)
465
+ this.#right.subtract(value.right)
466
+
467
+ return this
468
+ }
469
+
470
+ if (typeof value === 'string' &&
471
+ !Equation.isEquationString(value)) {
472
+ return this.subtract(new Equation(value))
473
+ }
474
+
475
+ const p = new Polynom(value)
476
+ this.#left.subtract(p)
477
+ this.#right.subtract(p)
478
+
479
+ return this
480
+ }
481
+
482
+ public test = (values: literalType<Fraction>): boolean => {
483
+ return (this.left.evaluate(values) as Fraction).isEqual(this.right.evaluate(values))
484
+ }
485
+
486
+ public get variables(): string[] {
487
+ return [...new Set(this.#right.variables.concat(this.#left.variables))]
488
+ }
489
+
490
+ #findSign = (equationString: string): string | false => {
491
+ if (equationString.includes('geq')) {
492
+ return (equationString.includes('\\geq')) ? '\\geq' : 'geq'
493
+ } else if (equationString.includes('leq')) {
494
+ return (equationString.includes('\\leq')) ? '\\leq' : 'leq'
495
+ } else if (equationString.includes('>=')) {
496
+ return '>='
497
+ } else if (equationString.includes('=>')) {
498
+ return '=>'
499
+ } else if (equationString.includes('>')) {
500
+ return '>'
501
+ } else if (equationString.includes('<=')) {
502
+ return '<='
503
+ } else if (equationString.includes('=<')) {
504
+ return '=<'
505
+ } else if (equationString.includes('<')) {
506
+ return '<'
507
+ } else if (equationString.includes('=')) {
508
+ return '='
509
+ }
510
+
511
+ throw new Error('The equation is not valid (no sign found)')
512
+ }
513
+
514
+ // -----------------------------------------------
515
+ // Equations solving algorithms
516
+ #formatSign = (signStr?: string): EQUATION_SIGN => {
517
+ if (signStr === undefined) {
518
+ return '='
519
+ }
520
+
521
+ if (signStr.includes('geq')) {
522
+ return '>='
523
+ } else if (signStr.includes('>=')) {
524
+ return '>='
525
+ } else if (signStr.includes('=>')) {
526
+ return '>='
527
+ } else if (signStr.includes('>')) {
528
+ return '>'
529
+ } else if (signStr.includes('leq')) {
530
+ return '<='
531
+ } else if (signStr.includes('<=')) {
532
+ return '<='
533
+ } else if (signStr.includes('=<')) {
534
+ return '<='
535
+ } else if (signStr.includes('<')) {
536
+ return '<'
537
+ } else {
538
+ return '='
539
+ }
540
+ }
541
+
542
+ #reverseSign = (): this => {
543
+ if (this.#sign === '=') {
544
+ return this
545
+ }
546
+
547
+ if (this.#sign.includes('<')) {
548
+ this.#sign.replace('<', '>')
549
+ return this
550
+ }
551
+ if (this.#sign.includes('>')) {
552
+ this.#sign.replace('>', '<')
553
+ return this
554
+ }
555
+
556
+ return this
557
+ }
558
+ }