Skip to content

Commit 89c8ce3

Browse files
committed
fix: kmap issue
1 parent a1293d4 commit 89c8ce3

File tree

3 files changed

+112
-127
lines changed

3 files changed

+112
-127
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/calculator/calculator.service.ts

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ export class CalculatorService {
9696
this.toString = function() {
9797
return "T";
9898
}
99+
this.toStringInner = function() {
100+
return "T";
101+
}
99102
this.equals = function(object) {
100103
return object == this;
101104
}
@@ -111,6 +114,9 @@ export class CalculatorService {
111114
this.toString = function() {
112115
return "F";
113116
}
117+
this.toStringInner = function() {
118+
return "F";
119+
}
114120
this.equals = function(object) {
115121
return object == this;
116122
}
@@ -128,6 +134,9 @@ export class CalculatorService {
128134
Variable.prototype.toString = function() {
129135
return this.variableName;
130136
}
137+
Variable.prototype.toStringInner = function() {
138+
return this.variableName;
139+
}
131140
Variable.prototype.equals = function(object) {
132141
if (!(object instanceof Variable)) {
133142
return false;
@@ -142,11 +151,43 @@ export class CalculatorService {
142151
return exp instanceof Variable;
143152
}
144153
154+
// Helper to check if an expression needs parentheses based on context
155+
function needsParens(child, parent) {
156+
// Variables, True, False, and NOT expressions don't need parens
157+
if (child instanceof Variable || child === True || child === False) {
158+
return false;
159+
}
160+
if (child instanceof NotExpression) {
161+
return false;
162+
}
163+
// If no parent, we're at the top level - no parens needed
164+
if (!parent) {
165+
return false;
166+
}
167+
// AND inside OR needs parens (lower precedence)
168+
if (child instanceof AndExpression && parent instanceof OrExpression) {
169+
return true;
170+
}
171+
// OR inside AND needs parens (for clarity)
172+
if (child instanceof OrExpression && parent instanceof AndExpression) {
173+
return true;
174+
}
175+
return false;
176+
}
177+
145178
function NotExpression(subs) {
146179
this.subs = subs;
147180
}
148-
NotExpression.prototype.toString = function() {
149-
return SYMBOL.NOT + this.subs[0];
181+
NotExpression.prototype.toString = function(parent) {
182+
var inner = this.subs[0];
183+
// NOT of compound expressions needs parens around the inner part
184+
if (inner instanceof AndExpression || inner instanceof OrExpression) {
185+
return SYMBOL.NOT + "(" + inner.toStringInner() + ")";
186+
}
187+
return SYMBOL.NOT + inner.toString(this);
188+
};
189+
NotExpression.prototype.toStringInner = function() {
190+
return this.toString(null);
150191
};
151192
NotExpression.prototype.equals = function(object) {
152193
if (!(object instanceof NotExpression)) {
@@ -162,8 +203,25 @@ export class CalculatorService {
162203
this.subs = subs;
163204
}
164205
165-
OrExpression.prototype.toString = function() {
166-
return Utils.parenthesize(Utils.arrayToString(this.subs, " " + SYMBOL.OR + " "));
206+
OrExpression.prototype.toString = function(parent) {
207+
var inner = this.toStringInner();
208+
// Only add parens if inside an AND expression
209+
if (parent instanceof AndExpression) {
210+
return "(" + inner + ")";
211+
}
212+
return inner;
213+
}
214+
OrExpression.prototype.toStringInner = function() {
215+
var parts = [];
216+
for (var i = 0; i < this.subs.length; i++) {
217+
var sub = this.subs[i];
218+
if (sub.toString) {
219+
parts.push(sub.toString(this));
220+
} else {
221+
parts.push(sub.toString());
222+
}
223+
}
224+
return parts.join(" " + SYMBOL.OR + " ");
167225
}
168226
OrExpression.prototype.contains = function(object) {
169227
if (!(object instanceof OrExpression)) {
@@ -231,8 +289,25 @@ export class CalculatorService {
231289
this.subs = subs;
232290
}
233291
234-
AndExpression.prototype.toString = function() {
235-
return Utils.parenthesize(Utils.arrayToString(this.subs, " " + SYMBOL.AND + " "));
292+
AndExpression.prototype.toString = function(parent) {
293+
var inner = this.toStringInner();
294+
// Only add parens if inside an OR expression (AND has higher precedence)
295+
if (parent instanceof OrExpression) {
296+
return "(" + inner + ")";
297+
}
298+
return inner;
299+
}
300+
AndExpression.prototype.toStringInner = function() {
301+
var parts = [];
302+
for (var i = 0; i < this.subs.length; i++) {
303+
var sub = this.subs[i];
304+
if (sub.toString) {
305+
parts.push(sub.toString(this));
306+
} else {
307+
parts.push(sub.toString());
308+
}
309+
}
310+
return parts.join(" " + SYMBOL.AND + " ");
236311
}
237312
AndExpression.prototype.contains = function(object) {
238313
if (!(object instanceof AndExpression)) {
@@ -1173,7 +1248,10 @@ export class CalculatorService {
11731248
universalBound: "Universal Bound",
11741249
deMorgans: "De Morgan's",
11751250
absorption: "Absorption",
1176-
negationsOfTF: "Negations of T and F"
1251+
negationsOfTF: "Negations of T and F",
1252+
XOR: "XOR Definition",
1253+
IMP: "Implication Definition",
1254+
BIMP: "Biconditional Definition"
11771255
};
11781256
const shortDict = {
11791257
commutative: "COM",
@@ -1186,7 +1264,10 @@ export class CalculatorService {
11861264
universalBound: "UB",
11871265
deMorgans: "DM",
11881266
absorption: "ABS",
1189-
negationsOfTF: "NTF"
1267+
negationsOfTF: "NTF",
1268+
XOR: "XOR",
1269+
IMP: "IMP",
1270+
BIMP: "BIMP"
11901271
};
11911272
11921273
function getLawName(lawFunction, useShort = Settings.getValue("short")) {
@@ -1347,22 +1428,40 @@ export class CalculatorService {
13471428
VariableManager.clear();
13481429
var parsed = Parser.parse(expr);
13491430
var steps = Equivalency.simplify(parsed);
1431+
1432+
// Check if original expression contained XOR, IF, or IFF that got converted
1433+
var hasXOR = expr.includes(SYMBOL.XOR) || /\bxor\b/i.test(expr);
1434+
var hasIF = expr.includes(SYMBOL.IF) || /->/g.test(expr) || /\bthen\b/i.test(expr);
1435+
var hasIFF = expr.includes(SYMBOL.IFF) || /<->/g.test(expr);
1436+
1437+
// Add conversion steps at the beginning if needed
1438+
var conversionSteps = [];
1439+
if (hasXOR || hasIF || hasIFF) {
1440+
// The first step after parsing shows the converted form
1441+
var conversionLaw = hasXOR ? "XOR" : (hasIF ? "IMP" : "BIMP");
1442+
conversionSteps.push({
1443+
expression: parsed.toString(),
1444+
law: "by " + conversionLaw,
1445+
lawName: conversionLaw
1446+
});
1447+
}
1448+
13501449
// Return previous shape but also allow frontend to request AST tokenization via annotate/tokenize helpers
13511450
return {
13521451
originalExpression: expr,
13531452
simplifiedExpression: steps[steps.length - 1].result,
1354-
steps: steps
1453+
steps: conversionSteps.concat(steps
13551454
.filter(function(s) { return s.lawString !== 'result'; })
13561455
.map(function(step) {
13571456
return {
13581457
expression: step.result,
13591458
law: step.lawString,
13601459
lawName: step.lawString.replace('by ', '')
13611460
};
1362-
}),
1363-
stepLines: steps
1461+
})),
1462+
stepLines: (hasXOR || hasIF || hasIFF ? [parsed.toString() + "by " + (hasXOR ? "XOR" : (hasIF ? "IMP" : "BIMP"))] : []).concat(steps
13641463
.filter(function(s) { return s.lawString !== 'result'; })
1365-
.map(function(step) { return step.result + step.lawString; })
1464+
.map(function(step) { return step.result + step.lawString; }))
13661465
};
13671466
};
13681467

yarn.lock

Lines changed: 0 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,61 +1013,6 @@
10131013
resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz"
10141014
integrity sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==
10151015

1016-
"@napi-rs/nice-android-arm-eabi@1.0.1":
1017-
version "1.0.1"
1018-
resolved "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz"
1019-
integrity sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==
1020-
1021-
"@napi-rs/nice-android-arm64@1.0.1":
1022-
version "1.0.1"
1023-
resolved "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz"
1024-
integrity sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==
1025-
1026-
"@napi-rs/nice-darwin-arm64@1.0.1":
1027-
version "1.0.1"
1028-
resolved "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz"
1029-
integrity sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==
1030-
1031-
"@napi-rs/nice-darwin-x64@1.0.1":
1032-
version "1.0.1"
1033-
resolved "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz"
1034-
integrity sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==
1035-
1036-
"@napi-rs/nice-freebsd-x64@1.0.1":
1037-
version "1.0.1"
1038-
resolved "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz"
1039-
integrity sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==
1040-
1041-
"@napi-rs/nice-linux-arm-gnueabihf@1.0.1":
1042-
version "1.0.1"
1043-
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz"
1044-
integrity sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==
1045-
1046-
"@napi-rs/nice-linux-arm64-gnu@1.0.1":
1047-
version "1.0.1"
1048-
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz"
1049-
integrity sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==
1050-
1051-
"@napi-rs/nice-linux-arm64-musl@1.0.1":
1052-
version "1.0.1"
1053-
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz"
1054-
integrity sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==
1055-
1056-
"@napi-rs/nice-linux-ppc64-gnu@1.0.1":
1057-
version "1.0.1"
1058-
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz"
1059-
integrity sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==
1060-
1061-
"@napi-rs/nice-linux-riscv64-gnu@1.0.1":
1062-
version "1.0.1"
1063-
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz"
1064-
integrity sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==
1065-
1066-
"@napi-rs/nice-linux-s390x-gnu@1.0.1":
1067-
version "1.0.1"
1068-
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz"
1069-
integrity sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==
1070-
10711016
"@napi-rs/nice-linux-x64-gnu@1.0.1":
10721017
version "1.0.1"
10731018
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz"
@@ -1078,21 +1023,6 @@
10781023
resolved "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz"
10791024
integrity sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==
10801025

1081-
"@napi-rs/nice-win32-arm64-msvc@1.0.1":
1082-
version "1.0.1"
1083-
resolved "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz"
1084-
integrity sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==
1085-
1086-
"@napi-rs/nice-win32-ia32-msvc@1.0.1":
1087-
version "1.0.1"
1088-
resolved "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz"
1089-
integrity sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==
1090-
1091-
"@napi-rs/nice-win32-x64-msvc@1.0.1":
1092-
version "1.0.1"
1093-
resolved "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz"
1094-
integrity sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==
1095-
10961026
"@napi-rs/nice@^1.0.1":
10971027
version "1.0.1"
10981028
resolved "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz"
@@ -1449,31 +1379,6 @@
14491379
slash "3.0.0"
14501380
source-map "^0.7.3"
14511381

1452-
"@swc/core-darwin-arm64@1.11.29":
1453-
version "1.11.29"
1454-
resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.29.tgz"
1455-
integrity sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==
1456-
1457-
"@swc/core-darwin-x64@1.11.29":
1458-
version "1.11.29"
1459-
resolved "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.29.tgz"
1460-
integrity sha512-S3eTo/KYFk+76cWJRgX30hylN5XkSmjYtCBnM4jPLYn7L6zWYEPajsFLmruQEiTEDUg0gBEWLMNyUeghtswouw==
1461-
1462-
"@swc/core-linux-arm-gnueabihf@1.11.29":
1463-
version "1.11.29"
1464-
resolved "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.29.tgz"
1465-
integrity sha512-o9gdshbzkUMG6azldHdmKklcfrcMx+a23d/2qHQHPDLUPAN+Trd+sDQUYArK5Fcm7TlpG4sczz95ghN0DMkM7g==
1466-
1467-
"@swc/core-linux-arm64-gnu@1.11.29":
1468-
version "1.11.29"
1469-
resolved "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.29.tgz"
1470-
integrity sha512-sLoaciOgUKQF1KX9T6hPGzvhOQaJn+3DHy4LOHeXhQqvBgr+7QcZ+hl4uixPKTzxk6hy6Hb0QOvQEdBAAR1gXw==
1471-
1472-
"@swc/core-linux-arm64-musl@1.11.29":
1473-
version "1.11.29"
1474-
resolved "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.29.tgz"
1475-
integrity sha512-PwjB10BC0N+Ce7RU/L23eYch6lXFHz7r3NFavIcwDNa/AAqywfxyxh13OeRy+P0cg7NDpWEETWspXeI4Ek8otw==
1476-
14771382
"@swc/core-linux-x64-gnu@1.11.29":
14781383
version "1.11.29"
14791384
resolved "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.29.tgz"
@@ -1484,21 +1389,6 @@
14841389
resolved "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.29.tgz"
14851390
integrity sha512-YER0XU1xqFdK0hKkfSVX1YIyCvMDI7K07GIpefPvcfyNGs38AXKhb2byySDjbVxkdl4dycaxxhRyhQ2gKSlsFQ==
14861391

1487-
"@swc/core-win32-arm64-msvc@1.11.29":
1488-
version "1.11.29"
1489-
resolved "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.29.tgz"
1490-
integrity sha512-po+WHw+k9g6FAg5IJ+sMwtA/fIUL3zPQ4m/uJgONBATCVnDDkyW6dBA49uHNVtSEvjvhuD8DVWdFP847YTcITw==
1491-
1492-
"@swc/core-win32-ia32-msvc@1.11.29":
1493-
version "1.11.29"
1494-
resolved "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.29.tgz"
1495-
integrity sha512-h+NjOrbqdRBYr5ItmStmQt6x3tnhqgwbj9YxdGPepbTDamFv7vFnhZR0YfB3jz3UKJ8H3uGJ65Zw1VsC+xpFkg==
1496-
1497-
"@swc/core-win32-x64-msvc@1.11.29":
1498-
version "1.11.29"
1499-
resolved "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.29.tgz"
1500-
integrity sha512-Q8cs2BDV9wqDvqobkXOYdC+pLUSEpX/KvI0Dgfun1F+LzuLotRFuDhrvkU9ETJA6OnD2+Fn/ieHgloiKA/Mn/g==
1501-
15021392
"@swc/core@^1.10.7", "@swc/core@^1.2.66", "@swc/core@^1.3.62", "@swc/core@>=1.2.50":
15031393
version "1.11.29"
15041394
resolved "https://registry.npmjs.org/@swc/core/-/core-1.11.29.tgz"
@@ -3757,11 +3647,6 @@ fs.realpath@^1.0.0:
37573647
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
37583648
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
37593649

3760-
fsevents@^2.3.2:
3761-
version "2.3.3"
3762-
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
3763-
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
3764-
37653650
function-bind@^1.1.2:
37663651
version "1.1.2"
37673652
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"

0 commit comments

Comments
 (0)