pimath 0.0.132 → 0.0.134
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.
- package/dist/pimath.js +2444 -3566
- package/package.json +37 -20
- package/types/algebra/equation.d.ts +109 -0
- package/types/algebra/equation.d.ts.map +1 -0
- package/types/algebra/equationSolver.d.ts +16 -0
- package/types/algebra/equationSolver.d.ts.map +1 -0
- package/types/algebra/factor.d.ts +47 -0
- package/types/algebra/factor.d.ts.map +1 -0
- package/{dist/maths → types}/algebra/monom.d.ts +98 -131
- package/types/algebra/monom.d.ts.map +1 -0
- package/types/algebra/polyFactor.d.ts +41 -0
- package/types/algebra/polyFactor.d.ts.map +1 -0
- package/types/algebra/polynom.d.ts +126 -0
- package/types/algebra/polynom.d.ts.map +1 -0
- package/types/algebra/rational.d.ts +41 -0
- package/types/algebra/rational.d.ts.map +1 -0
- package/{dist/maths → types}/coefficients/fraction.d.ts +69 -66
- package/types/coefficients/fraction.d.ts.map +1 -0
- package/{dist/maths → types}/coefficients/nthRoot.d.ts +3 -3
- package/{dist/maths → types}/geometry/circle.d.ts +10 -15
- package/types/geometry/circle.d.ts.map +1 -0
- package/types/geometry/geomMath.d.ts +10 -0
- package/types/geometry/geomMath.d.ts.map +1 -0
- package/{dist/maths → types}/geometry/line.d.ts +25 -35
- package/types/geometry/line.d.ts.map +1 -0
- package/types/geometry/line3.d.ts +50 -0
- package/types/geometry/line3.d.ts.map +1 -0
- package/types/geometry/plane3.d.ts +29 -0
- package/types/geometry/plane3.d.ts.map +1 -0
- package/types/geometry/vector.d.ts +70 -0
- package/types/geometry/vector.d.ts.map +1 -0
- package/types/geometry/vector3d.d.ts +37 -0
- package/types/geometry/vector3d.d.ts.map +1 -0
- package/types/index.d.ts +57 -0
- package/types/index.d.ts.map +1 -0
- package/types/numeric.d.ts +39 -0
- package/types/pimath.interface.d.ts +57 -0
- package/types/pimath.interface.d.ts.map +1 -0
- package/types/randomization/algebra/rndEquation.d.ts +4 -0
- package/types/randomization/algebra/rndEquation.d.ts.map +1 -0
- package/types/randomization/algebra/rndMonom.d.ts +4 -0
- package/types/randomization/algebra/rndMonom.d.ts.map +1 -0
- package/types/randomization/algebra/rndPolynom.d.ts +5 -0
- package/types/randomization/algebra/rndPolynom.d.ts.map +1 -0
- package/types/randomization/coefficient/rndFraction.d.ts +4 -0
- package/types/randomization/coefficient/rndFraction.d.ts.map +1 -0
- package/types/randomization/geometry/rndCircle.d.ts +4 -0
- package/types/randomization/geometry/rndCircle.d.ts.map +1 -0
- package/types/randomization/geometry/rndLine.d.ts +4 -0
- package/types/randomization/geometry/rndLine.d.ts.map +1 -0
- package/types/randomization/geometry/rndLine3.d.ts +4 -0
- package/types/randomization/geometry/rndLine3.d.ts.map +1 -0
- package/types/randomization/geometry/rndPoint.d.ts +4 -0
- package/types/randomization/geometry/rndPoint.d.ts.map +1 -0
- package/types/randomization/random.d.ts +20 -0
- package/types/randomization/random.d.ts.map +1 -0
- package/types/randomization/rndHelpers.d.ts +21 -0
- package/types/randomization/rndTypes.d.ts +64 -0
- package/types/randomization/rndTypes.d.ts.map +1 -0
- package/dist/main.d.ts +0 -1
- package/dist/maths/algebra/equation.d.ts +0 -120
- package/dist/maths/algebra/linearSystem.d.ts +0 -40
- package/dist/maths/algebra/logicalset.d.ts +0 -28
- package/dist/maths/algebra/polynom.d.ts +0 -155
- package/dist/maths/algebra/rational.d.ts +0 -44
- package/dist/maths/algebra/study/rationalStudy.d.ts +0 -14
- package/dist/maths/algebra/study.d.ts +0 -140
- package/dist/maths/geometry/point.d.ts +0 -36
- package/dist/maths/geometry/triangle.d.ts +0 -92
- package/dist/maths/geometry/vector.d.ts +0 -38
- package/dist/maths/numeric.d.ts +0 -28
- package/dist/maths/numexp.d.ts +0 -19
- package/dist/maths/randomization/random.d.ts +0 -26
- package/dist/maths/randomization/randomCore.d.ts +0 -7
- package/dist/maths/randomization/rndFraction.d.ts +0 -13
- package/dist/maths/randomization/rndGeometryCircle.d.ts +0 -13
- package/dist/maths/randomization/rndGeometryLine.d.ts +0 -13
- package/dist/maths/randomization/rndGeometryPoint.d.ts +0 -13
- package/dist/maths/randomization/rndHelpers.d.ts +0 -23
- package/dist/maths/randomization/rndMonom.d.ts +0 -13
- package/dist/maths/randomization/rndPolynom.d.ts +0 -14
- package/dist/maths/randomization/rndTypes.d.ts +0 -40
- package/dist/maths/shutingyard.d.ts +0 -59
- package/dist/pimath.d.ts +0 -39
- package/lib/main.ts +0 -1
- package/lib/maths/algebra/equation.ts +0 -891
- package/lib/maths/algebra/linearSystem.ts +0 -369
- package/lib/maths/algebra/logicalset.ts +0 -183
- package/lib/maths/algebra/monom.ts +0 -1027
- package/lib/maths/algebra/polynom.ts +0 -1537
- package/lib/maths/algebra/rational.ts +0 -244
- package/lib/maths/algebra/study/rationalStudy.ts +0 -287
- package/lib/maths/algebra/study.ts +0 -506
- package/lib/maths/coefficients/fraction.ts +0 -593
- package/lib/maths/coefficients/nthRoot.ts +0 -148
- package/lib/maths/geometry/circle.ts +0 -379
- package/lib/maths/geometry/line.ts +0 -604
- package/lib/maths/geometry/point.ts +0 -215
- package/lib/maths/geometry/triangle.ts +0 -368
- package/lib/maths/geometry/vector.ts +0 -243
- package/lib/maths/numeric.ts +0 -162
- package/lib/maths/numexp.ts +0 -198
- package/lib/maths/randomization/random.ts +0 -80
- package/lib/maths/randomization/randomCore.ts +0 -19
- package/lib/maths/randomization/rndFraction.ts +0 -47
- package/lib/maths/randomization/rndGeometryCircle.ts +0 -50
- package/lib/maths/randomization/rndGeometryLine.ts +0 -53
- package/lib/maths/randomization/rndGeometryPoint.ts +0 -69
- package/lib/maths/randomization/rndHelpers.ts +0 -107
- package/lib/maths/randomization/rndMonom.ts +0 -57
- package/lib/maths/randomization/rndPolynom.ts +0 -90
- package/lib/maths/randomization/rndTypes.ts +0 -43
- package/lib/maths/shutingyard.ts +0 -496
- package/lib/pimath.ts +0 -40
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
import {Equation, ISolution} from "./equation";
|
|
2
|
-
import {Monom} from "./monom";
|
|
3
|
-
import {Fraction} from "../coefficients/fraction";
|
|
4
|
-
import {Polynom} from "./polynom";
|
|
5
|
-
import {Numeric} from "../numeric.ts";
|
|
6
|
-
|
|
7
|
-
// TODO: Must check and rework
|
|
8
|
-
export class LinearSystem {
|
|
9
|
-
// Stores the original equations
|
|
10
|
-
private _equations: Equation[];
|
|
11
|
-
// Determine the letters in the linear system, usually ['x', 'y']
|
|
12
|
-
private _letters: string[];
|
|
13
|
-
// Resolution steps contains each steps
|
|
14
|
-
// letter : target letter
|
|
15
|
-
// steps: {system: current LinearSystem, operations: [*3,/5] or [[*3,*2], [,*5], [*2,]]}
|
|
16
|
-
private _resolutionSteps: {
|
|
17
|
-
[key: string]: {
|
|
18
|
-
equations: Equation[],
|
|
19
|
-
operations: (string[])[]
|
|
20
|
-
}[]
|
|
21
|
-
};
|
|
22
|
-
// Get the solution of the equation
|
|
23
|
-
private _solutions: { [letter: string]: ISolution };
|
|
24
|
-
|
|
25
|
-
constructor(...equationStrings: (string | Equation)[]) {
|
|
26
|
-
// TODO: allow construction to accept an array of values (like a matrix) to build the equations
|
|
27
|
-
this._equations = [];
|
|
28
|
-
this._letters = 'xyz'.split('');
|
|
29
|
-
|
|
30
|
-
if (equationStrings !== undefined && equationStrings.length > 0) {
|
|
31
|
-
this.parse(...equationStrings);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// ------------------------------------------
|
|
38
|
-
// Getter and setter
|
|
39
|
-
// ------------------------------------------
|
|
40
|
-
get equations(): Equation[] {
|
|
41
|
-
return this._equations;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
set equations(value) {
|
|
45
|
-
this._equations = value;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
get letters(): string {
|
|
49
|
-
return this._letters.join('')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
set letters(value: string) {
|
|
53
|
-
this._letters = value.split('');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get isSolvable(): boolean {
|
|
57
|
-
let V = this.variables;
|
|
58
|
-
|
|
59
|
-
// TODO: in some case, it is possible to resolve systems if there isn't the isSame number of vars and equations
|
|
60
|
-
if (V.length !== this._equations.length) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
//TODO: Must check if two equations isn't a linear combination of the others ?
|
|
65
|
-
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
get variables(): string[] {
|
|
70
|
-
return this._letters
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
get tex(): string {
|
|
74
|
-
// Build the array of values.
|
|
75
|
-
// Reorder
|
|
76
|
-
// This clone the system :!!!
|
|
77
|
-
//TODO: Avoid cloning this linear system
|
|
78
|
-
let LS = this.clone().reorder(),
|
|
79
|
-
letters = LS.variables
|
|
80
|
-
|
|
81
|
-
return this.buildTex(LS.equations)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
get solution(): string {
|
|
85
|
-
let tex: string[] = [];
|
|
86
|
-
|
|
87
|
-
if (this._solutions === undefined) {
|
|
88
|
-
this.solve();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
for (let letter in this._solutions) {
|
|
92
|
-
if (this._solutions[letter].display === "RR") {
|
|
93
|
-
return `\\left\\{ \\left(${this._letters.join(';')}\\right) \\big\\vert ${this.equations[0].tex} \\right\\}`;
|
|
94
|
-
}
|
|
95
|
-
if (this._solutions[letter].display === "O/") {
|
|
96
|
-
return `\\varnothing`
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
tex.push(this._solutions[letter].tex);
|
|
100
|
-
}
|
|
101
|
-
return `\\left(${tex.join(';')}\\right)`;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
get solutionAsDisplay(): string {
|
|
105
|
-
let display: string[] = [];
|
|
106
|
-
|
|
107
|
-
if (this._solutions === undefined) {
|
|
108
|
-
this.solve();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
for (let letter in this._solutions) {
|
|
112
|
-
if (this._solutions[letter].display === "RR") {
|
|
113
|
-
return `{(${this._letters.join(';')}) | ${this.equations[0].display} }`;
|
|
114
|
-
}
|
|
115
|
-
if (this._solutions[letter].display === "O/") {
|
|
116
|
-
return "O/"
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
display.push(this._solutions[letter].display);
|
|
120
|
-
}
|
|
121
|
-
return `(${display.join(';')})`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
get resolutionSteps(): { [p: string]: { equations: Equation[]; operations: string[][] }[] } {
|
|
125
|
-
return this._resolutionSteps;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
buildTex = (equations: Equation[], operators?: (string[])[]): string => {
|
|
129
|
-
let equStr: string[],
|
|
130
|
-
equArray: string[] = [],
|
|
131
|
-
m: Monom,
|
|
132
|
-
letters: string[] = []
|
|
133
|
-
|
|
134
|
-
// Get the letters from the linear system
|
|
135
|
-
for (let equ of equations) {
|
|
136
|
-
letters = letters.concat(equ.letters())
|
|
137
|
-
}
|
|
138
|
-
letters = [...new Set(letters)]
|
|
139
|
-
letters.sort()
|
|
140
|
-
|
|
141
|
-
for (let i = 0; i < equations.length; i++) {
|
|
142
|
-
let equ = equations[i]
|
|
143
|
-
|
|
144
|
-
equStr = [];
|
|
145
|
-
for (let L of letters) {
|
|
146
|
-
m = equ.left.monomByLetter(L);
|
|
147
|
-
|
|
148
|
-
if (equStr.length === 0) {
|
|
149
|
-
equStr.push(m.isZero() ? '' : m.tex);
|
|
150
|
-
} else {
|
|
151
|
-
equStr.push(m.isZero() ? '' : ((m.coefficient.sign() === 1) ? '+' : '') + m.tex);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Add the equal sign
|
|
156
|
-
equStr.push('=');
|
|
157
|
-
|
|
158
|
-
// Add the right hand part of the equation (should be only a number, because it has been reordered)
|
|
159
|
-
equStr.push(equ.right.tex);
|
|
160
|
-
|
|
161
|
-
// Add the operations if existing
|
|
162
|
-
if (operators !== undefined && operators[i] !== undefined) {
|
|
163
|
-
// add extra space at the end of the equation
|
|
164
|
-
equStr[equStr.length - 1] = equStr[equStr.length - 1] + ' \\phantom{\\quad}'
|
|
165
|
-
for (let o of operators[i]) {
|
|
166
|
-
equStr.push(`\\ \\cdot\\ ${o.startsWith('-') ? "\\left(" + o + "\\right)" : o}`)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Add to the list.
|
|
171
|
-
equArray.push(equStr.join('&'));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
let operatorsColumns = 0
|
|
175
|
-
if (operators !== undefined && operators.length > 0) {
|
|
176
|
-
operatorsColumns = operators[0].length
|
|
177
|
-
}
|
|
178
|
-
return `\\left\\{\\begin{array}{${"r".repeat(letters.length)}cl ${"|l".repeat(operatorsColumns)}}${equArray.join('\\\\\ ')}\\end{array}\\right.`;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
stepTex = (letter: string): string => {
|
|
182
|
-
const steps = this._resolutionSteps[letter]
|
|
183
|
-
|
|
184
|
-
if (steps === undefined) {
|
|
185
|
-
return ''
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// steps = { equations[], operations: [[],[]]
|
|
189
|
-
let tex: string[] = []
|
|
190
|
-
for (let i = 0; i < steps.length; i++) {
|
|
191
|
-
tex.push(this.buildTex(steps[i].equations, steps[i].operations))
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return `\\begin{aligned}&${tex.join('\\\\&')}\\end{aligned}`
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// ------------------------------------------
|
|
199
|
-
// Creation / parsing functions
|
|
200
|
-
|
|
201
|
-
// ------------------------------------------
|
|
202
|
-
parse = (...equations: (string | Equation)[]): LinearSystem => {
|
|
203
|
-
// make the original equations
|
|
204
|
-
this._equations = equations.map(value => new Equation(value));
|
|
205
|
-
// get the letters.
|
|
206
|
-
this._findLetters();
|
|
207
|
-
return this;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
clone = (): LinearSystem => {
|
|
211
|
-
return new LinearSystem().parse(...this._equations.map(equ => equ.clone()));
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// ------------------------------------------
|
|
215
|
-
reorder = (): LinearSystem => {
|
|
216
|
-
for (let E of this._equations) {
|
|
217
|
-
E.reorder();
|
|
218
|
-
}
|
|
219
|
-
return this;
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
// -----------------------------------------------
|
|
224
|
-
// Equations solving algorithms
|
|
225
|
-
|
|
226
|
-
solve = (withResolution?: boolean): LinearSystem => {
|
|
227
|
-
// Solve it by linear
|
|
228
|
-
this._solutions = {};
|
|
229
|
-
this._resolutionSteps = {};
|
|
230
|
-
|
|
231
|
-
// Reorder all equations.
|
|
232
|
-
this.reorder();
|
|
233
|
-
|
|
234
|
-
if (withResolution === undefined) {
|
|
235
|
-
withResolution = false
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
for (let letter of this.variables) {
|
|
239
|
-
this._solutions[letter] = this._solveOneLetter(letter, withResolution)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// TODO: LinearSystem - solve: optimization and handle undetermined and undefined systems.
|
|
243
|
-
return this;
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
mergeEquations = (eq1: Equation, eq2: Equation, factor1: Fraction, factor2: Fraction): Equation => {
|
|
247
|
-
// Set and clone the equations.
|
|
248
|
-
|
|
249
|
-
let eq1multiplied = eq1.clone().multiply(new Fraction(factor1)),
|
|
250
|
-
eq2multiplied = eq2.clone().multiply(new Fraction(factor2));
|
|
251
|
-
|
|
252
|
-
// Add both equations together.
|
|
253
|
-
eq1multiplied.left.add(eq2multiplied.left);
|
|
254
|
-
eq1multiplied.right.add(eq2multiplied.right);
|
|
255
|
-
|
|
256
|
-
return eq1multiplied;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
private _findLetters = (): LinearSystem => {
|
|
260
|
-
// Find all letters used.
|
|
261
|
-
let variables: Set<string> = new Set();
|
|
262
|
-
|
|
263
|
-
for (let equ of this._equations) {
|
|
264
|
-
variables = new Set([...variables, ...equ.variables]);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
this._letters = [...variables];
|
|
268
|
-
this._letters.sort()
|
|
269
|
-
return this;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
private _linearReduction(eq1: Equation, eq2: Equation, letter: string): { merged: Equation, factors: Fraction[] } {
|
|
273
|
-
// Get the monom for the particular letter.
|
|
274
|
-
let c1 = eq1.left.monomByDegree(1, letter).coefficient.clone(),
|
|
275
|
-
c2 = eq2.left.monomByDegree(1, letter).coefficient.clone().opposed();
|
|
276
|
-
|
|
277
|
-
// Reduce c1 and c2 by the gcd
|
|
278
|
-
const gcdN = Numeric.gcd(c1.numerator, c2.numerator),
|
|
279
|
-
gcdD = Numeric.gcd(c1.denominator, c2.denominator)
|
|
280
|
-
c1.divide(gcdN).multiply(gcdD)
|
|
281
|
-
c2.divide(gcdN).multiply(gcdD)
|
|
282
|
-
|
|
283
|
-
// if one value is -1, use 1 and make the other one opposed
|
|
284
|
-
if (c2.isNegativeOne()) {
|
|
285
|
-
c1.opposed()
|
|
286
|
-
c2.opposed()
|
|
287
|
-
} else if (c1.isNegativeOne()) {
|
|
288
|
-
c1.opposed()
|
|
289
|
-
c2.opposed()
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
return {
|
|
293
|
-
merged: this.mergeEquations(eq1, eq2, c2, c1),
|
|
294
|
-
factors: [c2, c1]
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Linear reduction of the equations to have only one letter
|
|
300
|
-
* @param letter letter to isolate
|
|
301
|
-
* @private
|
|
302
|
-
*/
|
|
303
|
-
private _solveOneLetter(letter: string, withResolution: boolean): ISolution {
|
|
304
|
-
// list of equations.
|
|
305
|
-
let LE: Equation[] = this.clone().equations,
|
|
306
|
-
reducedEquations: Equation[] = [],
|
|
307
|
-
lastIndex
|
|
308
|
-
|
|
309
|
-
this._resolutionSteps[letter] = []
|
|
310
|
-
|
|
311
|
-
// Reduce the equations.
|
|
312
|
-
// Do it as long as there is more than one step, but no more than the number of equations.
|
|
313
|
-
for (let L of this.variables) {
|
|
314
|
-
// Reset the stack
|
|
315
|
-
reducedEquations = [];
|
|
316
|
-
|
|
317
|
-
// remove the setLetter from all equations using linear combinations
|
|
318
|
-
if (L === letter) continue;
|
|
319
|
-
|
|
320
|
-
if (withResolution) {
|
|
321
|
-
this._resolutionSteps[letter].push({
|
|
322
|
-
equations: LE.map(x => x.clone()),
|
|
323
|
-
operations: [...new Array(LE.length)].map(x => [...new Array(LE.length - 1)].map(x => ""))
|
|
324
|
-
})
|
|
325
|
-
lastIndex = this._resolutionSteps[letter].length - 1
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// Linear reduction.
|
|
329
|
-
for (let i = 0; i < LE.length - 1; i++) {
|
|
330
|
-
const result = this._linearReduction(LE[i], LE[i + 1], L)
|
|
331
|
-
reducedEquations.push(result.merged)
|
|
332
|
-
|
|
333
|
-
if (withResolution) {
|
|
334
|
-
this._resolutionSteps[letter][lastIndex].operations[i][i] = result.factors[0].tex
|
|
335
|
-
this._resolutionSteps[letter][lastIndex].operations[i + 1][i] = result.factors[1].tex
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
LE = [...reducedEquations]
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Solve the equations
|
|
343
|
-
// let E = this._resolutionSteps[this._resolutionSteps.length - 1].equations[0];
|
|
344
|
-
let E = LE[0];
|
|
345
|
-
E.solve()
|
|
346
|
-
const solution = E.solutions[0]
|
|
347
|
-
|
|
348
|
-
if (withResolution) {
|
|
349
|
-
this._resolutionSteps[letter].push({
|
|
350
|
-
equations: [LE[0]],
|
|
351
|
-
operations: [[LE[0].left.monoms[0].coefficient.tex]]
|
|
352
|
-
})
|
|
353
|
-
|
|
354
|
-
let P: Polynom
|
|
355
|
-
if (solution.exact instanceof Fraction || typeof solution.exact === "string") {
|
|
356
|
-
P = new Polynom(solution.exact)
|
|
357
|
-
} else {
|
|
358
|
-
P = new Polynom(solution.value)
|
|
359
|
-
}
|
|
360
|
-
this._resolutionSteps[letter].push({
|
|
361
|
-
equations: [new Equation(new Polynom(letter), P)],
|
|
362
|
-
operations: []
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
}
|
|
366
|
-
return E.solutions[0]
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Polynom module contains everything necessary to handle polynoms.
|
|
3
|
-
* @module Logicalset
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {Shutingyard, ShutingyardMode} from '../shutingyard.ts';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Polynom class can handle polynoms, reorder, resolve, ...
|
|
10
|
-
*/
|
|
11
|
-
export class Logicalset {
|
|
12
|
-
private _rawString: string;
|
|
13
|
-
private _rpn: { token: string, tokenType: string }[]
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* @param {string} value (optional) Default polynom to parse on class creation
|
|
18
|
-
*/
|
|
19
|
-
constructor(value: string) {
|
|
20
|
-
this._rawString = value
|
|
21
|
-
this.parse(value)
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
get isLogicalset() {
|
|
26
|
-
return true;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
get rpn(): { token: string, tokenType: string }[] {
|
|
30
|
-
return this._rpn
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get tex(): string {
|
|
34
|
-
let varStack: { token: string, tokenType: string } [] = []
|
|
35
|
-
|
|
36
|
-
for (let token of this._rpn) {
|
|
37
|
-
if (token.tokenType === 'variable') {
|
|
38
|
-
varStack.push(token);
|
|
39
|
-
} else {
|
|
40
|
-
switch (token.token) {
|
|
41
|
-
case '&':
|
|
42
|
-
if (varStack.length >= 2) {
|
|
43
|
-
let second = varStack.pop(),
|
|
44
|
-
first = varStack.pop()
|
|
45
|
-
|
|
46
|
-
if (first.tokenType === 'mix') {
|
|
47
|
-
first.token = `( ${first.token} )`
|
|
48
|
-
}
|
|
49
|
-
if (second.tokenType === 'mix') {
|
|
50
|
-
second.token = `( ${second.token} )`
|
|
51
|
-
}
|
|
52
|
-
varStack.push({token: `${first.token} \\cap ${second.token}`, tokenType: 'mix'})
|
|
53
|
-
}
|
|
54
|
-
break
|
|
55
|
-
case '|':
|
|
56
|
-
if (varStack.length >= 2) {
|
|
57
|
-
let second = varStack.pop(),
|
|
58
|
-
first = varStack.pop()
|
|
59
|
-
|
|
60
|
-
if (first.tokenType === 'mix') {
|
|
61
|
-
first.token = `( ${first.token} )`
|
|
62
|
-
}
|
|
63
|
-
if (second.tokenType === 'mix') {
|
|
64
|
-
second.token = `( ${second.token} )`
|
|
65
|
-
}
|
|
66
|
-
varStack.push({token: `${first.token} \\cup ${second.token}`, tokenType: 'mix'})
|
|
67
|
-
}
|
|
68
|
-
break
|
|
69
|
-
case '-':
|
|
70
|
-
if (varStack.length >= 2) {
|
|
71
|
-
let second = varStack.pop(),
|
|
72
|
-
first = varStack.pop()
|
|
73
|
-
|
|
74
|
-
if (first.tokenType === 'mix') {
|
|
75
|
-
first.token = `( ${first.token} )`
|
|
76
|
-
}
|
|
77
|
-
if (second.tokenType === 'mix') {
|
|
78
|
-
second.token = `( ${second.token} )`
|
|
79
|
-
}
|
|
80
|
-
varStack.push({token: `${first.token} \\setminus ${second.token}`, tokenType: 'mix'})
|
|
81
|
-
}
|
|
82
|
-
break
|
|
83
|
-
case '!':
|
|
84
|
-
if (varStack.length >= 1) {
|
|
85
|
-
let first = varStack.pop()
|
|
86
|
-
varStack.push({token: `\\overline{ ${first.token} }`, tokenType: 'variable'})
|
|
87
|
-
}
|
|
88
|
-
break
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return varStack[0].token
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
evaluate(tokenSets: { [key: string]: unknown[] }, reference?: unknown[]): unknown[] {
|
|
97
|
-
let varStack: (Set<unknown>)[] = []
|
|
98
|
-
|
|
99
|
-
let referenceSet: Set<unknown>
|
|
100
|
-
if (reference === undefined) {
|
|
101
|
-
referenceSet = new Set()
|
|
102
|
-
for (let key in tokenSets) {
|
|
103
|
-
referenceSet = new Set([...referenceSet, ...tokenSets[key]])
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
referenceSet = new Set(reference)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
for (let token of this._rpn) {
|
|
110
|
-
if (token.tokenType === 'variable') {
|
|
111
|
-
// The variable has no token - assume it's empty.
|
|
112
|
-
if (tokenSets[token.token] === undefined) {
|
|
113
|
-
varStack.push(new Set())
|
|
114
|
-
} else {
|
|
115
|
-
varStack.push(new Set(tokenSets[token.token]));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
} else {
|
|
119
|
-
switch (token.token) {
|
|
120
|
-
case '&':
|
|
121
|
-
if (varStack.length >= 2) {
|
|
122
|
-
let second = varStack.pop(),
|
|
123
|
-
first = varStack.pop()
|
|
124
|
-
|
|
125
|
-
varStack.push(new Set([...first].filter(x => second.has(x))))
|
|
126
|
-
}
|
|
127
|
-
break
|
|
128
|
-
case '|':
|
|
129
|
-
if (varStack.length >= 2) {
|
|
130
|
-
let second = varStack.pop(),
|
|
131
|
-
first = varStack.pop()
|
|
132
|
-
varStack.push(new Set([...first, ...second]))
|
|
133
|
-
}
|
|
134
|
-
break
|
|
135
|
-
case '-':
|
|
136
|
-
if (varStack.length >= 2) {
|
|
137
|
-
let second = varStack.pop(),
|
|
138
|
-
first = varStack.pop()
|
|
139
|
-
varStack.push(new Set([...first].filter(x => !second.has(x))))
|
|
140
|
-
}
|
|
141
|
-
break
|
|
142
|
-
case '!':
|
|
143
|
-
if (varStack.length >= 1) {
|
|
144
|
-
let first = varStack.pop()
|
|
145
|
-
|
|
146
|
-
varStack.push(new Set([...referenceSet].filter(x => !first.has(x))))
|
|
147
|
-
}
|
|
148
|
-
break
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return [...varStack[0]].sort();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
vennAB(): any[] {
|
|
157
|
-
return this.evaluate({
|
|
158
|
-
A: ['A', 'AB'],
|
|
159
|
-
B: ['B', 'AB']
|
|
160
|
-
},
|
|
161
|
-
['A', 'B', 'AB', 'E']
|
|
162
|
-
)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
vennABC(): any[] {
|
|
166
|
-
return this.evaluate({
|
|
167
|
-
A: ['A', 'AB', 'AC', 'ABC'],
|
|
168
|
-
B: ['B', 'AB', 'BC', 'ABC'],
|
|
169
|
-
C: ['C', 'AC', 'BC', 'ABC']
|
|
170
|
-
},
|
|
171
|
-
['A', 'B', 'C', 'AB', 'AC', 'BC', 'E']
|
|
172
|
-
)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private parse = (value: string): Logicalset => {
|
|
176
|
-
// TODO: Must format the value string to convert some items...
|
|
177
|
-
|
|
178
|
-
// Parse the updated value to the shutingyard algorithm
|
|
179
|
-
this._rpn = new Shutingyard(ShutingyardMode.SET).parse(value).rpn;
|
|
180
|
-
|
|
181
|
-
return this;
|
|
182
|
-
}
|
|
183
|
-
}
|