yukigo 0.2.3 → 0.3.2
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/.mocharc.json +3 -3
- package/CHANGELOG.md +105 -40
- package/README.md +193 -193
- package/dist/analyzer/GraphBuilder.d.ts +1 -0
- package/dist/analyzer/GraphBuilder.js +2 -1
- package/dist/analyzer/index.d.ts +0 -7
- package/dist/analyzer/index.js +3 -3
- package/dist/analyzer/inspections/functional/functional.d.ts +1 -1
- package/dist/analyzer/inspections/functional/functional.js +1 -1
- package/dist/analyzer/inspections/functional/smells.d.ts +3 -3
- package/dist/analyzer/inspections/functional/smells.js +27 -35
- package/dist/analyzer/inspections/generic/generic.d.ts +22 -14
- package/dist/analyzer/inspections/generic/generic.js +82 -60
- package/dist/analyzer/inspections/generic/smells.d.ts +2 -0
- package/dist/analyzer/inspections/generic/smells.js +55 -64
- package/dist/analyzer/inspections/imperative/imperative.d.ts +3 -3
- package/dist/analyzer/inspections/imperative/imperative.js +3 -3
- package/dist/analyzer/inspections/imperative/smells.d.ts +1 -0
- package/dist/analyzer/inspections/imperative/smells.js +8 -5
- package/dist/analyzer/inspections/logic/logic.d.ts +8 -8
- package/dist/analyzer/inspections/logic/logic.js +5 -5
- package/dist/analyzer/inspections/logic/smells.js +2 -2
- package/dist/analyzer/inspections/object/object.d.ts +5 -5
- package/dist/analyzer/inspections/object/object.js +22 -21
- package/dist/analyzer/inspections/object/smells.js +11 -23
- package/dist/analyzer/utils.d.ts +6 -2
- package/dist/analyzer/utils.js +6 -2
- package/dist/interpreter/components/EnvBuilder.d.ts +20 -1
- package/dist/interpreter/components/EnvBuilder.js +211 -66
- package/dist/interpreter/components/EqualityComparer.d.ts +15 -0
- package/dist/interpreter/components/EqualityComparer.js +69 -0
- package/dist/interpreter/components/Operations.d.ts +17 -14
- package/dist/interpreter/components/Operations.js +61 -62
- package/dist/interpreter/components/PatternMatcher.d.ts +19 -58
- package/dist/interpreter/components/PatternMatcher.js +185 -286
- package/dist/interpreter/components/RuntimeContext.d.ts +24 -15
- package/dist/interpreter/components/RuntimeContext.js +43 -4
- package/dist/interpreter/components/TestRunner.d.ts +15 -13
- package/dist/interpreter/components/TestRunner.js +86 -53
- package/dist/interpreter/components/evaluators/BaseEvaluator.d.ts +19 -0
- package/dist/interpreter/components/evaluators/BaseEvaluator.js +20 -0
- package/dist/interpreter/components/evaluators/ExpressionEvaluator.d.ts +34 -0
- package/dist/interpreter/components/evaluators/ExpressionEvaluator.js +298 -0
- package/dist/interpreter/components/evaluators/OperationEvaluator.d.ts +25 -0
- package/dist/interpreter/components/evaluators/OperationEvaluator.js +226 -0
- package/dist/interpreter/components/evaluators/PrimitiveEvaluator.d.ts +19 -0
- package/dist/interpreter/components/evaluators/PrimitiveEvaluator.js +50 -0
- package/dist/interpreter/components/evaluators/StatementEvaluator.d.ts +28 -0
- package/dist/interpreter/components/evaluators/StatementEvaluator.js +240 -0
- package/dist/interpreter/components/evaluators/TestingEvaluator.d.ts +15 -0
- package/dist/interpreter/components/evaluators/TestingEvaluator.js +14 -0
- package/dist/interpreter/components/evaluators/index.d.ts +110 -0
- package/dist/interpreter/components/evaluators/index.js +21 -0
- package/dist/interpreter/components/evaluators/utils.d.ts +7 -0
- package/dist/interpreter/components/evaluators/utils.js +50 -0
- package/dist/interpreter/components/hooks/YukigoHook.d.ts +27 -0
- package/dist/interpreter/components/hooks/YukigoHook.js +1 -0
- package/dist/interpreter/components/kernel/commands.d.ts +122 -0
- package/dist/interpreter/components/kernel/commands.js +203 -0
- package/dist/interpreter/components/kernel/index.d.ts +51 -0
- package/dist/interpreter/components/kernel/index.js +176 -0
- package/dist/interpreter/components/logic/LogicEngine.d.ts +26 -23
- package/dist/interpreter/components/logic/LogicEngine.js +234 -221
- package/dist/interpreter/components/logic/LogicResolver.d.ts +22 -51
- package/dist/interpreter/components/logic/LogicResolver.js +73 -440
- package/dist/interpreter/components/logic/LogicTerm.d.ts +104 -0
- package/dist/interpreter/components/logic/LogicTerm.js +423 -0
- package/dist/interpreter/components/logic/LogicTranslator.d.ts +25 -9
- package/dist/interpreter/components/logic/LogicTranslator.js +211 -74
- package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +6 -4
- package/dist/interpreter/components/runtimes/FunctionRuntime.js +82 -84
- package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +13 -14
- package/dist/interpreter/components/runtimes/LazyRuntime.js +112 -239
- package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +17 -14
- package/dist/interpreter/components/runtimes/ObjectRuntime.js +105 -74
- package/dist/interpreter/errors.d.ts +10 -0
- package/dist/interpreter/errors.js +17 -0
- package/dist/interpreter/index.d.ts +9 -5
- package/dist/interpreter/index.js +11 -13
- package/dist/interpreter/primitives/YuValue.d.ts +21 -0
- package/dist/interpreter/primitives/YuValue.js +40 -0
- package/dist/interpreter/primitives/capabilities.d.ts +90 -0
- package/dist/interpreter/primitives/capabilities.js +1 -0
- package/dist/interpreter/primitives/entities/LazyList.d.ts +48 -0
- package/dist/interpreter/primitives/entities/LazyList.js +164 -0
- package/dist/interpreter/primitives/entities/LogicResult.d.ts +51 -0
- package/dist/interpreter/primitives/entities/LogicResult.js +101 -0
- package/dist/interpreter/primitives/entities/RuntimeClass.d.ts +24 -0
- package/dist/interpreter/primitives/entities/RuntimeClass.js +57 -0
- package/dist/interpreter/primitives/entities/RuntimeFunction.d.ts +40 -0
- package/dist/interpreter/primitives/entities/RuntimeFunction.js +73 -0
- package/dist/interpreter/primitives/entities/RuntimeObject.d.ts +27 -0
- package/dist/interpreter/primitives/entities/RuntimeObject.js +82 -0
- package/dist/interpreter/primitives/entities/RuntimePredicate.d.ts +19 -0
- package/dist/interpreter/primitives/entities/RuntimePredicate.js +59 -0
- package/dist/interpreter/primitives/index.d.ts +14 -0
- package/dist/interpreter/primitives/index.js +14 -0
- package/dist/interpreter/primitives/scalars/YuBoolean.d.ts +24 -0
- package/dist/interpreter/primitives/scalars/YuBoolean.js +69 -0
- package/dist/interpreter/primitives/scalars/YuChar.d.ts +28 -0
- package/dist/interpreter/primitives/scalars/YuChar.js +78 -0
- package/dist/interpreter/primitives/scalars/YuNil.d.ts +25 -0
- package/dist/interpreter/primitives/scalars/YuNil.js +73 -0
- package/dist/interpreter/primitives/scalars/YuNumber.d.ts +49 -0
- package/dist/interpreter/primitives/scalars/YuNumber.js +165 -0
- package/dist/interpreter/primitives/sequences/YuArray.d.ts +33 -0
- package/dist/interpreter/primitives/sequences/YuArray.js +150 -0
- package/dist/interpreter/primitives/sequences/YuString.d.ts +40 -0
- package/dist/interpreter/primitives/sequences/YuString.js +130 -0
- package/dist/interpreter/utils.d.ts +23 -10
- package/dist/interpreter/utils.js +25 -30
- package/dist/tester/index.d.ts +3 -3
- package/dist/tester/index.js +39 -28
- package/dist/utils/helpers.d.ts +13 -5
- package/dist/utils/helpers.js +38 -85
- package/package.json +3 -16
- package/src/analyzer/GraphBuilder.ts +143 -142
- package/src/analyzer/index.ts +185 -194
- package/src/analyzer/inspections/functional/functional.ts +121 -121
- package/src/analyzer/inspections/functional/smells.ts +88 -102
- package/src/analyzer/inspections/generic/generic.ts +610 -577
- package/src/analyzer/inspections/generic/smells.ts +355 -365
- package/src/analyzer/inspections/imperative/imperative.ts +104 -101
- package/src/analyzer/inspections/imperative/smells.ts +58 -54
- package/src/analyzer/inspections/logic/logic.ts +84 -90
- package/src/analyzer/inspections/logic/smells.ts +54 -54
- package/src/analyzer/inspections/object/object.ts +295 -264
- package/src/analyzer/inspections/object/smells.ts +130 -144
- package/src/analyzer/utils.ts +115 -109
- package/src/index.ts +3 -3
- package/src/interpreter/components/EnvBuilder.ts +405 -202
- package/src/interpreter/components/EqualityComparer.ts +107 -0
- package/src/interpreter/components/Operations.ts +126 -99
- package/src/interpreter/components/PatternMatcher.ts +375 -475
- package/src/interpreter/components/RuntimeContext.ts +181 -119
- package/src/interpreter/components/TestRunner.ts +223 -151
- package/src/interpreter/components/evaluators/BaseEvaluator.ts +36 -0
- package/src/interpreter/components/evaluators/ExpressionEvaluator.ts +475 -0
- package/src/interpreter/components/evaluators/OperationEvaluator.ts +477 -0
- package/src/interpreter/components/evaluators/PrimitiveEvaluator.ts +80 -0
- package/src/interpreter/components/evaluators/StatementEvaluator.ts +372 -0
- package/src/interpreter/components/evaluators/TestingEvaluator.ts +26 -0
- package/src/interpreter/components/evaluators/index.ts +34 -0
- package/src/interpreter/components/evaluators/utils.ts +64 -0
- package/src/interpreter/components/hooks/YukigoHook.ts +45 -0
- package/src/interpreter/components/kernel/commands.ts +255 -0
- package/src/interpreter/components/kernel/index.ts +222 -0
- package/src/interpreter/components/logic/LogicEngine.ts +509 -519
- package/src/interpreter/components/logic/LogicResolver.ts +209 -858
- package/src/interpreter/components/logic/LogicTerm.ts +477 -0
- package/src/interpreter/components/logic/LogicTranslator.ts +362 -149
- package/src/interpreter/components/runtimes/FunctionRuntime.ts +249 -227
- package/src/interpreter/components/runtimes/LazyRuntime.ts +226 -334
- package/src/interpreter/components/runtimes/ObjectRuntime.ts +262 -224
- package/src/interpreter/errors.ts +68 -47
- package/src/interpreter/index.ts +50 -52
- package/src/interpreter/primitives/YuValue.ts +64 -0
- package/src/interpreter/primitives/capabilities.ts +111 -0
- package/src/interpreter/primitives/entities/LazyList.ts +225 -0
- package/src/interpreter/primitives/entities/LogicResult.ts +133 -0
- package/src/interpreter/primitives/entities/RuntimeClass.ts +70 -0
- package/src/interpreter/primitives/entities/RuntimeFunction.ts +108 -0
- package/src/interpreter/primitives/entities/RuntimeObject.ts +110 -0
- package/src/interpreter/primitives/entities/RuntimePredicate.ts +77 -0
- package/src/interpreter/primitives/index.ts +17 -0
- package/src/interpreter/primitives/scalars/YuBoolean.ts +79 -0
- package/src/interpreter/primitives/scalars/YuChar.ts +94 -0
- package/src/interpreter/primitives/scalars/YuNil.ts +84 -0
- package/src/interpreter/primitives/scalars/YuNumber.ts +187 -0
- package/src/interpreter/primitives/sequences/YuArray.ts +178 -0
- package/src/interpreter/primitives/sequences/YuString.ts +165 -0
- package/src/interpreter/utils.ts +105 -84
- package/src/tester/index.ts +157 -128
- package/src/utils/helpers.ts +113 -169
- package/tests/analyzer/functional.spec.ts +221 -207
- package/tests/analyzer/generic.spec.ts +178 -178
- package/tests/analyzer/helpers.spec.ts +83 -89
- package/tests/analyzer/logic.spec.ts +237 -237
- package/tests/analyzer/oop.spec.ts +320 -323
- package/tests/analyzer/transitive.spec.ts +166 -166
- package/tests/interpreter/EnvBuilder.spec.ts +181 -183
- package/tests/interpreter/FunctionRuntime.spec.ts +224 -223
- package/tests/interpreter/LazyRuntime.spec.ts +227 -225
- package/tests/interpreter/LogicEngine.spec.ts +371 -327
- package/tests/interpreter/LogicSubstitution.spec.ts +90 -80
- package/tests/interpreter/ObjectRuntime.spec.ts +431 -606
- package/tests/interpreter/Operations.spec.ts +312 -220
- package/tests/interpreter/PatternSystem.spec.ts +254 -213
- package/tests/interpreter/Tests.spec.ts +122 -122
- package/tests/interpreter/interpreter.spec.ts +1143 -991
- package/tests/kernel/YukigoKernel.spec.ts +112 -0
- package/tests/tester/Tester.spec.ts +156 -152
- package/tsconfig.build.json +16 -15
- package/tsconfig.json +27 -25
- package/dist/interpreter/components/Visitor.d.ts +0 -70
- package/dist/interpreter/components/Visitor.js +0 -634
- package/dist/interpreter/entities.d.ts +0 -105
- package/dist/interpreter/entities.js +0 -96
- package/dist/interpreter/trampoline.d.ts +0 -17
- package/dist/interpreter/trampoline.js +0 -38
- package/dist/src/analyzer/GraphBuilder.d.ts +0 -30
- package/dist/src/analyzer/GraphBuilder.js +0 -100
- package/dist/src/analyzer/index.d.ts +0 -59
- package/dist/src/analyzer/index.js +0 -152
- package/dist/src/analyzer/inspections/functional/functional.d.ts +0 -44
- package/dist/src/analyzer/inspections/functional/functional.js +0 -149
- package/dist/src/analyzer/inspections/functional/smells.d.ts +0 -16
- package/dist/src/analyzer/inspections/functional/smells.js +0 -98
- package/dist/src/analyzer/inspections/generic/generic.d.ts +0 -178
- package/dist/src/analyzer/inspections/generic/generic.js +0 -604
- package/dist/src/analyzer/inspections/generic/smells.d.ts +0 -61
- package/dist/src/analyzer/inspections/generic/smells.js +0 -349
- package/dist/src/analyzer/inspections/imperative/imperative.d.ts +0 -35
- package/dist/src/analyzer/inspections/imperative/imperative.js +0 -109
- package/dist/src/analyzer/inspections/imperative/smells.d.ts +0 -16
- package/dist/src/analyzer/inspections/imperative/smells.js +0 -58
- package/dist/src/analyzer/inspections/logic/logic.d.ts +0 -32
- package/dist/src/analyzer/inspections/logic/logic.js +0 -96
- package/dist/src/analyzer/inspections/logic/smells.d.ts +0 -15
- package/dist/src/analyzer/inspections/logic/smells.js +0 -60
- package/dist/src/analyzer/inspections/object/object.d.ts +0 -90
- package/dist/src/analyzer/inspections/object/object.js +0 -321
- package/dist/src/analyzer/inspections/object/smells.d.ts +0 -30
- package/dist/src/analyzer/inspections/object/smells.js +0 -135
- package/dist/src/analyzer/utils.d.ts +0 -30
- package/dist/src/analyzer/utils.js +0 -78
- package/dist/src/index.d.ts +0 -4
- package/dist/src/index.js +0 -4
- package/dist/src/interpreter/components/EnvBuilder.d.ts +0 -21
- package/dist/src/interpreter/components/EnvBuilder.js +0 -155
- package/dist/src/interpreter/components/Operations.d.ts +0 -14
- package/dist/src/interpreter/components/Operations.js +0 -84
- package/dist/src/interpreter/components/PatternMatcher.d.ts +0 -73
- package/dist/src/interpreter/components/PatternMatcher.js +0 -358
- package/dist/src/interpreter/components/RuntimeContext.d.ts +0 -35
- package/dist/src/interpreter/components/RuntimeContext.js +0 -93
- package/dist/src/interpreter/components/TestRunner.d.ts +0 -19
- package/dist/src/interpreter/components/TestRunner.js +0 -110
- package/dist/src/interpreter/components/Visitor.d.ts +0 -71
- package/dist/src/interpreter/components/Visitor.js +0 -638
- package/dist/src/interpreter/components/logic/LogicEngine.d.ts +0 -29
- package/dist/src/interpreter/components/logic/LogicEngine.js +0 -259
- package/dist/src/interpreter/components/logic/LogicResolver.d.ts +0 -53
- package/dist/src/interpreter/components/logic/LogicResolver.js +0 -484
- package/dist/src/interpreter/components/logic/LogicTranslator.d.ts +0 -14
- package/dist/src/interpreter/components/logic/LogicTranslator.js +0 -99
- package/dist/src/interpreter/components/runtimes/FunctionRuntime.d.ts +0 -12
- package/dist/src/interpreter/components/runtimes/FunctionRuntime.js +0 -149
- package/dist/src/interpreter/components/runtimes/LazyRuntime.d.ts +0 -19
- package/dist/src/interpreter/components/runtimes/LazyRuntime.js +0 -269
- package/dist/src/interpreter/components/runtimes/ObjectRuntime.d.ts +0 -35
- package/dist/src/interpreter/components/runtimes/ObjectRuntime.js +0 -126
- package/dist/src/interpreter/errors.d.ts +0 -19
- package/dist/src/interpreter/errors.js +0 -36
- package/dist/src/interpreter/index.d.ts +0 -24
- package/dist/src/interpreter/index.js +0 -41
- package/dist/src/interpreter/trampoline.d.ts +0 -17
- package/dist/src/interpreter/trampoline.js +0 -38
- package/dist/src/interpreter/utils.d.ts +0 -11
- package/dist/src/interpreter/utils.js +0 -65
- package/dist/src/tester/index.d.ts +0 -25
- package/dist/src/tester/index.js +0 -113
- package/dist/src/utils/helpers.d.ts +0 -13
- package/dist/src/utils/helpers.js +0 -52
- package/src/interpreter/components/Visitor.ts +0 -1065
- package/src/interpreter/trampoline.ts +0 -71
|
@@ -1,259 +1,272 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { createStream } from "../../utils.js";
|
|
4
|
-
import { InterpreterVisitor } from "../Visitor.js";
|
|
1
|
+
import { Goal, Not, Sequence, } from "yukigo-ast";
|
|
2
|
+
import { solveGoalKernel } from "./LogicResolver.js";
|
|
5
3
|
import { LogicTranslator } from "./LogicTranslator.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { RuntimeContext } from "../RuntimeContext.js";
|
|
5
|
+
import { StepCommand, BindCommand, ChoiceCommand, NotCommand, FindallCommand, BacktrackCommand, } from "../kernel/commands.js";
|
|
6
|
+
import { error, raise } from "../../utils.js";
|
|
7
|
+
import { YuArray, LogicResult, LogicAnswer, isLogicTerm, YuBoolean, isLogicResult, YuNil, YuString, } from "../../primitives/index.js";
|
|
8
|
+
import { InterpreterVisitor } from "../evaluators/index.js";
|
|
8
9
|
export class LogicEngine {
|
|
9
10
|
context;
|
|
10
11
|
translator;
|
|
12
|
+
dispatch;
|
|
11
13
|
constructor(evaluator, context) {
|
|
12
14
|
this.context = context;
|
|
15
|
+
if (!this.context.logicState) {
|
|
16
|
+
this.context.logicState = {
|
|
17
|
+
variableCounter: 0,
|
|
18
|
+
idToName: new Map(),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
13
21
|
this.translator = new LogicTranslator(evaluator, this.context);
|
|
22
|
+
this.dispatch = this.buildDispatch();
|
|
23
|
+
}
|
|
24
|
+
buildDispatch() {
|
|
25
|
+
const goalKernel = (node, substs, scope) => new BindCommand(this.resolveTerms(node, substs, scope), (termsRes) => {
|
|
26
|
+
const terms = termsRes.asSequence;
|
|
27
|
+
if (!terms || !(terms instanceof YuArray))
|
|
28
|
+
return raise(error("LogicEngine", "Expected array of terms"));
|
|
29
|
+
return this.runKernel(node, terms.items, substs);
|
|
30
|
+
});
|
|
31
|
+
return new Map([
|
|
32
|
+
[
|
|
33
|
+
"Sequence",
|
|
34
|
+
(node, substs, scope) => this.solveConjunction(node.statements, substs, scope),
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"LogicConstraint",
|
|
38
|
+
(node, substs, scope) => this.solveConjunction([node.expression], substs, scope),
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
"UnifyOperation",
|
|
42
|
+
(node, substs, scope) => {
|
|
43
|
+
const op = node;
|
|
44
|
+
return new BindCommand(this.unifyExpr(op.left, op.right, substs, scope), (res) => {
|
|
45
|
+
const isMatch = res instanceof YuBoolean && res.value;
|
|
46
|
+
if (isMatch)
|
|
47
|
+
return new StepCommand(new LogicResult([new LogicAnswer(true, substs)]));
|
|
48
|
+
return new BacktrackCommand();
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
"AssignOperation",
|
|
54
|
+
(node, substs, scope) => this.solveAssign(node, substs, scope),
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
"Findall",
|
|
58
|
+
(node, substs, scope) => this.solveFindall(node, substs, scope),
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"Forall",
|
|
62
|
+
(node, substs, scope) => this.solveForall(node, substs, scope),
|
|
63
|
+
],
|
|
64
|
+
["Not", (node, substs, scope) => this.solveNot(node, substs, scope)],
|
|
65
|
+
["Goal", (node, substs, scope) => goalKernel(node, substs, scope)],
|
|
66
|
+
[
|
|
67
|
+
"Exist",
|
|
68
|
+
(node, substs, scope) => goalKernel(node, substs, scope),
|
|
69
|
+
],
|
|
70
|
+
["If", (node, substs, scope) => this.solveIf(node, substs, scope)],
|
|
71
|
+
[
|
|
72
|
+
"Call",
|
|
73
|
+
(node, substs, scope) => {
|
|
74
|
+
const callNode = node;
|
|
75
|
+
return new BindCommand(this.translator.expressionToTerm(callNode.callee, scope), (calleeTermVal) => {
|
|
76
|
+
const calleeTerm = calleeTermVal
|
|
77
|
+
.instantiate(substs)
|
|
78
|
+
.resolve(substs);
|
|
79
|
+
return new BindCommand(this.resolveArgSequentially(callNode.args, substs, scope), (argsRes) => {
|
|
80
|
+
const resolvedArgs = argsRes
|
|
81
|
+
.items;
|
|
82
|
+
let targetPredicate;
|
|
83
|
+
let targetArgs;
|
|
84
|
+
if (calleeTerm.logicTermType === "Compound") {
|
|
85
|
+
const comp = calleeTerm;
|
|
86
|
+
targetPredicate = comp.functor;
|
|
87
|
+
targetArgs = [...comp.args, ...resolvedArgs];
|
|
88
|
+
}
|
|
89
|
+
else if (calleeTerm.logicTermType === "Constant") {
|
|
90
|
+
const constTerm = calleeTerm;
|
|
91
|
+
const val = constTerm.value;
|
|
92
|
+
if (val instanceof YuString) {
|
|
93
|
+
targetPredicate = val.value;
|
|
94
|
+
targetArgs = resolvedArgs;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return new BacktrackCommand();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return new BacktrackCommand();
|
|
102
|
+
}
|
|
103
|
+
return solveGoalKernel(this.context, targetPredicate, targetArgs, (body, s, scp) => this.solveConjunction(body, s, scp), substs, this.translator);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
]);
|
|
14
109
|
}
|
|
15
|
-
unifyExpr(left, right,
|
|
16
|
-
return this.translator.
|
|
17
|
-
|
|
18
|
-
return
|
|
110
|
+
unifyExpr(left, right, substs = new Map(), scope) {
|
|
111
|
+
return new BindCommand(this.translator.expressionToTerm(left, scope), (leftTerm) => {
|
|
112
|
+
if (!isLogicTerm(leftTerm))
|
|
113
|
+
return new BacktrackCommand();
|
|
114
|
+
return new BindCommand(this.translator.expressionToTerm(right, scope), (rightTerm) => {
|
|
115
|
+
if (!isLogicTerm(rightTerm))
|
|
116
|
+
return new BacktrackCommand();
|
|
117
|
+
return leftTerm.unify(rightTerm, substs);
|
|
19
118
|
});
|
|
20
119
|
});
|
|
21
120
|
}
|
|
22
|
-
solveQuery(node
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
else if (mode === "stream") {
|
|
28
|
-
return k(this.createLazyStream(node.expressions, new Map()));
|
|
29
|
-
}
|
|
30
|
-
// "first" mode
|
|
31
|
-
return this.solveConjunction(node.expressions, new Map(), (s) => k(this.formatLogicResult(s)), () => k(false));
|
|
121
|
+
solveQuery(node) {
|
|
122
|
+
const scope = new Map();
|
|
123
|
+
const compiled = this.solveConjunction(node.expressions, new Map(), scope);
|
|
124
|
+
return this.aggregateResults(compiled, scope);
|
|
32
125
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
return solveGoalCPS(this.context, id, patterns, (body, s, onSucc, onFail) => this.solveConjunction(body, s, onSucc, onFail), new Map(), (s) => k(this.formatLogicResult(s)), () => k(false));
|
|
126
|
+
solveGoalLike(node, outerSubsts, outerScope) {
|
|
127
|
+
const scope = outerScope ?? new Map();
|
|
128
|
+
const substs = outerSubsts ?? new Map();
|
|
129
|
+
return new BindCommand(this.resolveTerms(node, substs, scope), (termsRes) => {
|
|
130
|
+
const termsSeq = termsRes.asSequence;
|
|
131
|
+
if (!(termsSeq instanceof YuArray))
|
|
132
|
+
return new BacktrackCommand();
|
|
133
|
+
const terms = termsSeq.items;
|
|
134
|
+
if (!terms.every(isLogicTerm))
|
|
135
|
+
return new BacktrackCommand();
|
|
136
|
+
return this.runKernel(node, terms, substs);
|
|
45
137
|
});
|
|
46
138
|
}
|
|
47
|
-
solveNot(node,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return solveFindallCPS(node, new Map(), (body, substs, onSuccess, onFailure) => this.solveConjunction(body, substs, onSuccess, onFailure), (finalSubsts) => {
|
|
52
|
-
const pat = finalSubsts.get(node.bag.name.value);
|
|
53
|
-
const val = this.translator.patternToPrimitive(pat);
|
|
54
|
-
return k(val);
|
|
55
|
-
}, () => k([]));
|
|
139
|
+
solveNot(node, substs = new Map(), scope = new Map()) {
|
|
140
|
+
const clonedSubsts = new Map(substs);
|
|
141
|
+
const innerGoalCmd = this.solveConjunction([node.expression], clonedSubsts, scope);
|
|
142
|
+
return new NotCommand(innerGoalCmd, substs);
|
|
56
143
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
144
|
+
solveFindall(node, substs = new Map(), scope = new Map()) {
|
|
145
|
+
const clonedSubsts = new Map(substs);
|
|
146
|
+
const innerGoalCmd = this.solveConjunction([node.goal], clonedSubsts, scope);
|
|
147
|
+
return new FindallCommand(node.template, node.bag, innerGoalCmd, substs, scope, this.translator);
|
|
61
148
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
149
|
+
solveAssign(op, substs, scope) {
|
|
150
|
+
const localEnv = this.createLocalEnv(substs);
|
|
151
|
+
const isolatedContext = new RuntimeContext(this.context.config);
|
|
152
|
+
isolatedContext.logicState = this.context.logicState;
|
|
153
|
+
isolatedContext.setEnv({ head: localEnv, tail: this.context.env });
|
|
154
|
+
const localEvaluator = new InterpreterVisitor(isolatedContext);
|
|
155
|
+
return new BindCommand(localEvaluator.evaluate(op.right), (val) => {
|
|
156
|
+
const resultTerm = this.translator.primitiveToTerm(val);
|
|
157
|
+
return new BindCommand(this.translator.expressionToTerm(op.left, scope), (leftTerm) => {
|
|
158
|
+
if (!isLogicTerm(leftTerm))
|
|
159
|
+
return new BacktrackCommand();
|
|
160
|
+
if (leftTerm.unify(resultTerm, substs)) {
|
|
161
|
+
return new StepCommand(new LogicResult([new LogicAnswer(true, substs)]));
|
|
162
|
+
}
|
|
163
|
+
return new BacktrackCommand();
|
|
164
|
+
});
|
|
73
165
|
});
|
|
74
166
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (nodes.length === 0) {
|
|
79
|
-
if (this.context.config.debug)
|
|
80
|
-
console.log(`[LogicEngine] Nothing else to solve. Success.`);
|
|
81
|
-
return onSuccess(substs, onFailure);
|
|
82
|
-
}
|
|
83
|
-
const [head, ...tail] = nodes;
|
|
84
|
-
return () => this.solveSingle(head, substs, (newSubsts, next) => {
|
|
85
|
-
return this.solveConjunction(tail, newSubsts, onSuccess, next);
|
|
86
|
-
}, onFailure);
|
|
167
|
+
solveForall(node, substs = new Map(), scope = new Map()) {
|
|
168
|
+
// a forall(Cond, Action) is equivalent to \+ (Cond, \+ Action)
|
|
169
|
+
return this.solveNot(new Not(new Sequence([node.condition, new Not(node.action)])), substs, scope);
|
|
87
170
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
171
|
+
aggregateResults(command, scope) {
|
|
172
|
+
return new BindCommand(command, (res) => {
|
|
173
|
+
if (!isLogicResult(res))
|
|
174
|
+
return new StepCommand(res);
|
|
175
|
+
const mappedAnswers = res.allAnswers.map((ans) => this.finalizeUserResult(ans, scope));
|
|
176
|
+
return new StepCommand(new LogicResult(mappedAnswers));
|
|
177
|
+
});
|
|
92
178
|
}
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return () => this.solveConjunction(goal.statements, substs, onSuccess, onFailure);
|
|
179
|
+
branchSolutions(solutions, tail, scope) {
|
|
180
|
+
if (solutions.length === 0)
|
|
181
|
+
return new BacktrackCommand();
|
|
182
|
+
if (solutions.length === 1) {
|
|
183
|
+
return this.solveConjunction(tail, solutions[0], scope);
|
|
99
184
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
185
|
+
return new ChoiceCommand(solutions.map((s) => this.solveConjunction(tail, s, scope)));
|
|
186
|
+
}
|
|
187
|
+
solveConjunction(nodes, substs, scope) {
|
|
188
|
+
if (nodes.length === 0) {
|
|
189
|
+
return new StepCommand(new LogicResult([new LogicAnswer(true, substs)]));
|
|
105
190
|
}
|
|
106
|
-
|
|
107
|
-
|
|
191
|
+
const [head, ...tail] = nodes;
|
|
192
|
+
const solver = this.dispatch.get(head.constructor.name) ??
|
|
193
|
+
((node, s) => this.solveCondition(node, s));
|
|
194
|
+
const currentSubst = new Map(substs);
|
|
195
|
+
return new BindCommand(solver(head, currentSubst, scope), (res) => {
|
|
196
|
+
// fail if result not a LogicResult or if some conditionfail
|
|
197
|
+
if (!isLogicResult(res) || !res.allSuccessful())
|
|
198
|
+
return new BacktrackCommand();
|
|
199
|
+
return this.branchSolutions(res.getSuccessfulSolutions(), tail, scope);
|
|
108
200
|
});
|
|
109
201
|
}
|
|
110
|
-
solveCondition(expr, substs
|
|
111
|
-
this.createLocalEnv(substs);
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return onSuccess(currentSubsts, onFailure);
|
|
127
|
-
}
|
|
128
|
-
return onFailure();
|
|
202
|
+
solveCondition(expr, substs) {
|
|
203
|
+
const localEnv = this.createLocalEnv(substs);
|
|
204
|
+
const isolatedContext = new RuntimeContext(this.context.config);
|
|
205
|
+
isolatedContext.logicState = this.context.logicState;
|
|
206
|
+
isolatedContext.setEnv({ head: localEnv, tail: this.context.env });
|
|
207
|
+
const localEvaluator = new InterpreterVisitor(isolatedContext);
|
|
208
|
+
return new BindCommand(localEvaluator.evaluate(expr), (result) => {
|
|
209
|
+
// fail if result is falsy
|
|
210
|
+
const isTrue = (result instanceof YuBoolean && result.value) ||
|
|
211
|
+
(result instanceof LogicResult && result.success) ||
|
|
212
|
+
result instanceof YuNil;
|
|
213
|
+
if (!isTrue)
|
|
214
|
+
return new BacktrackCommand();
|
|
215
|
+
return new StepCommand(new LogicResult([new LogicAnswer(true, substs)]));
|
|
129
216
|
});
|
|
130
217
|
}
|
|
131
|
-
isLogicGoal(node) {
|
|
132
|
-
return (node instanceof Goal ||
|
|
133
|
-
node instanceof Exist ||
|
|
134
|
-
node instanceof Findall ||
|
|
135
|
-
node instanceof LogicConstraint ||
|
|
136
|
-
node instanceof Sequence);
|
|
137
|
-
}
|
|
138
218
|
createLocalEnv(substs) {
|
|
139
|
-
|
|
140
|
-
for (const [
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// map base name if it was standardized apart ("X_1" -> "X")
|
|
145
|
-
const baseNameMatch = name.match(/^(.*)_\d+$/);
|
|
146
|
-
if (baseNameMatch) {
|
|
147
|
-
const baseName = baseNameMatch[1];
|
|
148
|
-
if (!this.context.env.head.has(baseName)) {
|
|
149
|
-
this.context.define(baseName, value);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
prepareLogicTargetCPS(node, substs, k) {
|
|
155
|
-
const id = node.identifier.value;
|
|
156
|
-
if (node instanceof Goal) {
|
|
157
|
-
const patterns = [];
|
|
158
|
-
const next = (index) => {
|
|
159
|
-
if (index >= node.args.length)
|
|
160
|
-
return k({ id, patterns });
|
|
161
|
-
return this.translator.instantiateExpressionAsPattern(node.args[index], substs, (p) => {
|
|
162
|
-
patterns.push(p);
|
|
163
|
-
return () => next(index + 1);
|
|
164
|
-
});
|
|
165
|
-
};
|
|
166
|
-
return () => next(0);
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
const patterns = node.patterns.map((pat) => instantiate(pat, substs));
|
|
170
|
-
return k({ id, patterns });
|
|
219
|
+
const env = new Map();
|
|
220
|
+
for (const [id, term] of substs) {
|
|
221
|
+
const name = typeof id === "string" ? id : this.translator.getName(id);
|
|
222
|
+
if (name)
|
|
223
|
+
env.set(name, term.instantiate(substs).toPrimitive(substs));
|
|
171
224
|
}
|
|
225
|
+
return env;
|
|
172
226
|
}
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}, () => k(results));
|
|
227
|
+
finalizeUserResult(ans, scope) {
|
|
228
|
+
const solution = ans.getSolution();
|
|
229
|
+
const fromScope = Array.from(scope.entries()).map(([name, term]) => [name, term.instantiate(solution)]);
|
|
230
|
+
const fromSolution = Array.from(solution.entries()).map(([id, term]) => [
|
|
231
|
+
typeof id === "number" ? this.translator.getName(id) : id,
|
|
232
|
+
term.instantiate(solution),
|
|
233
|
+
]);
|
|
234
|
+
const userMapped = new Map([fromSolution, fromScope].flatMap((s) => [...s]));
|
|
235
|
+
return new LogicAnswer(ans.isSuccessful(), userMapped);
|
|
183
236
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}, () => k(results));
|
|
237
|
+
resolveTerms(node, substs, scope) {
|
|
238
|
+
if (node.is(Goal))
|
|
239
|
+
return this.resolveArgSequentially(node.args, substs, scope);
|
|
240
|
+
const terms = node.patterns.map((pat) => this.translator.patternToTerm(pat, scope).instantiate(substs));
|
|
241
|
+
return new StepCommand(new YuArray(terms));
|
|
190
242
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
next: () => {
|
|
205
|
-
trampoline(thunk);
|
|
206
|
-
if (currentSubst) {
|
|
207
|
-
const res = this.formatLogicResult(currentSubst);
|
|
208
|
-
thunk = currentNext();
|
|
209
|
-
return { value: res, done: false };
|
|
210
|
-
}
|
|
211
|
-
return { value: undefined, done: true };
|
|
212
|
-
},
|
|
213
|
-
};
|
|
214
|
-
});
|
|
243
|
+
resolveArgSequentially(args, substs, scope) {
|
|
244
|
+
const terms = [];
|
|
245
|
+
const next = (index) => {
|
|
246
|
+
if (index >= args.length) {
|
|
247
|
+
return new StepCommand(new YuArray(terms));
|
|
248
|
+
}
|
|
249
|
+
return new BindCommand(this.translator.instantiateExpressionAsTerm(args[index], substs, scope), (t) => {
|
|
250
|
+
if (isLogicTerm(t))
|
|
251
|
+
terms.push(t);
|
|
252
|
+
return next(index + 1);
|
|
253
|
+
});
|
|
254
|
+
};
|
|
255
|
+
return next(0);
|
|
215
256
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
let currentNext = null;
|
|
219
|
-
let thunk = solveGoalCPS(this.context, id, patterns, (body, s, onSucc, onFail) => this.solveConjunction(body, s, onSucc, onFail), substs, (s, next) => {
|
|
220
|
-
currentSubst = s;
|
|
221
|
-
currentNext = next;
|
|
222
|
-
return null;
|
|
223
|
-
}, () => {
|
|
224
|
-
currentSubst = null;
|
|
225
|
-
return null;
|
|
226
|
-
});
|
|
227
|
-
return createStream(() => {
|
|
228
|
-
return {
|
|
229
|
-
next: () => {
|
|
230
|
-
trampoline(thunk);
|
|
231
|
-
if (currentSubst) {
|
|
232
|
-
const res = this.formatLogicResult(currentSubst);
|
|
233
|
-
thunk = currentNext();
|
|
234
|
-
return { value: res, done: false };
|
|
235
|
-
}
|
|
236
|
-
return { value: undefined, done: true };
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
});
|
|
257
|
+
runKernel(node, terms, substs) {
|
|
258
|
+
return solveGoalKernel(this.context, node.identifier.value, terms, (body, s, scp) => this.solveConjunction(body, s, scp), substs, this.translator);
|
|
240
259
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// Also map base name if it was standardized apart (e.g., "X_1" -> "X")
|
|
248
|
-
const baseNameMatch = key.match(/^(.*)_\d+$/);
|
|
249
|
-
if (baseNameMatch) {
|
|
250
|
-
const baseName = baseNameMatch[1];
|
|
251
|
-
if (!solutions.has(baseName)) {
|
|
252
|
-
solutions.set(baseName, val);
|
|
253
|
-
}
|
|
260
|
+
solveIf(node, substs, scope) {
|
|
261
|
+
return new BindCommand(this.solveConjunction([node.condition], substs, scope), (res) => {
|
|
262
|
+
if (isLogicResult(res) && res.allSuccessful()) {
|
|
263
|
+
const solutions = res.getSuccessfulSolutions();
|
|
264
|
+
if (solutions.length === 1) {
|
|
265
|
+
return this.solveConjunction([node.then], solutions[0], scope);
|
|
254
266
|
}
|
|
267
|
+
return new ChoiceCommand(solutions.map((s) => this.solveConjunction([node.then], s, scope)));
|
|
255
268
|
}
|
|
269
|
+
return this.solveConjunction([node.elseExpr], substs, scope);
|
|
256
270
|
});
|
|
257
|
-
return { success: true, solutions };
|
|
258
271
|
}
|
|
259
272
|
}
|
|
@@ -1,53 +1,24 @@
|
|
|
1
|
-
import { Fact,
|
|
2
|
-
import { Thunk } from "../../trampoline.js";
|
|
1
|
+
import { Fact, Rule, Visitor, ASTNode } from "yukigo-ast";
|
|
3
2
|
import { LogicExecutable } from "./LogicEngine.js";
|
|
4
3
|
import { RuntimeContext } from "../RuntimeContext.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*
|
|
23
|
-
*/
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
* Creates a successful logic result.
|
|
27
|
-
*/
|
|
28
|
-
export declare function success(substs: Substitution): InternalLogicResult;
|
|
29
|
-
/**
|
|
30
|
-
* Unifies two patterns given an existing set of substitutions.
|
|
31
|
-
* Returns the updated substitution map or null if unification fails.
|
|
32
|
-
*/
|
|
33
|
-
export declare function unify(t1: Pattern, t2: Pattern, argEnv?: Substitution): Substitution | null;
|
|
34
|
-
/**
|
|
35
|
-
* Follows variable bindings in the substitution map until a non-variable or unbound variable is found.
|
|
36
|
-
*/
|
|
37
|
-
export declare function resolve(node: Pattern, env: Substitution): Pattern;
|
|
38
|
-
/**
|
|
39
|
-
* Fully instantiates a pattern by replacing all bound variables with their values.
|
|
40
|
-
*/
|
|
41
|
-
export declare function instantiate(pattern: Pattern, substs: Substitution, seen?: Set<string>): Pattern;
|
|
42
|
-
/**
|
|
43
|
-
* Renames all variables in a Rule or Fact to fresh names to avoid name clashes during unification.
|
|
44
|
-
*/
|
|
45
|
-
export declare function renameVariables<T extends Rule | Fact>(clause: T): T;
|
|
46
|
-
/**
|
|
47
|
-
* Solves a single logic goal (predicate call) using CPS.
|
|
48
|
-
*/
|
|
49
|
-
export declare function solveGoalCPS(ctx: RuntimeContext, predicateName: string, args: Pattern[], solveBody: BodySolverCPS, baseSubst: Substitution, onSuccess: SuccessCont, onFailure: FailureCont): Thunk<any>;
|
|
50
|
-
/**
|
|
51
|
-
* Solves a findall/3 goal using CPS.
|
|
52
|
-
*/
|
|
53
|
-
export declare function solveFindallCPS(node: Findall, currentSubsts: Substitution, solveBody: BodySolverCPS, onSuccess: SuccessCont, onFailure: FailureCont): Thunk<any>;
|
|
4
|
+
import { ExecutionCommand } from "../kernel/commands.js";
|
|
5
|
+
import { LogicTranslator } from "./LogicTranslator.js";
|
|
6
|
+
import { VariableTerm } from "./LogicTerm.js";
|
|
7
|
+
import { LogicTerm, Substitution } from "../../primitives/index.js";
|
|
8
|
+
type Solver = (expressions: LogicExecutable[], env: Substitution, scope?: Map<string, VariableTerm>) => ExecutionCommand;
|
|
9
|
+
export declare class GoalKernelVisitor implements Visitor<ExecutionCommand> {
|
|
10
|
+
private readonly args;
|
|
11
|
+
private readonly baseSubst;
|
|
12
|
+
private readonly solveBody;
|
|
13
|
+
private readonly translator;
|
|
14
|
+
constructor(args: LogicTerm[], baseSubst: Substitution, solveBody: Solver, translator: LogicTranslator);
|
|
15
|
+
visitFact(fact: Fact): ExecutionCommand;
|
|
16
|
+
visitRule(rule: Rule): ExecutionCommand;
|
|
17
|
+
fallback(node: ASTNode): ExecutionCommand;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Solves a single logic goal (predicate call) using the Kernel.
|
|
21
|
+
* Returns a non-deterministic command. Aggregation should happen at top-level.
|
|
22
|
+
*/
|
|
23
|
+
export declare function solveGoalKernel(ctx: RuntimeContext, predicateName: string, args: LogicTerm[], solveBody: Solver, baseSubst: Substitution, translator: LogicTranslator): ExecutionCommand;
|
|
24
|
+
export {};
|