@stevenvo780/st-lang 3.1.0 → 3.1.1
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/api.d.ts.map +1 -1
- package/dist/api.js +44 -9
- package/dist/api.js.map +1 -1
- package/dist/parser/parser.d.ts +4 -0
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +213 -92
- package/dist/parser/parser.js.map +1 -1
- package/dist/profiles/classical/first-order.d.ts.map +1 -1
- package/dist/profiles/classical/first-order.js +12 -5
- package/dist/profiles/classical/first-order.js.map +1 -1
- package/dist/profiles/classical/propositional.d.ts.map +1 -1
- package/dist/profiles/classical/propositional.js +281 -35
- package/dist/profiles/classical/propositional.js.map +1 -1
- package/dist/profiles/shared/tableau-engine.d.ts +4 -3
- package/dist/profiles/shared/tableau-engine.d.ts.map +1 -1
- package/dist/profiles/shared/tableau-engine.js +101 -15
- package/dist/profiles/shared/tableau-engine.js.map +1 -1
- package/dist/protocol/handler.d.ts +4 -0
- package/dist/protocol/handler.d.ts.map +1 -1
- package/dist/protocol/handler.js +133 -41
- package/dist/protocol/handler.js.map +1 -1
- package/dist/repl/repl.d.ts +2 -0
- package/dist/repl/repl.d.ts.map +1 -1
- package/dist/repl/repl.js +39 -18
- package/dist/repl/repl.js.map +1 -1
- package/dist/runtime/compat.d.ts +29 -0
- package/dist/runtime/compat.d.ts.map +1 -0
- package/dist/runtime/compat.js +821 -0
- package/dist/runtime/compat.js.map +1 -0
- package/dist/runtime/interpreter.d.ts +3 -0
- package/dist/runtime/interpreter.d.ts.map +1 -1
- package/dist/runtime/interpreter.js +128 -28
- package/dist/runtime/interpreter.js.map +1 -1
- package/dist/tests/compat.test.d.ts +2 -0
- package/dist/tests/compat.test.d.ts.map +1 -0
- package/dist/tests/compat.test.js +247 -0
- package/dist/tests/compat.test.js.map +1 -0
- package/dist/tests/core.test.js +37 -0
- package/dist/tests/core.test.js.map +1 -1
- package/dist/tests/parser.test.js +38 -0
- package/dist/tests/parser.test.js.map +1 -1
- package/dist/tests/profiles.test.js +8 -0
- package/dist/tests/profiles.test.js.map +1 -1
- package/dist/tests/protocol-text-layer.test.d.ts +2 -0
- package/dist/tests/protocol-text-layer.test.d.ts.map +1 -0
- package/dist/tests/protocol-text-layer.test.js +54 -0
- package/dist/tests/protocol-text-layer.test.js.map +1 -0
- package/dist/text-layer/compiler.d.ts.map +1 -1
- package/dist/text-layer/compiler.js +35 -8
- package/dist/text-layer/compiler.js.map +1 -1
- package/dist/types/index.d.ts +27 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -704,6 +704,77 @@ function addDerivedFormula(state, formula, justification, premises) {
|
|
|
704
704
|
state.known.set(hash, formula);
|
|
705
705
|
return true;
|
|
706
706
|
}
|
|
707
|
+
function buildPremiseRefs(theory, premiseNames) {
|
|
708
|
+
return premiseNames.map((name) => ({
|
|
709
|
+
name,
|
|
710
|
+
location: (theory.axioms.get(name) || theory.theorems.get(name))?.source,
|
|
711
|
+
}));
|
|
712
|
+
}
|
|
713
|
+
function buildProof(goal, steps, premiseNames, theory, method = 'natural_deduction', subproofs) {
|
|
714
|
+
return {
|
|
715
|
+
goal,
|
|
716
|
+
steps,
|
|
717
|
+
status: 'complete',
|
|
718
|
+
derivedFrom: premiseNames,
|
|
719
|
+
premiseRefs: buildPremiseRefs(theory, premiseNames),
|
|
720
|
+
method,
|
|
721
|
+
subproofs,
|
|
722
|
+
metadata: {
|
|
723
|
+
createdAt: new Date().toISOString(),
|
|
724
|
+
profile: theory.profile,
|
|
725
|
+
},
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
function isNegationOf(a, b) {
|
|
729
|
+
return a.kind === 'not' && !!a.args?.[0] && formulasEqual(a.args[0], b);
|
|
730
|
+
}
|
|
731
|
+
function isExcludedMiddleFormula(formula) {
|
|
732
|
+
if (formula.kind !== 'or' || !formula.args?.[0] || !formula.args?.[1])
|
|
733
|
+
return false;
|
|
734
|
+
return (isNegationOf(formula.args[0], formula.args[1]) || isNegationOf(formula.args[1], formula.args[0]));
|
|
735
|
+
}
|
|
736
|
+
function getCommutativeVariant(formula) {
|
|
737
|
+
if ((formula.kind === 'and' || formula.kind === 'or') && formula.args?.[0] && formula.args?.[1]) {
|
|
738
|
+
return { kind: formula.kind, args: [formula.args[1], formula.args[0]] };
|
|
739
|
+
}
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
function getAssociativeVariants(formula) {
|
|
743
|
+
const variants = [];
|
|
744
|
+
if ((formula.kind === 'and' || formula.kind === 'or') && formula.args?.[0] && formula.args?.[1]) {
|
|
745
|
+
const [left, right] = formula.args;
|
|
746
|
+
if (left.kind === formula.kind && left.args?.[0] && left.args?.[1]) {
|
|
747
|
+
variants.push({
|
|
748
|
+
kind: formula.kind,
|
|
749
|
+
args: [left.args[0], { kind: formula.kind, args: [left.args[1], right] }],
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
if (right.kind === formula.kind && right.args?.[0] && right.args?.[1]) {
|
|
753
|
+
variants.push({
|
|
754
|
+
kind: formula.kind,
|
|
755
|
+
args: [{ kind: formula.kind, args: [left, right.args[0]] }, right.args[1]],
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
return variants;
|
|
760
|
+
}
|
|
761
|
+
function getAbsorptionResult(formula) {
|
|
762
|
+
if (formula.kind === 'and' && formula.args?.[0] && formula.args?.[1]) {
|
|
763
|
+
const [left, right] = formula.args;
|
|
764
|
+
if (right.kind === 'or' && right.args?.some((arg) => formulasEqual(arg, left)))
|
|
765
|
+
return left;
|
|
766
|
+
if (left.kind === 'or' && left.args?.some((arg) => formulasEqual(arg, right)))
|
|
767
|
+
return right;
|
|
768
|
+
}
|
|
769
|
+
if (formula.kind === 'or' && formula.args?.[0] && formula.args?.[1]) {
|
|
770
|
+
const [left, right] = formula.args;
|
|
771
|
+
if (right.kind === 'and' && right.args?.some((arg) => formulasEqual(arg, left)))
|
|
772
|
+
return left;
|
|
773
|
+
if (left.kind === 'and' && left.args?.some((arg) => formulasEqual(arg, right)))
|
|
774
|
+
return right;
|
|
775
|
+
}
|
|
776
|
+
return null;
|
|
777
|
+
}
|
|
707
778
|
function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
708
779
|
const state = {
|
|
709
780
|
known: new Map(),
|
|
@@ -712,7 +783,25 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
712
783
|
};
|
|
713
784
|
// Cargar premisas
|
|
714
785
|
for (const name of premiseNames) {
|
|
715
|
-
|
|
786
|
+
let f = theory.axioms.get(name) || theory.theorems.get(name);
|
|
787
|
+
// Fallback: if name not found directly, search for an axiom/theorem whose formula
|
|
788
|
+
// matches the bare atom name (e.g., premise "Q" matches a theorem whose formula is atom Q)
|
|
789
|
+
if (!f) {
|
|
790
|
+
for (const [, formula] of theory.axioms) {
|
|
791
|
+
if (formula.kind === 'atom' && formula.name === name) {
|
|
792
|
+
f = formula;
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
if (!f) {
|
|
797
|
+
for (const [, formula] of theory.theorems) {
|
|
798
|
+
if (formula.kind === 'atom' && formula.name === name) {
|
|
799
|
+
f = formula;
|
|
800
|
+
break;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
716
805
|
if (f) {
|
|
717
806
|
state.stepCount++;
|
|
718
807
|
state.steps.push({
|
|
@@ -724,6 +813,9 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
724
813
|
state.known.set(formulaHash(f), f);
|
|
725
814
|
}
|
|
726
815
|
}
|
|
816
|
+
if (isExcludedMiddleFormula(goal)) {
|
|
817
|
+
addDerivedFormula(state, goal, 'Tercero excluido', []);
|
|
818
|
+
}
|
|
727
819
|
// Intentar derivar con BFS aplicando reglas (optimizado)
|
|
728
820
|
const maxIterations = 1000;
|
|
729
821
|
let changed = true;
|
|
@@ -928,7 +1020,9 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
928
1020
|
const disjHashRev = formulaHash({ kind: 'or', args: [r, p] });
|
|
929
1021
|
if (state.known.has(disjHash) || state.known.has(disjHashRev)) {
|
|
930
1022
|
const qs = { kind: 'or', args: [q, s] };
|
|
931
|
-
const disjFormula = state.known.get(disjHash)
|
|
1023
|
+
const disjFormula = state.known.get(disjHash) ?? state.known.get(disjHashRev);
|
|
1024
|
+
if (!disjFormula)
|
|
1025
|
+
continue;
|
|
932
1026
|
changed =
|
|
933
1027
|
addDerivedFormula(state, qs, 'Dilema Constructivo', [
|
|
934
1028
|
findStep(state.steps, f1),
|
|
@@ -975,6 +1069,32 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
975
1069
|
]) || changed;
|
|
976
1070
|
}
|
|
977
1071
|
}
|
|
1072
|
+
const commutative = getCommutativeVariant(f1);
|
|
1073
|
+
if (commutative && isRelevantToGoal(commutative, goal)) {
|
|
1074
|
+
changed =
|
|
1075
|
+
addDerivedFormula(state, commutative, 'Conmutatividad', [findStep(state.steps, f1)]) ||
|
|
1076
|
+
changed;
|
|
1077
|
+
}
|
|
1078
|
+
for (const associative of getAssociativeVariants(f1)) {
|
|
1079
|
+
if (isRelevantToGoal(associative, goal)) {
|
|
1080
|
+
changed =
|
|
1081
|
+
addDerivedFormula(state, associative, 'Asociatividad', [findStep(state.steps, f1)]) ||
|
|
1082
|
+
changed;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
if ((f1.kind === 'and' || f1.kind === 'or') &&
|
|
1086
|
+
f1.args?.[0] &&
|
|
1087
|
+
f1.args?.[1] &&
|
|
1088
|
+
formulasEqual(f1.args[0], f1.args[1])) {
|
|
1089
|
+
changed =
|
|
1090
|
+
addDerivedFormula(state, f1.args[0], 'Idempotencia', [findStep(state.steps, f1)]) ||
|
|
1091
|
+
changed;
|
|
1092
|
+
}
|
|
1093
|
+
const absorbed = getAbsorptionResult(f1);
|
|
1094
|
+
if (absorbed) {
|
|
1095
|
+
changed =
|
|
1096
|
+
addDerivedFormula(state, absorbed, 'Absorcion', [findStep(state.steps, f1)]) || changed;
|
|
1097
|
+
}
|
|
978
1098
|
// Disjunction Introduction: de A, derivar A | B
|
|
979
1099
|
// Relaxed: also allow intermediate disjunctions that are relevant to goal
|
|
980
1100
|
if (goal.kind === 'or' && goal.args?.[0] && goal.args?.[1]) {
|
|
@@ -1027,6 +1147,35 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1027
1147
|
findStep(state.steps, f1),
|
|
1028
1148
|
]) || changed;
|
|
1029
1149
|
}
|
|
1150
|
+
// Implicación material (→ a ∨): de A->B, derivar !A|B
|
|
1151
|
+
if (f1.kind === 'implies' && f1.args?.[0] && f1.args?.[1]) {
|
|
1152
|
+
const matImpl = {
|
|
1153
|
+
kind: 'or',
|
|
1154
|
+
args: [{ kind: 'not', args: [f1.args[0]] }, f1.args[1]],
|
|
1155
|
+
};
|
|
1156
|
+
if (isRelevantToGoal(matImpl, goal)) {
|
|
1157
|
+
changed =
|
|
1158
|
+
addDerivedFormula(state, matImpl, 'Implicacion material (→ a ∨)', [
|
|
1159
|
+
findStep(state.steps, f1),
|
|
1160
|
+
]) || changed;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
// Implicación material inversa (∨ a →): de !A|B, derivar A->B
|
|
1164
|
+
if (f1.kind === 'or' &&
|
|
1165
|
+
f1.args?.[0]?.kind === 'not' &&
|
|
1166
|
+
f1.args[0].args?.[0] &&
|
|
1167
|
+
f1.args?.[1]) {
|
|
1168
|
+
const impl = {
|
|
1169
|
+
kind: 'implies',
|
|
1170
|
+
args: [f1.args[0].args[0], f1.args[1]],
|
|
1171
|
+
};
|
|
1172
|
+
if (isRelevantToGoal(impl, goal)) {
|
|
1173
|
+
changed =
|
|
1174
|
+
addDerivedFormula(state, impl, 'Implicacion material (∨ a →)', [
|
|
1175
|
+
findStep(state.steps, f1),
|
|
1176
|
+
]) || changed;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1030
1179
|
// Contraposition: de A->B, derivar !B->!A
|
|
1031
1180
|
// Restringir a fórmulas con profundidad de negación baja para evitar
|
|
1032
1181
|
// cadenas infinitas de contrapositivas (!!A→!!B → !!!B→!!!A → ...)
|
|
@@ -1251,21 +1400,13 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1251
1400
|
if (state.known.has(formulaHash(goal))) {
|
|
1252
1401
|
// Filtrar solo pasos relevantes para la derivación
|
|
1253
1402
|
const relevantSteps = traceBack(state.steps, goal);
|
|
1254
|
-
return
|
|
1255
|
-
goal,
|
|
1256
|
-
steps: relevantSteps,
|
|
1257
|
-
status: 'complete',
|
|
1258
|
-
derivedFrom: premiseNames,
|
|
1259
|
-
};
|
|
1403
|
+
return buildProof(goal, relevantSteps, premiseNames, theory);
|
|
1260
1404
|
}
|
|
1261
1405
|
// --- Sub-derivaciones recursivas (antes del fallback semántico) ---
|
|
1262
1406
|
const MAX_SUB_DEPTH = 2;
|
|
1263
1407
|
// Prueba Condicional real (→-Introducción / Deduction Theorem):
|
|
1264
1408
|
// Para derivar A→B, asumimos A como premisa temporal y derivamos B.
|
|
1265
|
-
if (depth < MAX_SUB_DEPTH &&
|
|
1266
|
-
goal.kind === 'implies' &&
|
|
1267
|
-
goal.args?.[0] &&
|
|
1268
|
-
goal.args?.[1]) {
|
|
1409
|
+
if (depth < MAX_SUB_DEPTH && goal.kind === 'implies' && goal.args?.[0] && goal.args?.[1]) {
|
|
1269
1410
|
const assumption = goal.args[0];
|
|
1270
1411
|
const subGoal = goal.args[1];
|
|
1271
1412
|
// Create a temporary theory with the assumption added
|
|
@@ -1304,7 +1445,6 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1304
1445
|
premises: [],
|
|
1305
1446
|
});
|
|
1306
1447
|
// Add sub-derivation steps (renumber, adjusting premise references)
|
|
1307
|
-
const subStepOffset = stepNum;
|
|
1308
1448
|
const subStepMap = new Map();
|
|
1309
1449
|
for (const s of subProof.steps) {
|
|
1310
1450
|
if (s.justification.startsWith('Premisa') && formulasEqual(s.formula, assumption)) {
|
|
@@ -1330,19 +1470,15 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1330
1470
|
}
|
|
1331
1471
|
// Add final conditional proof step
|
|
1332
1472
|
stepNum++;
|
|
1333
|
-
const subGoalStepNum = subStepMap.get(subProof.steps[subProof.steps.length - 1]?.stepNumber ?? 0) ??
|
|
1473
|
+
const subGoalStepNum = subStepMap.get(subProof.steps[subProof.steps.length - 1]?.stepNumber ?? 0) ?? stepNum - 1;
|
|
1334
1474
|
mainSteps.push({
|
|
1335
1475
|
stepNumber: stepNum,
|
|
1336
1476
|
formula: goal,
|
|
1337
1477
|
justification: 'Prueba Condicional (Teorema de Deduccion)',
|
|
1338
1478
|
premises: [assumptionStepNum, subGoalStepNum],
|
|
1479
|
+
subproofs: [subProof],
|
|
1339
1480
|
});
|
|
1340
|
-
return
|
|
1341
|
-
goal,
|
|
1342
|
-
steps: mainSteps,
|
|
1343
|
-
status: 'complete',
|
|
1344
|
-
derivedFrom: premiseNames,
|
|
1345
|
-
};
|
|
1481
|
+
return buildProof(goal, mainSteps, premiseNames, theory, 'natural_deduction', [subProof]);
|
|
1346
1482
|
}
|
|
1347
1483
|
}
|
|
1348
1484
|
}
|
|
@@ -1351,8 +1487,10 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1351
1487
|
if (depth < MAX_SUB_DEPTH) {
|
|
1352
1488
|
const disjunctions = Array.from(state.known.values()).filter((f) => f.kind === 'or' && f.args?.[0] && f.args?.[1]);
|
|
1353
1489
|
for (const disj of disjunctions) {
|
|
1354
|
-
const left = disj.args[0];
|
|
1355
|
-
const right = disj.args[1];
|
|
1490
|
+
const left = disj.args?.[0];
|
|
1491
|
+
const right = disj.args?.[1];
|
|
1492
|
+
if (!left || !right)
|
|
1493
|
+
continue;
|
|
1356
1494
|
// Try to derive goal assuming left
|
|
1357
1495
|
const tempTheoryL = {
|
|
1358
1496
|
profile: theory.profile,
|
|
@@ -1469,13 +1607,12 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1469
1607
|
formula: goal,
|
|
1470
1608
|
justification: 'Eliminacion de disyuncion (prueba por casos)',
|
|
1471
1609
|
premises: [disjStepNum, leftGoalStep, rightGoalStep],
|
|
1610
|
+
subproofs: [subProofL, subProofR],
|
|
1472
1611
|
});
|
|
1473
|
-
return
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
derivedFrom: premiseNames,
|
|
1478
|
-
};
|
|
1612
|
+
return buildProof(goal, mainSteps, premiseNames, theory, 'natural_deduction', [
|
|
1613
|
+
subProofL,
|
|
1614
|
+
subProofR,
|
|
1615
|
+
]);
|
|
1479
1616
|
}
|
|
1480
1617
|
}
|
|
1481
1618
|
// Fallback: verificar semánticamente
|
|
@@ -1547,12 +1684,7 @@ function tryDerive(goal, theory, premiseNames, depth = 0) {
|
|
|
1547
1684
|
state.known.set(goalHash, goal);
|
|
1548
1685
|
}
|
|
1549
1686
|
const relevantSteps = traceBack(state.steps, goal);
|
|
1550
|
-
return
|
|
1551
|
-
goal,
|
|
1552
|
-
steps: relevantSteps,
|
|
1553
|
-
status: 'complete',
|
|
1554
|
-
derivedFrom: premiseNames,
|
|
1555
|
-
};
|
|
1687
|
+
return buildProof(goal, relevantSteps, premiseNames, theory, 'semantic');
|
|
1556
1688
|
}
|
|
1557
1689
|
}
|
|
1558
1690
|
return null;
|
|
@@ -1583,7 +1715,17 @@ function traceBack(steps, goal) {
|
|
|
1583
1715
|
}
|
|
1584
1716
|
}
|
|
1585
1717
|
trace(goalStep.stepNumber);
|
|
1586
|
-
|
|
1718
|
+
const filtered = steps.filter((s) => needed.has(s.stepNumber));
|
|
1719
|
+
// Compact renumbering: eliminate gaps in step numbers
|
|
1720
|
+
const oldToNew = new Map();
|
|
1721
|
+
filtered.forEach((s, i) => {
|
|
1722
|
+
oldToNew.set(s.stepNumber, i + 1);
|
|
1723
|
+
});
|
|
1724
|
+
return filtered.map((s) => ({
|
|
1725
|
+
...s,
|
|
1726
|
+
stepNumber: oldToNew.get(s.stepNumber) ?? s.stepNumber,
|
|
1727
|
+
premises: s.premises.map((p) => oldToNew.get(p) ?? p),
|
|
1728
|
+
}));
|
|
1587
1729
|
}
|
|
1588
1730
|
// --- Perfil Classical Propositional ---
|
|
1589
1731
|
class ClassicalPropositional {
|
|
@@ -1779,6 +1921,96 @@ class ClassicalPropositional {
|
|
|
1779
1921
|
formula: goal,
|
|
1780
1922
|
};
|
|
1781
1923
|
}
|
|
1924
|
+
// Semantic fallback: verify via SAT/truth-table whether goal follows from axioms
|
|
1925
|
+
const allAxiomFormulas = premiseNames
|
|
1926
|
+
.map((n) => theory.axioms.get(n) || theory.theorems.get(n))
|
|
1927
|
+
.filter((f) => f !== undefined);
|
|
1928
|
+
let semanticResult;
|
|
1929
|
+
const atoms = new Set();
|
|
1930
|
+
for (const f of allAxiomFormulas)
|
|
1931
|
+
collectAtoms(f).forEach((a) => atoms.add(a));
|
|
1932
|
+
collectAtoms(goal).forEach((a) => atoms.add(a));
|
|
1933
|
+
const atomList = Array.from(atoms).sort();
|
|
1934
|
+
if (allAxiomFormulas.length > 0) {
|
|
1935
|
+
// With premises: check if premises entail goal
|
|
1936
|
+
const allPure = allAxiomFormulas.every(isPurePropositional) && isPurePropositional(goal);
|
|
1937
|
+
if (allPure && atomList.length <= 26) {
|
|
1938
|
+
const premiseBits = allAxiomFormulas.map((f) => evaluateBitset(f, atomList).result);
|
|
1939
|
+
const goalBits = evaluateBitset(goal, atomList).result;
|
|
1940
|
+
const allOnes = bvOnes(1 << atomList.length);
|
|
1941
|
+
let premisesConj = allOnes;
|
|
1942
|
+
for (const pb of premiseBits)
|
|
1943
|
+
premisesConj = bvAnd(premisesConj, pb);
|
|
1944
|
+
semanticResult = bvIsZero(bvAnd(premisesConj, bvNot(goalBits, allOnes)));
|
|
1945
|
+
}
|
|
1946
|
+
else if (allPure && atomList.length > 26) {
|
|
1947
|
+
let conjunction = allAxiomFormulas[0];
|
|
1948
|
+
for (let i = 1; i < allAxiomFormulas.length; i++) {
|
|
1949
|
+
conjunction = { kind: 'and', args: [conjunction, allAxiomFormulas[i]] };
|
|
1950
|
+
}
|
|
1951
|
+
const negGoal = { kind: 'not', args: [goal] };
|
|
1952
|
+
const check = { kind: 'and', args: [conjunction, negGoal] };
|
|
1953
|
+
semanticResult = !(0, dpll_1.dpll)(check).satisfiable;
|
|
1954
|
+
}
|
|
1955
|
+
else {
|
|
1956
|
+
const valuations = generateValuations(atomList);
|
|
1957
|
+
semanticResult = true;
|
|
1958
|
+
for (const v of valuations) {
|
|
1959
|
+
const premisesTrue = allAxiomFormulas.every((f) => evaluateClassical(f, v));
|
|
1960
|
+
if (premisesTrue && !evaluateClassical(goal, v)) {
|
|
1961
|
+
semanticResult = false;
|
|
1962
|
+
break;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
else {
|
|
1968
|
+
// No premises: check if goal is a tautology
|
|
1969
|
+
if (isPurePropositional(goal) && atomList.length <= 26) {
|
|
1970
|
+
const { result, allOnes } = evaluateBitset(goal, atomList);
|
|
1971
|
+
semanticResult = bvEquals(result, allOnes);
|
|
1972
|
+
}
|
|
1973
|
+
else if (isPurePropositional(goal) && atomList.length > 26) {
|
|
1974
|
+
const negated = { kind: 'not', args: [goal] };
|
|
1975
|
+
semanticResult = !(0, dpll_1.dpll)(negated).satisfiable;
|
|
1976
|
+
}
|
|
1977
|
+
else {
|
|
1978
|
+
const valuations = generateValuations(atomList);
|
|
1979
|
+
semanticResult = valuations.every((v) => evaluateClassical(goal, v));
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
if (semanticResult) {
|
|
1983
|
+
const semanticProofSteps = [
|
|
1984
|
+
...premiseNames
|
|
1985
|
+
.map((n, i) => {
|
|
1986
|
+
const f = theory.axioms.get(n) || theory.theorems.get(n);
|
|
1987
|
+
return f
|
|
1988
|
+
? {
|
|
1989
|
+
stepNumber: i + 1,
|
|
1990
|
+
formula: f,
|
|
1991
|
+
justification: `Premisa (${n})`,
|
|
1992
|
+
premises: [],
|
|
1993
|
+
}
|
|
1994
|
+
: null;
|
|
1995
|
+
})
|
|
1996
|
+
.filter((s) => s !== null),
|
|
1997
|
+
{
|
|
1998
|
+
stepNumber: premiseNames.length + 1,
|
|
1999
|
+
formula: goal,
|
|
2000
|
+
justification: 'Verificacion semantica (tautologia o consecuencia logica)',
|
|
2001
|
+
premises: premiseNames.map((_, i) => i + 1),
|
|
2002
|
+
},
|
|
2003
|
+
];
|
|
2004
|
+
const semanticProof = buildProof(goal, semanticProofSteps, premiseNames, theory, 'semantic');
|
|
2005
|
+
return {
|
|
2006
|
+
status: 'provable',
|
|
2007
|
+
output: `${formulaToString(goal)} es DEMOSTRABLE desde la teoria`,
|
|
2008
|
+
proof: semanticProof,
|
|
2009
|
+
educationalNote: (0, educational_notes_1.pickEducationalNote)({ op: 'prove', ok: true }),
|
|
2010
|
+
diagnostics: [],
|
|
2011
|
+
formula: goal,
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
1782
2014
|
return {
|
|
1783
2015
|
status: 'refutable',
|
|
1784
2016
|
output: `${formulaToString(goal)} NO es demostrable desde la teoria dada`,
|
|
@@ -1915,6 +2147,20 @@ class ClassicalPropositional {
|
|
|
1915
2147
|
};
|
|
1916
2148
|
}
|
|
1917
2149
|
explain(formula) {
|
|
2150
|
+
if (!isPurePropositional(formula)) {
|
|
2151
|
+
return {
|
|
2152
|
+
status: 'error',
|
|
2153
|
+
output: `explain solo esta disponible para formulas puramente proposicionales: ${(0, format_1.formulaToUnicode)(formula)}`,
|
|
2154
|
+
diagnostics: [
|
|
2155
|
+
{
|
|
2156
|
+
severity: 'error',
|
|
2157
|
+
message: 'La formula incluye operadores no proposicionales; use un perfil con explain semantico especifico.',
|
|
2158
|
+
},
|
|
2159
|
+
...this.checkWellFormed(formula),
|
|
2160
|
+
],
|
|
2161
|
+
formula,
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
1918
2164
|
const wf = this.checkWellFormed(formula);
|
|
1919
2165
|
if (wf.length > 0) {
|
|
1920
2166
|
return { status: 'error', diagnostics: wf, formula };
|