yukigo 0.2.2 → 0.3.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/.mocharc.json +3 -3
- package/CHANGELOG.md +102 -41
- 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 +21 -14
- package/dist/analyzer/inspections/generic/generic.js +78 -59
- 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 +12 -5
- package/dist/utils/helpers.js +6 -79
- 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 -581
- 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 +81 -168
- 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 +188 -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,327 +1,371 @@
|
|
|
1
|
-
import { expect } from "chai";
|
|
2
|
-
import {
|
|
3
|
-
SymbolPrimitive,
|
|
4
|
-
NumberPrimitive,
|
|
5
|
-
LiteralPattern,
|
|
6
|
-
VariablePattern,
|
|
7
|
-
Fact,
|
|
8
|
-
Findall,
|
|
9
|
-
Goal,
|
|
10
|
-
Pattern,
|
|
11
|
-
Rule,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
new
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
],
|
|
66
|
-
|
|
67
|
-
const rulesSibling
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
[varPat("
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
context
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
expect(results).to.be.
|
|
291
|
-
|
|
292
|
-
const names = results.map((
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
expect(names).to.include("ares");
|
|
297
|
-
expect(names).to.include("athena");
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import {
|
|
3
|
+
SymbolPrimitive,
|
|
4
|
+
NumberPrimitive,
|
|
5
|
+
LiteralPattern,
|
|
6
|
+
VariablePattern,
|
|
7
|
+
Fact,
|
|
8
|
+
Findall,
|
|
9
|
+
Goal,
|
|
10
|
+
Pattern,
|
|
11
|
+
Rule,
|
|
12
|
+
Equation,
|
|
13
|
+
Sequence,
|
|
14
|
+
UnguardedBody,
|
|
15
|
+
Statement,
|
|
16
|
+
Variable,
|
|
17
|
+
NilPrimitive,
|
|
18
|
+
LogicConstraint,
|
|
19
|
+
Expression,
|
|
20
|
+
Query,
|
|
21
|
+
} from "yukigo-ast";
|
|
22
|
+
import { createGlobalEnv } from "../../src/interpreter/utils.js";
|
|
23
|
+
import { LogicEngine } from "../../src/interpreter/components/logic/LogicEngine.js";
|
|
24
|
+
import { RuntimeContext } from "../../src/interpreter/components/RuntimeContext.js";
|
|
25
|
+
import { YukigoKernel } from "../../src/interpreter/components/kernel/index.js";
|
|
26
|
+
import { StepCommand } from "../../src/interpreter/components/kernel/commands.js";
|
|
27
|
+
import {
|
|
28
|
+
VariableTerm,
|
|
29
|
+
ConstantTerm,
|
|
30
|
+
ListTerm,
|
|
31
|
+
ConsTerm,
|
|
32
|
+
CompoundTerm,
|
|
33
|
+
} from "../../src/interpreter/components/logic/LogicTerm.js";
|
|
34
|
+
import {
|
|
35
|
+
YuValue,
|
|
36
|
+
RuntimePredicate,
|
|
37
|
+
LogicTerm,
|
|
38
|
+
Substitution,
|
|
39
|
+
YuString,
|
|
40
|
+
YuNumber,
|
|
41
|
+
LazyList,
|
|
42
|
+
LazyStepResult,
|
|
43
|
+
YuNil,
|
|
44
|
+
LogicResult,
|
|
45
|
+
YuBoolean,
|
|
46
|
+
} from "../../src/interpreter/primitives/index.js";
|
|
47
|
+
import { InterpreterVisitor } from "../../src/interpreter/components/evaluators/index.js";
|
|
48
|
+
|
|
49
|
+
const s = (val: string) => new SymbolPrimitive(val);
|
|
50
|
+
const n = (val: number) => new NumberPrimitive(val);
|
|
51
|
+
const lit = (val: string | number) =>
|
|
52
|
+
new LiteralPattern(typeof val === "string" ? s(val) : n(val));
|
|
53
|
+
const varPat = (name: string) => new VariablePattern(s(name));
|
|
54
|
+
|
|
55
|
+
const makeEq = (args: Pattern[], stmts: Statement[]) =>
|
|
56
|
+
new Equation(args, new UnguardedBody(new Sequence(stmts)));
|
|
57
|
+
const makeFact = (id: string, args: Pattern[]) => new Fact(s(id), args);
|
|
58
|
+
const makeRule = (id: string, body: Equation[]) => new Rule(s(id), body);
|
|
59
|
+
const makeGoal = (id: string, args: Pattern[]) => new Goal(s(id), args);
|
|
60
|
+
const makeConstraint = (expr: Expression) => new LogicConstraint(expr);
|
|
61
|
+
|
|
62
|
+
const factsParent = new RuntimePredicate("parent", [
|
|
63
|
+
makeFact("parent", [lit("zeus"), lit("ares")]),
|
|
64
|
+
makeFact("parent", [lit("zeus"), lit("athena")]),
|
|
65
|
+
makeFact("parent", [lit("hera"), lit("ares")]),
|
|
66
|
+
]);
|
|
67
|
+
const rulesSibling = new RuntimePredicate("sibling", [
|
|
68
|
+
makeRule("sibling", [
|
|
69
|
+
makeEq(
|
|
70
|
+
[varPat("X"), varPat("Y")],
|
|
71
|
+
[
|
|
72
|
+
makeConstraint(makeGoal("parent", [varPat("Z"), varPat("X")])),
|
|
73
|
+
makeConstraint(makeGoal("parent", [varPat("Z"), varPat("Y")])),
|
|
74
|
+
],
|
|
75
|
+
),
|
|
76
|
+
]),
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
describe("Logic Engine & Unification", () => {
|
|
80
|
+
let engine: LogicEngine;
|
|
81
|
+
let evaluator: InterpreterVisitor;
|
|
82
|
+
let kernel: YukigoKernel;
|
|
83
|
+
let context: RuntimeContext;
|
|
84
|
+
let globalEnv: any;
|
|
85
|
+
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
globalEnv = createGlobalEnv();
|
|
88
|
+
context = new RuntimeContext({
|
|
89
|
+
debug: false,
|
|
90
|
+
outputMode: "all",
|
|
91
|
+
});
|
|
92
|
+
context.setEnv(globalEnv);
|
|
93
|
+
context.define("sibling", rulesSibling);
|
|
94
|
+
context.define("parent", factsParent);
|
|
95
|
+
evaluator = new InterpreterVisitor(context);
|
|
96
|
+
engine = new LogicEngine(evaluator, context);
|
|
97
|
+
kernel = new YukigoKernel(evaluator, "all");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const unify = (
|
|
101
|
+
t1: LogicTerm,
|
|
102
|
+
t2: LogicTerm,
|
|
103
|
+
substs: Substitution = new Map(),
|
|
104
|
+
) => {
|
|
105
|
+
const cmd = t1.unify(t2, substs);
|
|
106
|
+
const k = new YukigoKernel(evaluator, "first");
|
|
107
|
+
const res = k.run(cmd);
|
|
108
|
+
if (res instanceof YuBoolean && res.value) {
|
|
109
|
+
return substs;
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
describe("Unification Algorithm", () => {
|
|
115
|
+
it("should unify two identical literals", () => {
|
|
116
|
+
const p1 = new ConstantTerm(new YuString("cat"));
|
|
117
|
+
const p2 = new ConstantTerm(new YuString("cat"));
|
|
118
|
+
const result = unify(p1, p2);
|
|
119
|
+
expect(result).to.not.be.null;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("should not unify different literals", () => {
|
|
123
|
+
const p1 = new ConstantTerm(new YuString("cat"));
|
|
124
|
+
const p2 = new ConstantTerm(new YuString("dog"));
|
|
125
|
+
const result = unify(p1, p2);
|
|
126
|
+
expect(result).to.be.null;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("should unify a variable with a literal", () => {
|
|
130
|
+
const v1 = new VariableTerm(1, "X");
|
|
131
|
+
const p2 = new ConstantTerm(new YuString("cat"));
|
|
132
|
+
const result = unify(v1, p2);
|
|
133
|
+
|
|
134
|
+
expect(result).to.not.be.null;
|
|
135
|
+
const resolved = v1.resolve(result!);
|
|
136
|
+
expect(resolved).to.be.instanceOf(ConstantTerm);
|
|
137
|
+
expect((resolved as ConstantTerm).value.toJSON()).to.equal("cat");
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("should unify two variables (aliasing)", () => {
|
|
141
|
+
const v1 = new VariableTerm(1, "X");
|
|
142
|
+
const v2 = new VariableTerm(2, "Y");
|
|
143
|
+
const result = unify(v1, v2);
|
|
144
|
+
expect(result).to.not.be.null;
|
|
145
|
+
expect(result!.has(1)).to.be.true;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe("ConsPattern Unification", () => {
|
|
149
|
+
it("should unify two identical ConsPatterns", () => {
|
|
150
|
+
const p1 = new ConsTerm(
|
|
151
|
+
new ConstantTerm(new YuNumber(1)),
|
|
152
|
+
new ListTerm([]),
|
|
153
|
+
);
|
|
154
|
+
const p2 = new ConsTerm(
|
|
155
|
+
new ConstantTerm(new YuNumber(1)),
|
|
156
|
+
new ListTerm([]),
|
|
157
|
+
);
|
|
158
|
+
const result = unify(p1, p2);
|
|
159
|
+
expect(result).to.not.be.null;
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("should unify ConsPattern with equivalent ListPattern", () => {
|
|
163
|
+
const cons = new ConsTerm(
|
|
164
|
+
new ConstantTerm(new YuNumber(1)),
|
|
165
|
+
new ListTerm([new ConstantTerm(new YuNumber(2))]),
|
|
166
|
+
);
|
|
167
|
+
const list = new ListTerm([
|
|
168
|
+
new ConstantTerm(new YuNumber(1)),
|
|
169
|
+
new ConstantTerm(new YuNumber(2)),
|
|
170
|
+
]);
|
|
171
|
+
const result = unify(cons, list);
|
|
172
|
+
expect(result).to.not.be.null;
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("should unify ListPattern with equivalent ConsPattern", () => {
|
|
176
|
+
const list = new ListTerm([
|
|
177
|
+
new ConstantTerm(new YuNumber(1)),
|
|
178
|
+
new ConstantTerm(new YuNumber(2)),
|
|
179
|
+
]);
|
|
180
|
+
const cons = new ConsTerm(
|
|
181
|
+
new ConstantTerm(new YuNumber(1)),
|
|
182
|
+
new ListTerm([new ConstantTerm(new YuNumber(2))]),
|
|
183
|
+
);
|
|
184
|
+
const result = unify(list, cons);
|
|
185
|
+
expect(result).to.not.be.null;
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("should fail if heads do not match", () => {
|
|
189
|
+
const cons = new ConsTerm(
|
|
190
|
+
new ConstantTerm(new YuNumber(1)),
|
|
191
|
+
new ListTerm([new ConstantTerm(new YuNumber(2))]),
|
|
192
|
+
);
|
|
193
|
+
const list = new ListTerm([
|
|
194
|
+
new ConstantTerm(new YuNumber(3)),
|
|
195
|
+
new ConstantTerm(new YuNumber(2)),
|
|
196
|
+
]);
|
|
197
|
+
const result = unify(cons, list);
|
|
198
|
+
expect(result).to.be.null;
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("should fail if ListPattern is empty and ConsPattern expects head", () => {
|
|
202
|
+
const list = new ListTerm([]);
|
|
203
|
+
const cons = new ConsTerm(
|
|
204
|
+
new VariableTerm(1, "H"),
|
|
205
|
+
new VariableTerm(2, "T"),
|
|
206
|
+
);
|
|
207
|
+
const result = unify(list, cons);
|
|
208
|
+
expect(result).to.be.null;
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("should bind variables in ConsPattern", () => {
|
|
212
|
+
const list = new ListTerm([
|
|
213
|
+
new ConstantTerm(new YuNumber(1)),
|
|
214
|
+
new ConstantTerm(new YuNumber(2)),
|
|
215
|
+
]);
|
|
216
|
+
|
|
217
|
+
const vH = new VariableTerm(1, "H");
|
|
218
|
+
const vT = new VariableTerm(2, "T");
|
|
219
|
+
const cons = new ConsTerm(vH, vT);
|
|
220
|
+
const result = unify(cons, list) as Substitution;
|
|
221
|
+
expect(result).to.not.be.null;
|
|
222
|
+
|
|
223
|
+
const h = vH.resolve(result);
|
|
224
|
+
expect(h).to.be.instanceOf(ConstantTerm);
|
|
225
|
+
|
|
226
|
+
const t = vT.resolve(result);
|
|
227
|
+
expect(t).to.be.instanceOf(ListTerm);
|
|
228
|
+
expect((t as ListTerm).elements).to.have.lengthOf(1);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("should fail unification with occurs check (circularity)", () => {
|
|
232
|
+
const vX = new VariableTerm(1, "X");
|
|
233
|
+
const compound = new CompoundTerm("f", [vX]);
|
|
234
|
+
const result = unify(vX, compound);
|
|
235
|
+
expect(result).to.be.null;
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("should unify infinite LazyList with Variable lazily", () => {
|
|
239
|
+
const createLazyRange = (val: number): LazyList => {
|
|
240
|
+
return new LazyList(() => {
|
|
241
|
+
return new StepCommand(
|
|
242
|
+
new LazyStepResult(new YuNumber(val), createLazyRange(val + 1)),
|
|
243
|
+
);
|
|
244
|
+
}, `Range(${val})`);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const lazyList = createLazyRange(1);
|
|
248
|
+
|
|
249
|
+
evaluator.evaluate = (node: any) => {
|
|
250
|
+
if (
|
|
251
|
+
node instanceof Variable &&
|
|
252
|
+
node.identifier.value === "Infinite"
|
|
253
|
+
) {
|
|
254
|
+
return new StepCommand(lazyList);
|
|
255
|
+
}
|
|
256
|
+
if (node instanceof SymbolPrimitive)
|
|
257
|
+
return new StepCommand(new YuString(node.value));
|
|
258
|
+
return new StepCommand(YuNil.getInstance());
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const infiniteVar = new Variable(s("Infinite"), new NilPrimitive(null));
|
|
262
|
+
const xVar = new Variable(s("X"), new NilPrimitive(null));
|
|
263
|
+
|
|
264
|
+
const result = kernel.run(
|
|
265
|
+
engine.unifyExpr(xVar, infiniteVar),
|
|
266
|
+
) as YuValue[];
|
|
267
|
+
expect(result[0].toJSON()).to.be.true;
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
describe("LogicEngine Execution", () => {
|
|
273
|
+
it("should solve a simple ground goal (Fact exists)", () => {
|
|
274
|
+
const query = makeGoal("parent", [lit("zeus"), lit("ares")]);
|
|
275
|
+
const results = kernel.run(engine.solveGoalLike(query)) as LogicResult[];
|
|
276
|
+
expect(results[0].success).to.be.true;
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it("should fail a ground goal that does not exist", () => {
|
|
280
|
+
const query = makeGoal("parent", [lit("zeus"), lit("thor")]);
|
|
281
|
+
const results = kernel.run(engine.solveGoalLike(query)) as LogicResult[];
|
|
282
|
+
expect(results).to.be.empty;
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it("should solve a goal with a variable", () => {
|
|
286
|
+
const goal = makeGoal("parent", [lit("zeus"), varPat("Child")]);
|
|
287
|
+
const query = new Query([goal]);
|
|
288
|
+
const results = kernel.run(engine.solveQuery(query)) as LogicResult[];
|
|
289
|
+
|
|
290
|
+
expect(results.every((res) => res.allSuccessful())).to.be.true;
|
|
291
|
+
|
|
292
|
+
const names = results.map((res) =>
|
|
293
|
+
(res.solutions.get("Child") as ConstantTerm).value.toJSON(),
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
expect(names).to.include("ares");
|
|
297
|
+
expect(names).to.include("athena");
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it("should solve a rule using backtracking", () => {
|
|
301
|
+
const query = makeGoal("sibling", [lit("ares"), lit("athena")]);
|
|
302
|
+
const results = kernel.run(engine.solveGoalLike(query)) as LogicResult[];
|
|
303
|
+
expect(results[0].success).to.be.true;
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("should solve a rule using backtracking with variable", () => {
|
|
308
|
+
const goal = makeGoal("sibling", [lit("ares"), varPat("Child")]);
|
|
309
|
+
const query = new Query([goal]);
|
|
310
|
+
const results = kernel.run(engine.solveQuery(query)) as LogicResult[];
|
|
311
|
+
expect(results.every((res) => res.allSuccessful())).to.be.true;
|
|
312
|
+
const names = results.map((res) =>
|
|
313
|
+
(res.solutions.get("Child") as ConstantTerm).value.toJSON(),
|
|
314
|
+
);
|
|
315
|
+
expect(names).to.include("ares");
|
|
316
|
+
expect(names).to.include("athena");
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
describe("Output Modes", () => {
|
|
320
|
+
it('should return all results when outputMode is "all"', () => {
|
|
321
|
+
const goal = makeGoal("parent", [lit("zeus"), varPat("X")]);
|
|
322
|
+
const query = new Query([goal]);
|
|
323
|
+
const results = kernel.run(engine.solveQuery(query)) as LogicResult[];
|
|
324
|
+
expect(results[0]).to.be.instanceOf(LogicResult);
|
|
325
|
+
expect(results[1]).to.be.instanceOf(LogicResult);
|
|
326
|
+
const names = results.map((res) =>
|
|
327
|
+
(res.solutions.get("X") as ConstantTerm).value.toJSON(),
|
|
328
|
+
);
|
|
329
|
+
expect(names).to.include("ares");
|
|
330
|
+
expect(names).to.include("athena");
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
describe("Findall", () => {
|
|
335
|
+
it("should collect all solutions into a list", () => {
|
|
336
|
+
const findallNode = new Findall(
|
|
337
|
+
varPat("X"),
|
|
338
|
+
makeGoal("parent", [lit("zeus"), varPat("X")]),
|
|
339
|
+
varPat("List"),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const queryNode = new Query([findallNode]);
|
|
343
|
+
const results = kernel.run(engine.solveQuery(queryNode)) as LogicResult[];
|
|
344
|
+
const firstResult = results[0];
|
|
345
|
+
expect(firstResult.allSuccessful()).to.be.true;
|
|
346
|
+
|
|
347
|
+
const answer = firstResult.allAnswers[0];
|
|
348
|
+
const solution = answer.getSolution();
|
|
349
|
+
|
|
350
|
+
const list = solution.get("List") as ListTerm;
|
|
351
|
+
expect(list).to.not.be.undefined;
|
|
352
|
+
|
|
353
|
+
const names = list.elements.map((el) =>
|
|
354
|
+
(el as ConstantTerm).value.toJSON(),
|
|
355
|
+
);
|
|
356
|
+
expect(names).to.have.lengthOf(2);
|
|
357
|
+
expect(names).to.include("ares");
|
|
358
|
+
expect(names).to.include("athena");
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
describe("Expression Unification", () => {
|
|
362
|
+
it("should successfully unify a variable with an array expression", () => {
|
|
363
|
+
globalEnv.head.set("myList", new YuString("dummy"));
|
|
364
|
+
const X = new Variable(s("X"), new NilPrimitive(null));
|
|
365
|
+
const myList = new Variable(s("myList"), new NilPrimitive(null));
|
|
366
|
+
const result = kernel.run(engine.unifyExpr(X, myList)) as YuValue[];
|
|
367
|
+
expect(result[0].toJSON()).to.be.true;
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
});
|