eyeling 1.15.4 → 1.15.5

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.
@@ -0,0 +1,92 @@
1
+ # ================================================================
2
+ # Symbolic FFT
3
+ #
4
+ # Relation signatures:
5
+ #
6
+ # ((samples) v p n) :eval expr.
7
+ # ((a0 a1 a2 a3 a4 a5 a6 a7) x0 x1 x2 x3 x4 x5 x6 x7) :fft true.
8
+ #
9
+ # Expression encoding:
10
+ #
11
+ # a(I) -> (:a I)
12
+ # w^P -> (:pow :w P)
13
+ # A1 + w^P * A2 -> (:plus A1 (:times (:pow :w P) A2))
14
+ # ================================================================
15
+
16
+ @prefix : <http://example.org/fft#>.
17
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
18
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
19
+
20
+ # Base case: a singleton list evaluates to a(I).
21
+ { ((?i) ?v ?p ?n) :eval (:a ?i). } <= {}.
22
+
23
+ # Length 2
24
+ {
25
+ ((?i0 ?i1) ?v ?p ?n) :eval
26
+ (:plus ?a1 (:times (:pow ?v ?p) ?a2)).
27
+ }
28
+ <=
29
+ {
30
+ (?p 2) math:product ?pp.
31
+ (?pp ?n) math:remainder ?p1.
32
+
33
+ ((?i0) ?v ?p1 ?n) :eval ?a1.
34
+ ((?i1) ?v ?p1 ?n) :eval ?a2.
35
+ }.
36
+
37
+ # Length 4: alternate [0,2] and [1,3]
38
+ {
39
+ ((?i0 ?i1 ?i2 ?i3) ?v ?p ?n) :eval
40
+ (:plus ?a1 (:times (:pow ?v ?p) ?a2)).
41
+ }
42
+ <=
43
+ {
44
+ (?p 2) math:product ?pp.
45
+ (?pp ?n) math:remainder ?p1.
46
+
47
+ ((?i0 ?i2) ?v ?p1 ?n) :eval ?a1.
48
+ ((?i1 ?i3) ?v ?p1 ?n) :eval ?a2.
49
+ }.
50
+
51
+ # Length 8: alternate [0,2,4,6] and [1,3,5,7]
52
+ {
53
+ ((?i0 ?i1 ?i2 ?i3 ?i4 ?i5 ?i6 ?i7) ?v ?p ?n) :eval
54
+ (:plus ?a1 (:times (:pow ?v ?p) ?a2)).
55
+ }
56
+ <=
57
+ {
58
+ (?p 2) math:product ?pp.
59
+ (?pp ?n) math:remainder ?p1.
60
+
61
+ ((?i0 ?i2 ?i4 ?i6) ?v ?p1 ?n) :eval ?a1.
62
+ ((?i1 ?i3 ?i5 ?i7) ?v ?p1 ?n) :eval ?a2.
63
+ }.
64
+
65
+ # The original Prolog fft/2 calls eval at powers w^0 .. w^7 for N = 8.
66
+ {
67
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7)
68
+ ?x0 ?x1 ?x2 ?x3 ?x4 ?x5 ?x6 ?x7) :fft true.
69
+ }
70
+ <=
71
+ {
72
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 0 8) :eval ?x0.
73
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 1 8) :eval ?x1.
74
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 2 8) :eval ?x2.
75
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 3 8) :eval ?x3.
76
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 4 8) :eval ?x4.
77
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 5 8) :eval ?x5.
78
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 6 8) :eval ?x6.
79
+ ((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :w 7 8) :eval ?x7.
80
+ }.
81
+
82
+ {
83
+ ((0 1 2 3 4 5 6 7)
84
+ ?x0 ?x1 ?x2 ?x3 ?x4 ?x5 ?x6 ?x7) :fft true.
85
+ }
86
+ log:query
87
+ {
88
+ :result :fft (
89
+ ?x0 ?x1 ?x2 ?x3
90
+ ?x4 ?x5 ?x6 ?x7
91
+ ).
92
+ }.
@@ -0,0 +1,3 @@
1
+ @prefix : <http://example.org/fft#> .
2
+
3
+ :result :fft ((:plus (:plus (:plus (:a 0) (:times (:pow :w 0) (:a 4))) (:times (:pow :w 0) (:plus (:a 2) (:times (:pow :w 0) (:a 6))))) (:times (:pow :w 0) (:plus (:plus (:a 1) (:times (:pow :w 0) (:a 5))) (:times (:pow :w 0) (:plus (:a 3) (:times (:pow :w 0) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 4) (:a 4))) (:times (:pow :w 2) (:plus (:a 2) (:times (:pow :w 4) (:a 6))))) (:times (:pow :w 1) (:plus (:plus (:a 1) (:times (:pow :w 4) (:a 5))) (:times (:pow :w 2) (:plus (:a 3) (:times (:pow :w 4) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 0) (:a 4))) (:times (:pow :w 4) (:plus (:a 2) (:times (:pow :w 0) (:a 6))))) (:times (:pow :w 2) (:plus (:plus (:a 1) (:times (:pow :w 0) (:a 5))) (:times (:pow :w 4) (:plus (:a 3) (:times (:pow :w 0) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 4) (:a 4))) (:times (:pow :w 6) (:plus (:a 2) (:times (:pow :w 4) (:a 6))))) (:times (:pow :w 3) (:plus (:plus (:a 1) (:times (:pow :w 4) (:a 5))) (:times (:pow :w 6) (:plus (:a 3) (:times (:pow :w 4) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 0) (:a 4))) (:times (:pow :w 0) (:plus (:a 2) (:times (:pow :w 0) (:a 6))))) (:times (:pow :w 4) (:plus (:plus (:a 1) (:times (:pow :w 0) (:a 5))) (:times (:pow :w 0) (:plus (:a 3) (:times (:pow :w 0) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 4) (:a 4))) (:times (:pow :w 2) (:plus (:a 2) (:times (:pow :w 4) (:a 6))))) (:times (:pow :w 5) (:plus (:plus (:a 1) (:times (:pow :w 4) (:a 5))) (:times (:pow :w 2) (:plus (:a 3) (:times (:pow :w 4) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 0) (:a 4))) (:times (:pow :w 4) (:plus (:a 2) (:times (:pow :w 0) (:a 6))))) (:times (:pow :w 6) (:plus (:plus (:a 1) (:times (:pow :w 0) (:a 5))) (:times (:pow :w 4) (:plus (:a 3) (:times (:pow :w 0) (:a 7))))))) (:plus (:plus (:plus (:a 0) (:times (:pow :w 4) (:a 4))) (:times (:pow :w 6) (:plus (:a 2) (:times (:pow :w 4) (:a 6))))) (:times (:pow :w 7) (:plus (:plus (:a 1) (:times (:pow :w 4) (:a 5))) (:times (:pow :w 6) (:plus (:a 3) (:times (:pow :w 4) (:a 7)))))))) .
package/eyeling.js CHANGED
@@ -8606,6 +8606,22 @@ function assertValidQNamePrefix(prefixName, fail, tok, context = 'prefixed name'
8606
8606
  }
8607
8607
  }
8608
8608
 
8609
+ function isKeywordLikeIdent(name) {
8610
+ return (
8611
+ name === 'a' ||
8612
+ name === 'has' ||
8613
+ name === 'is' ||
8614
+ name === 'of' ||
8615
+ name === 'true' ||
8616
+ name === 'false' ||
8617
+ name === 'id'
8618
+ );
8619
+ }
8620
+
8621
+ function failInvalidKeywordLikeIdent(fail, tok, name) {
8622
+ fail(`invalid_keyword(${name})`, tok);
8623
+ }
8624
+
8609
8625
  class Parser {
8610
8626
  constructor(tokens) {
8611
8627
  this.toks = tokens;
@@ -8795,7 +8811,10 @@ class Parser {
8795
8811
  if (tok2.typ === 'IriRef') {
8796
8812
  iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
8797
8813
  } else if (tok2.typ === 'Ident') {
8798
- iri = this.prefixes.expandQName(tok2.value || '');
8814
+ const qn = tok2.value || '';
8815
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
8816
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
8817
+ iri = this.prefixes.expandQName(qn);
8799
8818
  } else {
8800
8819
  this.fail(`Expected IRI after @prefix, got ${tok2.toString()}`, tok2);
8801
8820
  }
@@ -8809,7 +8828,10 @@ class Parser {
8809
8828
  if (tok.typ === 'IriRef') {
8810
8829
  iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
8811
8830
  } else if (tok.typ === 'Ident') {
8812
- iri = tok.value || '';
8831
+ const qn = tok.value || '';
8832
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
8833
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, '@base directive IRI');
8834
+ iri = this.prefixes.expandQName(qn);
8813
8835
  } else {
8814
8836
  this.fail(`Expected IRI after @base, got ${tok.toString()}`, tok);
8815
8837
  }
@@ -8835,7 +8857,10 @@ class Parser {
8835
8857
  if (tok2.typ === 'IriRef') {
8836
8858
  iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
8837
8859
  } else if (tok2.typ === 'Ident') {
8838
- iri = this.prefixes.expandQName(tok2.value || '');
8860
+ const qn = tok2.value || '';
8861
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
8862
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
8863
+ iri = this.prefixes.expandQName(qn);
8839
8864
  } else {
8840
8865
  this.fail(`Expected IRI after PREFIX, got ${tok2.toString()}`, tok2);
8841
8866
  }
@@ -8853,7 +8878,10 @@ class Parser {
8853
8878
  if (tok.typ === 'IriRef') {
8854
8879
  iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
8855
8880
  } else if (tok.typ === 'Ident') {
8856
- iri = tok.value || '';
8881
+ const qn = tok.value || '';
8882
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
8883
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, 'BASE directive IRI');
8884
+ iri = this.prefixes.expandQName(qn);
8857
8885
  } else {
8858
8886
  this.fail(`Expected IRI after BASE, got ${tok.toString()}`, tok);
8859
8887
  }
@@ -8905,7 +8933,7 @@ class Parser {
8905
8933
  assertValidQNamePrefix(name.split(':', 1)[0], this.fail.bind(this), tok);
8906
8934
  return internIri(this.prefixes.expandQName(name));
8907
8935
  } else {
8908
- return internIri(name);
8936
+ failInvalidKeywordLikeIdent(this.fail.bind(this), tok, name);
8909
8937
  }
8910
8938
  }
8911
8939
 
@@ -8936,10 +8964,9 @@ class Parser {
8936
8964
  dtIri = dtTok.value || '';
8937
8965
  } else if (dtTok.typ === 'Ident') {
8938
8966
  const qn = dtTok.value || '';
8939
- if (qn.includes(':')) {
8940
- assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), dtTok, 'datatype prefixed name');
8941
- dtIri = this.prefixes.expandQName(qn);
8942
- } else dtIri = qn;
8967
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), dtTok, qn);
8968
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), dtTok, 'datatype prefixed name');
8969
+ dtIri = this.prefixes.expandQName(qn);
8943
8970
  } else {
8944
8971
  this.fail(`Expected datatype after ^^, got ${dtTok.toString()}`, dtTok);
8945
8972
  }
package/lib/parser.js CHANGED
@@ -37,6 +37,22 @@ function assertValidQNamePrefix(prefixName, fail, tok, context = 'prefixed name'
37
37
  }
38
38
  }
39
39
 
40
+ function isKeywordLikeIdent(name) {
41
+ return (
42
+ name === 'a' ||
43
+ name === 'has' ||
44
+ name === 'is' ||
45
+ name === 'of' ||
46
+ name === 'true' ||
47
+ name === 'false' ||
48
+ name === 'id'
49
+ );
50
+ }
51
+
52
+ function failInvalidKeywordLikeIdent(fail, tok, name) {
53
+ fail(`invalid_keyword(${name})`, tok);
54
+ }
55
+
40
56
  class Parser {
41
57
  constructor(tokens) {
42
58
  this.toks = tokens;
@@ -226,7 +242,10 @@ class Parser {
226
242
  if (tok2.typ === 'IriRef') {
227
243
  iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
228
244
  } else if (tok2.typ === 'Ident') {
229
- iri = this.prefixes.expandQName(tok2.value || '');
245
+ const qn = tok2.value || '';
246
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
247
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
248
+ iri = this.prefixes.expandQName(qn);
230
249
  } else {
231
250
  this.fail(`Expected IRI after @prefix, got ${tok2.toString()}`, tok2);
232
251
  }
@@ -240,7 +259,10 @@ class Parser {
240
259
  if (tok.typ === 'IriRef') {
241
260
  iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
242
261
  } else if (tok.typ === 'Ident') {
243
- iri = tok.value || '';
262
+ const qn = tok.value || '';
263
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
264
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, '@base directive IRI');
265
+ iri = this.prefixes.expandQName(qn);
244
266
  } else {
245
267
  this.fail(`Expected IRI after @base, got ${tok.toString()}`, tok);
246
268
  }
@@ -266,7 +288,10 @@ class Parser {
266
288
  if (tok2.typ === 'IriRef') {
267
289
  iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
268
290
  } else if (tok2.typ === 'Ident') {
269
- iri = this.prefixes.expandQName(tok2.value || '');
291
+ const qn = tok2.value || '';
292
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
293
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
294
+ iri = this.prefixes.expandQName(qn);
270
295
  } else {
271
296
  this.fail(`Expected IRI after PREFIX, got ${tok2.toString()}`, tok2);
272
297
  }
@@ -284,7 +309,10 @@ class Parser {
284
309
  if (tok.typ === 'IriRef') {
285
310
  iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
286
311
  } else if (tok.typ === 'Ident') {
287
- iri = tok.value || '';
312
+ const qn = tok.value || '';
313
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
314
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, 'BASE directive IRI');
315
+ iri = this.prefixes.expandQName(qn);
288
316
  } else {
289
317
  this.fail(`Expected IRI after BASE, got ${tok.toString()}`, tok);
290
318
  }
@@ -336,7 +364,7 @@ class Parser {
336
364
  assertValidQNamePrefix(name.split(':', 1)[0], this.fail.bind(this), tok);
337
365
  return internIri(this.prefixes.expandQName(name));
338
366
  } else {
339
- return internIri(name);
367
+ failInvalidKeywordLikeIdent(this.fail.bind(this), tok, name);
340
368
  }
341
369
  }
342
370
 
@@ -367,10 +395,9 @@ class Parser {
367
395
  dtIri = dtTok.value || '';
368
396
  } else if (dtTok.typ === 'Ident') {
369
397
  const qn = dtTok.value || '';
370
- if (qn.includes(':')) {
371
- assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), dtTok, 'datatype prefixed name');
372
- dtIri = this.prefixes.expandQName(qn);
373
- } else dtIri = qn;
398
+ if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), dtTok, qn);
399
+ assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), dtTok, 'datatype prefixed name');
400
+ dtIri = this.prefixes.expandQName(qn);
374
401
  } else {
375
402
  this.fail(`Expected datatype after ^^, got ${dtTok.toString()}`, dtTok);
376
403
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.15.4",
3
+ "version": "1.15.5",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [