yukigo-prolog-parser 0.1.0 → 0.1.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.
@@ -4,31 +4,32 @@
4
4
  // @ts-ignore
5
5
  function id(d: any[]): any { return d[0]; }
6
6
  declare var period: any;
7
+ declare var testKeyword: any;
8
+ declare var lparen: any;
9
+ declare var rparen: any;
10
+ declare var comma: any;
7
11
  declare var colonDash: any;
8
12
  declare var queryOp: any;
9
- declare var comma: any;
10
13
  declare var semicolon: any;
11
14
  declare var forallRule: any;
12
15
  declare var findallRule: any;
13
- declare var notOperator: any;
14
- declare var lparen: any;
15
- declare var rparen: any;
16
16
  declare var consOp: any;
17
17
  declare var wildcard: any;
18
18
  declare var variable: any;
19
19
  declare var atom: any;
20
+ declare var primitiveOperator: any;
20
21
  declare var op: any;
21
22
  declare var comparisonOp: any;
22
23
  declare var number: any;
23
24
  declare var string: any;
24
25
  declare var WS: any;
25
-
26
- import {
26
+ import {
27
27
  NumberPrimitive,
28
28
  StringPrimitive,
29
29
  Rule,
30
30
  Fact,
31
31
  Query,
32
+ ListPrimitive,
32
33
  ConsExpression,
33
34
  ArithmeticBinaryOperation,
34
35
  ArithmeticUnaryOperation,
@@ -37,6 +38,8 @@ import {
37
38
  Not,
38
39
  Findall,
39
40
  Sequence,
41
+ UnguardedBody,
42
+ Equation,
40
43
  If,
41
44
  Call,
42
45
  Forall,
@@ -47,14 +50,22 @@ import {
47
50
  FunctorPattern,
48
51
  ConsPattern,
49
52
  ListPattern,
53
+ LogicConstraint,
50
54
  LiteralPattern,
51
55
  WildcardPattern,
52
- TuplePattern
56
+ TuplePattern,
57
+ Test,
58
+ Assert,
59
+ Truth
53
60
  } from "yukigo-ast"
54
61
 
55
62
  import { PrologLexer } from "./lexer.js"
56
63
 
57
- const asSequence = (d) => d.length === 1 ? d[0] : new Sequence(d);
64
+ const asSequence = (d) => {
65
+ if (d instanceof Sequence) return d;
66
+ if (Array.isArray(d)) return d.length === 1 ? d[0] : new Sequence(d);
67
+ return new Sequence([d]);
68
+ };
58
69
 
59
70
 
60
71
  interface NearleyToken {
@@ -90,17 +101,23 @@ const grammar: Grammar = {
90
101
  {"name": "program$ebnf$1", "symbols": []},
91
102
  {"name": "program$ebnf$1$subexpression$1", "symbols": ["clause", "_"]},
92
103
  {"name": "program$ebnf$1", "symbols": ["program$ebnf$1", "program$ebnf$1$subexpression$1"], "postprocess": (d) => d[0].concat([d[1]])},
93
- {"name": "program", "symbols": ["program$ebnf$1"], "postprocess": (d) => d[0].map(x => x[0]).filter(x => x !== null).flat(Infinity)},
104
+ {"name": "program", "symbols": ["_", "program$ebnf$1"], "postprocess": (d) => d[1].map(x => x[0]).filter(x => x !== null).flat(Infinity)},
94
105
  {"name": "clause$subexpression$1", "symbols": ["fact"]},
95
106
  {"name": "clause$subexpression$1", "symbols": ["rule"]},
96
107
  {"name": "clause$subexpression$1", "symbols": ["query"]},
108
+ {"name": "clause$subexpression$1", "symbols": ["test_rule"]},
97
109
  {"name": "clause", "symbols": ["clause$subexpression$1"], "postprocess": (d) => d[0][0]},
98
110
  {"name": "fact$ebnf$1", "symbols": ["arguments"], "postprocess": id},
99
111
  {"name": "fact$ebnf$1", "symbols": [], "postprocess": () => null},
100
112
  {"name": "fact", "symbols": ["any_atom", "fact$ebnf$1", "_", (PrologLexer.has("period") ? {type: "period"} : period)], "postprocess": (d) => new Fact(d[0], d[1] ?? [])},
101
- {"name": "rule$ebnf$1", "symbols": ["arguments"], "postprocess": id},
102
- {"name": "rule$ebnf$1", "symbols": [], "postprocess": () => null},
103
- {"name": "rule", "symbols": ["any_atom", "rule$ebnf$1", "_", (PrologLexer.has("colonDash") ? {type: "colonDash"} : colonDash), "_", "body", "_", (PrologLexer.has("period") ? {type: "period"} : period)], "postprocess": (d) => new Rule(d[0], d[1] ?? [], d[5])},
113
+ {"name": "rule", "symbols": ["any_atom", "equation", "_", (PrologLexer.has("period") ? {type: "period"} : period)], "postprocess": (d) => new Rule(d[0], [d[1]])},
114
+ {"name": "test_rule$ebnf$1", "symbols": ["test_args"], "postprocess": id},
115
+ {"name": "test_rule$ebnf$1", "symbols": [], "postprocess": () => null},
116
+ {"name": "test_rule", "symbols": [(PrologLexer.has("testKeyword") ? {type: "testKeyword"} : testKeyword), (PrologLexer.has("lparen") ? {type: "lparen"} : lparen), "_", "structural_literal", "test_rule$ebnf$1", "_", (PrologLexer.has("rparen") ? {type: "rparen"} : rparen), "equation", "_", (PrologLexer.has("period") ? {type: "period"} : period)], "postprocess": (d) => new Test(d[3], d[7].body.sequence, d[4] ? [d[4]] : [])},
117
+ {"name": "test_args", "symbols": ["_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "pattern"], "postprocess": (d) => d[3]},
118
+ {"name": "equation$ebnf$1", "symbols": ["arguments"], "postprocess": id},
119
+ {"name": "equation$ebnf$1", "symbols": [], "postprocess": () => null},
120
+ {"name": "equation", "symbols": ["equation$ebnf$1", "_", (PrologLexer.has("colonDash") ? {type: "colonDash"} : colonDash), "_", "body"], "postprocess": (d) => new Equation(d[0] || [], new UnguardedBody(new Sequence(d[4])))},
104
121
  {"name": "query", "symbols": [(PrologLexer.has("queryOp") ? {type: "queryOp"} : queryOp), "_", "body", "_", (PrologLexer.has("period") ? {type: "period"} : period)], "postprocess": (d) => new Query(d[2])},
105
122
  {"name": "body$ebnf$1", "symbols": []},
106
123
  {"name": "body$ebnf$1$subexpression$1$subexpression$1", "symbols": [(PrologLexer.has("comma") ? {type: "comma"} : comma)]},
@@ -116,19 +133,20 @@ const grammar: Grammar = {
116
133
  {"name": "expression$subexpression$1", "symbols": ["comparison"]},
117
134
  {"name": "expression$subexpression$1", "symbols": ["not"]},
118
135
  {"name": "expression$subexpression$1", "symbols": ["exist"]},
136
+ {"name": "expression$subexpression$1", "symbols": ["assertion"]},
119
137
  {"name": "expression", "symbols": ["expression$subexpression$1"], "postprocess": (d) => d[0][0]},
120
- {"name": "expression", "symbols": [{"literal":"("}, "_", "expression", "_", {"literal":")"}], "postprocess": (d) => d[2]},
138
+ {"name": "expression", "symbols": [{"literal":"("}, "_", "body", "_", {"literal":")"}], "postprocess": (d) => new Sequence(d[2])},
121
139
  {"name": "conditional", "symbols": [{"literal":"("}, "_", "body", "_", {"literal":"->"}, "_", "body", "_", (PrologLexer.has("semicolon") ? {type: "semicolon"} : semicolon), "_", "body", "_", {"literal":")"}], "postprocess": (d) =>
122
140
  new If(
123
141
  asSequence(d[2]),
124
142
  asSequence(d[6]),
125
143
  asSequence(d[10])
126
- )
144
+ )
127
145
  },
128
146
  {"name": "forall", "symbols": [(PrologLexer.has("forallRule") ? {type: "forallRule"} : forallRule), {"literal":"("}, "_", "expression", "_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "expression", "_", {"literal":")"}], "postprocess": (d) => new Forall(d[3], d[7])},
129
- {"name": "findall", "symbols": [(PrologLexer.has("findallRule") ? {type: "findallRule"} : findallRule), {"literal":"("}, "_", "expression", "_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "expression", "_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "expression", "_", {"literal":")"}], "postprocess": (d) => new Findall(d[3], d[7], d[11])},
130
- {"name": "not", "symbols": [(PrologLexer.has("notOperator") ? {type: "notOperator"} : notOperator), "_", "expression"], "postprocess": (d) => new Not([d[2]])},
131
- {"name": "not", "symbols": [(PrologLexer.has("notOperator") ? {type: "notOperator"} : notOperator), "_", {"literal":"("}, "_", {"literal":"("}, "_", "body", "_", {"literal":")"}, "_", {"literal":")"}], "postprocess": (d) => new Not([asSequence(d[6])])},
147
+ {"name": "findall", "symbols": [(PrologLexer.has("findallRule") ? {type: "findallRule"} : findallRule), {"literal":"("}, "_", "pattern", "_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "expression", "_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "pattern", "_", {"literal":")"}], "postprocess": (d) => new Findall(d[3], d[7], d[11])},
148
+ {"name": "not", "symbols": [{"literal":"not"}, {"literal":"("}, "_", "expression", "_", {"literal":")"}], "postprocess": (d) => new Not(asSequence(d[3]))},
149
+ {"name": "not", "symbols": [{"literal":"\\+"}, "_", "expression"], "postprocess": (d) => new Not(d[2])},
132
150
  {"name": "exist", "symbols": [{"literal":"call"}, (PrologLexer.has("lparen") ? {type: "lparen"} : lparen), "_", "pattern_list", "_", (PrologLexer.has("rparen") ? {type: "rparen"} : rparen)], "postprocess": (d) => {
133
151
  const [callee, ...rest] = d[3]
134
152
  return new Call(callee.name, rest)
@@ -137,13 +155,20 @@ const grammar: Grammar = {
137
155
  {"name": "exist$ebnf$1", "symbols": [], "postprocess": () => null},
138
156
  {"name": "exist", "symbols": ["any_atom", "exist$ebnf$1"], "postprocess": (d, l, reject) => {
139
157
  const val = d[0].value;
140
- if (val === "not" || val === "\\+") return reject;
158
+ if (["not", "\\+", "call", "assertion"].includes(val)) return reject;
141
159
  return new Exist(d[0], d[1] ?? [])
142
160
  } },
143
161
  {"name": "exist", "symbols": ["variable"], "postprocess": (d) => new Exist(d[0], [])},
144
- {"name": "assignment", "symbols": ["addition", "_", {"literal":"is"}, "_", "addition"], "postprocess": (d) => new AssignOperation("Assign", d[0], d[4])},
145
- {"name": "unification", "symbols": ["addition", "_", {"literal":"="}, "_", "addition"], "postprocess": (d) => new UnifyOperation("Unify", d[0], d[4])},
146
- {"name": "comparison", "symbols": ["addition", "_", "comparison_op", "_", "addition"], "postprocess": (d) => new ComparisonOperation(d[2], d[0], d[4])},
162
+ {"name": "assertion", "symbols": [{"literal":"assertion"}, (PrologLexer.has("lparen") ? {type: "lparen"} : lparen), "_", "expression", "_", (PrologLexer.has("rparen") ? {type: "rparen"} : rparen)], "postprocess": (d) =>
163
+ new Assert(null, new Truth(asSequence(d[3])))
164
+ },
165
+ {"name": "assignment", "symbols": ["addition", "_", {"literal":"is"}, "_", "addition"], "postprocess": (d) =>
166
+ new LogicConstraint(new AssignOperation("Assign", d[0], d[4]))
167
+ },
168
+ {"name": "unification", "symbols": ["addition", "_", {"literal":"="}, "_", "addition"], "postprocess": (d) => new LogicConstraint(new UnifyOperation("Unify", d[0], d[4]))},
169
+ {"name": "comparison", "symbols": ["addition", "_", "comparison_op", "_", "addition"], "postprocess": (d) =>
170
+ new LogicConstraint(new ComparisonOperation(d[2], d[0], d[4]))
171
+ },
147
172
  {"name": "addition", "symbols": ["multiplication", "_", {"literal":"+"}, "_", "addition"], "postprocess": (d) => new ArithmeticBinaryOperation("Plus", d[0], d[4])},
148
173
  {"name": "addition", "symbols": ["multiplication", "_", {"literal":"-"}, "_", "addition"], "postprocess": (d) => new ArithmeticBinaryOperation("Minus", d[0], d[4])},
149
174
  {"name": "addition", "symbols": ["multiplication"], "postprocess": id},
@@ -152,14 +177,32 @@ const grammar: Grammar = {
152
177
  {"name": "multiplication", "symbols": ["primary"], "postprocess": id},
153
178
  {"name": "primary", "symbols": ["arithmetic_literal"], "postprocess": id},
154
179
  {"name": "primary", "symbols": ["variable"], "postprocess": id},
155
- {"name": "primary", "symbols": ["strict_atom", "arguments"], "postprocess": d => new Exist(d[0], d[1] ?? [])},
180
+ {"name": "primary", "symbols": [{"literal":"-"}, "_", "primary"], "postprocess": (d) => new ArithmeticUnaryOperation("Negation", d[2])},
181
+ {"name": "primary", "symbols": ["strict_atom", "arguments"], "postprocess": (d, l, reject) => {
182
+ const val = d[0].value;
183
+ if (["abs", "round", "sqrt", "max", "assertion"].includes(val)) return reject;
184
+ return new Exist(d[0], d[1] ?? [])
185
+ } },
156
186
  {"name": "primary", "symbols": ["primitiveOperation"], "postprocess": id},
157
187
  {"name": "primary", "symbols": ["cons_expr"], "postprocess": id},
188
+ {"name": "primary", "symbols": ["list_expr"], "postprocess": id},
158
189
  {"name": "primary", "symbols": [{"literal":"("}, "_", "addition", "_", {"literal":")"}], "postprocess": d => d[2]},
159
- {"name": "cons_expr", "symbols": [{"literal":"["}, "_", "primary_list", "_", (PrologLexer.has("consOp") ? {type: "consOp"} : consOp), "_", "expression", "_", {"literal":"]"}], "postprocess": (d) => new ConsExpression(d[2], d[6])},
190
+ {"name": "list_expr$ebnf$1", "symbols": ["primary_list"], "postprocess": id},
191
+ {"name": "list_expr$ebnf$1", "symbols": [], "postprocess": () => null},
192
+ {"name": "list_expr", "symbols": [{"literal":"["}, "_", "list_expr$ebnf$1", "_", {"literal":"]"}], "postprocess": (d) => new ListPrimitive(d[2] || [])},
193
+ {"name": "cons_expr", "symbols": [{"literal":"["}, "_", "primary_list", "_", (PrologLexer.has("consOp") ? {type: "consOp"} : consOp), "_", "addition", "_", {"literal":"]"}], "postprocess": (d) => {
194
+ const heads = d[2];
195
+ const tail = d[6];
196
+ let current = tail;
197
+ for (let i = heads.length - 1; i >= 0; i--) {
198
+ current = new ConsExpression(heads[i], current);
199
+ }
200
+ return current;
201
+ } },
160
202
  {"name": "primitiveOperation", "symbols": [{"literal":"round"}, "__", "addition"], "postprocess": d => new ArithmeticUnaryOperation("Round", d[2])},
161
203
  {"name": "primitiveOperation", "symbols": [{"literal":"abs"}, "__", "addition"], "postprocess": d => new ArithmeticUnaryOperation("Absolute", d[2])},
162
204
  {"name": "primitiveOperation", "symbols": [{"literal":"sqrt"}, "__", "addition"], "postprocess": d => new ArithmeticUnaryOperation("Sqrt", d[2])},
205
+ {"name": "primitiveOperation", "symbols": [{"literal":"max"}, {"literal":"("}, "_", "addition", "_", {"literal":","}, "_", "addition", "_", {"literal":")"}], "postprocess": d => new ArithmeticBinaryOperation("Max", d[3], d[7])},
163
206
  {"name": "primitiveArguments", "symbols": [(PrologLexer.has("lparen") ? {type: "lparen"} : lparen), "_", "primary_list", "_", (PrologLexer.has("rparen") ? {type: "rparen"} : rparen)], "postprocess": (d) => d[2]},
164
207
  {"name": "primary_list$ebnf$1", "symbols": []},
165
208
  {"name": "primary_list$ebnf$1$subexpression$1", "symbols": ["_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "addition"]},
@@ -170,18 +213,30 @@ const grammar: Grammar = {
170
213
  {"name": "pattern_list$ebnf$1$subexpression$1", "symbols": ["_", (PrologLexer.has("comma") ? {type: "comma"} : comma), "_", "pattern"]},
171
214
  {"name": "pattern_list$ebnf$1", "symbols": ["pattern_list$ebnf$1", "pattern_list$ebnf$1$subexpression$1"], "postprocess": (d) => d[0].concat([d[1]])},
172
215
  {"name": "pattern_list", "symbols": ["pattern", "pattern_list$ebnf$1"], "postprocess": (d) => [d[0], ...d[1].map(x => x[3])]},
173
- {"name": "pattern", "symbols": ["variable"], "postprocess": (d) => new VariablePattern(d[0])},
174
- {"name": "pattern", "symbols": ["structural_literal"], "postprocess": (d) => new LiteralPattern(d[0])},
175
- {"name": "pattern", "symbols": [(PrologLexer.has("wildcard") ? {type: "wildcard"} : wildcard)], "postprocess": (d) => new WildcardPattern()},
176
- {"name": "pattern", "symbols": ["any_atom", "arguments"], "postprocess": (d) => new FunctorPattern(d[0], d[1])},
177
- {"name": "pattern", "symbols": [{"literal":"("}, "_", "pattern_list", "_", {"literal":")"}], "postprocess": (d) => new TuplePattern(d[2])},
178
- {"name": "pattern", "symbols": [{"literal":"["}, "_", "pattern_list", "_", (PrologLexer.has("consOp") ? {type: "consOp"} : consOp), "_", "pattern", "_", {"literal":"]"}], "postprocess": (d) => new ConsPattern(d[2].length > 1 ? new ListPattern(d[2]) : d[2][0], new VariablePattern(d[6]))},
179
- {"name": "pattern$ebnf$1", "symbols": ["pattern_list"], "postprocess": id},
180
- {"name": "pattern$ebnf$1", "symbols": [], "postprocess": () => null},
181
- {"name": "pattern", "symbols": [{"literal":"["}, "_", "pattern$ebnf$1", "_", {"literal":"]"}], "postprocess": (d) => new ListPattern(d[2] ? d[2] : [])},
216
+ {"name": "pattern", "symbols": ["infix_pattern"], "postprocess": id},
217
+ {"name": "pattern", "symbols": ["primary_pattern"], "postprocess": id},
218
+ {"name": "primary_pattern", "symbols": ["variable"], "postprocess": (d) => new VariablePattern(d[0])},
219
+ {"name": "primary_pattern", "symbols": ["structural_literal"], "postprocess": (d) => new LiteralPattern(d[0])},
220
+ {"name": "primary_pattern", "symbols": [(PrologLexer.has("wildcard") ? {type: "wildcard"} : wildcard)], "postprocess": (d) => new WildcardPattern()},
221
+ {"name": "primary_pattern", "symbols": ["any_atom", "arguments"], "postprocess": (d) => new FunctorPattern(d[0], d[1])},
222
+ {"name": "primary_pattern", "symbols": [{"literal":"("}, "_", "pattern_list", "_", {"literal":")"}], "postprocess": (d) => new TuplePattern(d[2])},
223
+ {"name": "primary_pattern", "symbols": [{"literal":"["}, "_", "pattern_list", "_", (PrologLexer.has("consOp") ? {type: "consOp"} : consOp), "_", "pattern", "_", {"literal":"]"}], "postprocess": (d) => {
224
+ const heads = d[2];
225
+ const tail = d[6];
226
+ let current = tail;
227
+ for (let i = heads.length - 1; i >= 0; i--) {
228
+ current = new ConsPattern(heads[i], current);
229
+ }
230
+ return current;
231
+ } },
232
+ {"name": "primary_pattern$ebnf$1", "symbols": ["pattern_list"], "postprocess": id},
233
+ {"name": "primary_pattern$ebnf$1", "symbols": [], "postprocess": () => null},
234
+ {"name": "primary_pattern", "symbols": [{"literal":"["}, "_", "primary_pattern$ebnf$1", "_", {"literal":"]"}], "postprocess": (d) => new ListPattern(d[2] ? d[2] : [])},
235
+ {"name": "infix_pattern", "symbols": ["primary_pattern", "_", "any_atom", "_", "pattern"], "postprocess": (d) => new FunctorPattern(d[2], [d[0], d[4]])},
182
236
  {"name": "variable", "symbols": [(PrologLexer.has("variable") ? {type: "variable"} : variable)], "postprocess": (d) => new SymbolPrimitive(d[0].value)},
183
237
  {"name": "strict_atom", "symbols": [(PrologLexer.has("atom") ? {type: "atom"} : atom)], "postprocess": (d) => new SymbolPrimitive(d[0].value)},
184
- {"name": "any_atom$subexpression$1", "symbols": [(PrologLexer.has("atom") ? {type: "atom"} : atom)]},
238
+ {"name": "strict_atom", "symbols": [(PrologLexer.has("primitiveOperator") ? {type: "primitiveOperator"} : primitiveOperator)], "postprocess": (d) => new SymbolPrimitive(d[0].value)},
239
+ {"name": "any_atom", "symbols": ["strict_atom"], "postprocess": id},
185
240
  {"name": "any_atom$subexpression$1", "symbols": [(PrologLexer.has("op") ? {type: "op"} : op)]},
186
241
  {"name": "any_atom$subexpression$1", "symbols": [(PrologLexer.has("comparisonOp") ? {type: "comparisonOp"} : comparisonOp)]},
187
242
  {"name": "any_atom", "symbols": ["any_atom$subexpression$1"], "postprocess": (d) => new SymbolPrimitive(d[0][0].value)},
@@ -1,39 +1,40 @@
1
- import { makeLexer } from "moo-ignore";
2
- import moo from "moo";
3
- export const PrologLexerConfig = {
4
- WS: /[ \t]+/,
5
- wildcard: "_",
6
- notOperator: { match: ["\\+", "not"] },
7
- forallRule: "forall",
8
- findallRule: "findall",
9
- comment: /%.*|\/\*[\s\S]*?\*\//,
10
- number:
11
- /-?\b(?:[0-9]+(?:\.[0-9]+(?:e[+-]?[0-9]+)?)?|0o[0-7]+|0x[0-9a-fA-F]+|0b[01]+)\b/,
12
- string: /(?:'(?:[^']|'')*')/,
13
- backtick: "`",
14
- lparen: "(",
15
- rparen: ")",
16
- lbracket: "{",
17
- rbracket: "}",
18
- lsquare: "[",
19
- rsquare: "]",
20
- comma: ",",
21
- arrow: "->",
22
- period: ".",
23
- semicolon: ";",
24
- colonDash: ":-",
25
- consOp: "|",
26
- queryOp: "?-",
27
- comparisonOp: /@<|@=<|@>=|@>|<|=<|>=|>|=@=|\\=@=|=:=|=\\=|==|\\==|\\=|=/,
28
- op: /\+|-|\*|\/|\/\/|~|\^|\?|\$|''|\.\./,
29
- variable: /[A-Z][a-zA-Z0-9_]*/,
30
- atom: {
31
- match: /[a-z!][a-zA-Z0-9_]*/,
32
- type: moo.keywords({
33
- primitiveOperator: ["round", "abs", "sqrt", "call"],
34
- }),
35
- },
36
- NL: { match: /\r?\n/, lineBreaks: true },
37
- };
38
-
39
- export const PrologLexer = makeLexer(PrologLexerConfig, ["comment", "NL"]);
1
+ import { makeLexer } from "moo-ignore";
2
+ import moo from "moo";
3
+ export const PrologLexerConfig = {
4
+ WS: /[ \t]+/,
5
+ wildcard: "_",
6
+ notOperator: { match: ["\\+", "not"] },
7
+ forallRule: "forall",
8
+ findallRule: "findall",
9
+ comment: /%.*|\/\*[\s\S]*?\*\//,
10
+ number:
11
+ /\b(?:[0-9]+(?:\.[0-9]+(?:e[+-]?[0-9]+)?)?|0o[0-7]+|0x[0-9a-fA-F]+|0b[01]+)\b/,
12
+ string: /(?:'(?:[^']|'')*'|"(?:[^"]|"")*")/,
13
+ backtick: "`",
14
+ lparen: "(",
15
+ rparen: ")",
16
+ lbracket: "{",
17
+ rbracket: "}",
18
+ lsquare: "[",
19
+ rsquare: "]",
20
+ comma: ",",
21
+ arrow: "->",
22
+ period: ".",
23
+ semicolon: ";",
24
+ colonDash: ":-",
25
+ consOp: "|",
26
+ queryOp: "?-",
27
+ comparisonOp: /@<|@=<|@>=|@>|<|=<|>=|>|=@=|\\=@=|=:=|=\\=|==|\\==|\\=|=/,
28
+ op: /\+|-|\*|\/|\/\/|~|\^|\?|\$|''|\.\./,
29
+ variable: /[A-Z][a-zA-Z0-9_\u00C0-\u00FF]*/,
30
+ atom: {
31
+ match: /[a-z!][a-zA-Z0-9_\u00C0-\u00FF]*/,
32
+ type: moo.keywords({
33
+ primitiveOperator: ["round", "abs", "sqrt", "call", "max", "assertion"],
34
+ testKeyword: ["test"],
35
+ }),
36
+ },
37
+ NL: { match: /\r?\n/, lineBreaks: true },
38
+ };
39
+
40
+ export const PrologLexer = makeLexer(PrologLexerConfig, ["comment", "NL"]);
@@ -1,119 +1,132 @@
1
- % between(+Low, +High, ?Value)
2
- % True if Low =< Value =< High (assuming integers)
3
- between(Low, High, Low) :- Low =< High.
4
- between(Low, High, Value) :-
5
- Low < High,
6
- NextLow is Low + 1,
7
- between(NextLow, High, Value).
8
-
9
- % union(+List1, +List2, -Union)
10
- % Union of two lists without duplicates (order not preserved)
11
- union([], L, L).
12
- union([H|T], L2, Union) :-
13
- ( member(H, L2)
14
- -> union(T, L2, Union)
15
- ; Union = [H|Rest],
16
- union(T, L2, Rest)
17
- ).
18
-
19
- % intersection(+List1, +List2, -Intersection)
20
- intersection([], _, []).
21
- intersection([H|T], L2, [H|Rest]) :-
22
- member(H, L2),
23
- !,
24
- intersection(T, L2, Rest).
25
- intersection([_|T], L2, Rest) :-
26
- intersection(T, L2, Rest).
27
-
28
- % max_member(-Max, +List)
29
- max_member(Max, [Max]) :- !.
30
- max_member(Max, [H|T]) :-
31
- max_member(M, T),
32
- ( H > M
33
- -> Max = H
34
- ; Max = M
35
- ).
36
-
37
- % min_member(-Min, +List)
38
- min_member(Min, [Min]) :- !.
39
- min_member(Min, [H|T]) :-
40
- min_member(M, T),
41
- ( H < M
42
- -> Min = H
43
- ; Min = M
44
- ).
45
-
46
- % sumlist(+List, -Sum)
47
- sumlist([], 0).
48
- sumlist([H|T], Sum) :-
49
- sumlist(T, RestSum),
50
- Sum is H + RestSum.
51
-
52
- % length(?List, ?Length)
53
- length([], 0).
54
- length([_|Tail], N) :-
55
- length(Tail, M),
56
- N is M + 1.
57
-
58
- % flatten(+NestedList, -FlatList)
59
- flatten([], []).
60
- flatten([H|T], Flat) :-
61
- !,
62
- flatten(H, FlatH),
63
- flatten(T, FlatT),
64
- append(FlatH, FlatT, Flat).
65
- flatten(X, [X]).
66
-
67
- % reverse(+List, -Reversed)
68
- reverse(List, Reversed) :-
69
- reverse_acc(List, [], Reversed).
70
-
71
- reverse_acc([], Acc, Acc).
72
- reverse_acc([H|T], Acc, Reversed) :-
73
- reverse_acc(T, [H|Acc], Reversed).
74
-
75
- % list_to_set(+List, -Set)
76
- % Removes duplicates, keeps first occurrence
77
- list_to_set([], []).
78
- list_to_set([H|T], [H|Rest]) :-
79
- exclude(==(H), T, T1),
80
- list_to_set(T1, Rest).
81
-
82
- ==(H, T) :-
83
- H == T.
84
-
85
- % nth0(?Index, ?List, ?Elem)
86
- % Index starts at 0
87
- nth0(0, [H|_], H).
88
- nth0(N, [_|T], Elem) :-
89
- N > 0,
90
- N1 is N - 1,
91
- nth0(N1, T, Elem).
92
-
93
- % nth1(?Index, ?List, ?Elem)
94
- % Index starts at 1
95
- nth1(1, [H|_], H).
96
- nth1(N, [_|T], Elem) :-
97
- N > 1,
98
- N1 is N - 1,
99
- nth1(N1, T, Elem).
100
-
101
- % append/3 (needed for flatten and union)
102
- append([], L, L).
103
- append([H|T], L, [H|R]) :-
104
- append(T, L, R).
105
-
106
- % member/2 (needed for many predicates)
107
- member(H, [H|_]).
108
- member(H, [_|T]) :-
109
- member(H, T).
110
-
111
- % exclude(+Pred, +List, -Filtered)
112
- % Removes elements satisfying Pred
113
- exclude(_, [], []).
114
- exclude(Pred, [H|T], Rest) :-
115
- ( call(Pred, H)
116
- -> exclude(Pred, T, Rest)
117
- ; Rest = [H|Rest2],
118
- exclude(Pred, T, Rest2)
119
- ).
1
+ export const stdCode = `
2
+ % between(+Low, +High, ?Value)
3
+ % True if Low =< Value =< High (assuming integers)
4
+ between(Low, High, Low) :- Low =< High.
5
+ between(Low, High, Value) :-
6
+ Low < High,
7
+ NextLow is Low + 1,
8
+ between(NextLow, High, Value).
9
+
10
+ % union(+List1, +List2, -Union)
11
+ % Union of two lists without duplicates (order not preserved)
12
+ union([], L, L).
13
+ union([H|T], L2, Union) :-
14
+ ( member(H, L2)
15
+ -> union(T, L2, Union)
16
+ ; Union = [H|Rest],
17
+ union(T, L2, Rest)
18
+ ).
19
+
20
+ % intersection(+List1, +List2, -Intersection)
21
+ intersection([], _, []).
22
+ intersection([H|T], L2, [H|Rest]) :-
23
+ member(H, L2),
24
+ !,
25
+ intersection(T, L2, Rest).
26
+ intersection([_|T], L2, Rest) :-
27
+ intersection(T, L2, Rest).
28
+
29
+ % max_member(-Max, +List)
30
+ max_member(Max, [Max]) :- !.
31
+ max_member(Max, [H|T]) :-
32
+ max_member(M, T),
33
+ ( H > M
34
+ -> Max = H
35
+ ; Max = M
36
+ ).
37
+
38
+ % min_member(-Min, +List)
39
+ min_member(Min, [Min]) :- !.
40
+ min_member(Min, [H|T]) :-
41
+ min_member(M, T),
42
+ ( H < M
43
+ -> Min = H
44
+ ; Min = M
45
+ ).
46
+
47
+ % sumlist(+List, -Sum)
48
+ sumlist([], 0).
49
+ sumlist([H|T], Sum) :-
50
+ sumlist(T, RestSum),
51
+ Sum is H + RestSum.
52
+
53
+ % length(?List, ?Length)
54
+ length([], 0).
55
+ length([_|Tail], N) :-
56
+ length(Tail, M),
57
+ N is M + 1.
58
+
59
+ % flatten(+NestedList, -FlatList)
60
+ flatten([], []).
61
+ flatten([H|T], Flat) :-
62
+ !,
63
+ flatten(H, FlatH),
64
+ flatten(T, FlatT),
65
+ append(FlatH, FlatT, Flat).
66
+ flatten(X, [X]).
67
+
68
+ % reverse(+List, -Reversed)
69
+ reverse(List, Reversed) :-
70
+ reverse_acc(List, [], Reversed).
71
+
72
+ reverse_acc([], Acc, Acc).
73
+ reverse_acc([H|T], Acc, Reversed) :-
74
+ reverse_acc(T, [H|Acc], Reversed).
75
+
76
+ % list_to_set(+List, -Set)
77
+ % Removes duplicates, keeps first occurrence
78
+ list_to_set([], []).
79
+ list_to_set([H|T], [H|Rest]) :-
80
+ exclude(==(H), T, T1),
81
+ list_to_set(T1, Rest).
82
+
83
+ ==(H, T) :-
84
+ H == T.
85
+
86
+ % nth0(?Index, ?List, ?Elem)
87
+ % Index starts at 0
88
+ nth0(0, [H|_], H).
89
+ nth0(N, [_|T], Elem) :-
90
+ N > 0,
91
+ N1 is N - 1,
92
+ nth0(N1, T, Elem).
93
+
94
+ % nth1(?Index, ?List, ?Elem)
95
+ % Index starts at 1
96
+ nth1(1, [H|_], H).
97
+ nth1(N, [_|T], Elem) :-
98
+ N > 1,
99
+ N1 is N - 1,
100
+ nth1(N1, T, Elem).
101
+
102
+ % append/3 (needed for flatten and union)
103
+ append([], L, L).
104
+ append([H|T], L, [H|R]) :-
105
+ append(T, L, R).
106
+
107
+ % member/2 (needed for many predicates)
108
+ member(H, [H|_]).
109
+ member(H, [_|T]) :-
110
+ member(H, T).
111
+
112
+ % exclude(+Pred, +List, -Filtered)
113
+ % Removes elements satisfying Pred
114
+ exclude(_, [], []).
115
+ exclude(Pred, [H|T], Rest) :-
116
+ ( call(Pred, H)
117
+ -> exclude(Pred, T, Rest)
118
+ ; Rest = [H|Rest2],
119
+ exclude(Pred, T, Rest2)
120
+ ).
121
+
122
+ % Arithmetic predicates
123
+ abs(X, Y) :- Y is abs(X).
124
+ round(X, Y) :- Y is round(X).
125
+ sqrt(X, Y) :- Y is sqrt(X).
126
+
127
+
128
+ max_list([X], X).
129
+ max_list([H|T], Max) :-
130
+ max_list(T, MaxTail),
131
+ Max is max(H, MaxTail).
132
+ `