eyeling 1.5.21 → 1.5.22

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/examples/gps.n3 CHANGED
@@ -7,45 +7,43 @@
7
7
 
8
8
  @prefix math: <http://www.w3.org/2000/10/swap/math#>.
9
9
  @prefix list: <http://www.w3.org/2000/10/swap/list#>.
10
- @prefix gps: <https://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
11
- @prefix : <https://eyereasoner.github.io/eye/reasoning#>.
12
-
13
- # ---------------------
14
- # Data (a small sample)
15
- # ---------------------
10
+ @prefix gps: <https://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
11
+ @prefix : <https://eyereasoner.github.io/eye/reasoning#>.
16
12
 
17
13
  # current state
18
14
  :i1 :location :Gent.
19
15
 
20
- # map of Belgium
21
- (:Gent :Brugge :drive_gent_brugge 1500.0 0.006 0.96 0.99) :edge true .
22
- (:Gent :Kortrijk :drive_gent_kortrijk 1600.0 0.007 0.96 0.99) :edge true .
23
- (:Kortrijk :Brugge :drive_kortrijk_brugge 1600.0 0.007 0.96 0.99) :edge true .
24
- (:Brugge :Oostende :drive_brugge_oostende 900.0 0.004 0.98 1.0) :edge true .
16
+ # -------------------------------------------------
17
+ # map of Belgium (as backward rules / descriptions)
18
+ # -------------------------------------------------
19
+ {:map-BE gps:description ({?S :location :Gent} true {?S :location :Brugge} :drive_gent_brugge 1500.0 0.006 0.96 0.99)} <= true.
20
+ {:map-BE gps:description ({?S :location :Gent} true {?S :location :Kortrijk} :drive_gent_kortrijk 1600.0 0.007 0.96 0.99)} <= true.
21
+ {:map-BE gps:description ({?S :location :Kortrijk} true {?S :location :Brugge} :drive_kortrijk_brugge 1600.0 0.007 0.96 0.99)} <= true.
22
+ {:map-BE gps:description ({?S :location :Brugge} true {?S :location :Oostende} :drive_brugge_oostende 900.0 0.004 0.98 1.0 )} <= true.
25
23
 
26
- # ----------------
27
- # Path computation
28
- # ----------------
24
+ # -----------------------------
25
+ # Compute all paths by chaining
26
+ # -----------------------------
29
27
 
30
- # Base: one edge is a path
28
+ # Base: a single map description is a path
31
29
  {
32
30
  (?From ?To (?Act) ?Dur ?Cost ?Belief ?Comfort) :path true.
33
31
  }
34
32
  <=
35
33
  {
36
- (?From ?To ?Act ?Dur ?Cost ?Belief ?Comfort) :edge true.
34
+ :map-BE gps:description (?From true ?To ?Act ?Dur ?Cost ?Belief ?Comfort).
37
35
  }.
38
36
 
39
- # Recursive: edge + path => path, aggregate weights, concatenate action list
37
+ # Recursive: chain one step + rest path, and aggregate weights
40
38
  {
41
- (?From ?To ?Acts ?Dur ?Cost ?Belief ?Comfort) :path true.
39
+ (?From ?To ?Actions ?Dur ?Cost ?Belief ?Comfort) :path true.
42
40
  }
43
41
  <=
44
42
  {
45
- (?From ?Mid ?Act ?Dur1 ?Cost1 ?Bel1 ?Comf1) :edge true.
43
+ :map-BE gps:description (?From true ?Mid ?Act ?Dur1 ?Cost1 ?Bel1 ?Comf1).
46
44
  (?Mid ?To ?RestActs ?Dur2 ?Cost2 ?Bel2 ?Comf2) :path true.
47
45
 
48
- ((?Act) ?RestActs) list:append ?Acts.
46
+ ((?Act) ?RestActs) list:append ?Actions.
49
47
 
50
48
  (?Dur1 ?Dur2) math:sum ?Dur.
51
49
  (?Cost1 ?Cost2) math:sum ?Cost.
@@ -53,13 +51,12 @@
53
51
  (?Comf1 ?Comf2) math:product ?Comfort.
54
52
  }.
55
53
 
56
- # -------------------------
57
- # Query: only paths to goal
58
- # -------------------------
59
-
54
+ # ------------------------------------------------------
55
+ # "Query": derive gps:path facts for i1, goal = Oostende
56
+ # ------------------------------------------------------
60
57
  {
61
- :i1 :location ?Start.
62
- (?Start :Oostende ?Acts ?Dur ?Cost ?Bel ?Comf) :path true.
58
+ :i1 :location :Gent.
59
+ ({:i1 :location :Gent} {:i1 :location :Oostende} ?Acts ?Dur ?Cost ?Bel ?Comf) :path true.
63
60
  }
64
61
  =>
65
62
  {
@@ -6,11 +6,19 @@
6
6
  # :i1 gps:path ((:drive_gent_kortrijk :drive_kortrijk_brugge :drive_brugge_oostende) 4100 0.018 0.903168 0.9801) .
7
7
  # It holds because the following instance of the rule body is provable:
8
8
  # :i1 :location :Gent .
9
- # (:Gent :Oostende (:drive_gent_kortrijk :drive_kortrijk_brugge :drive_brugge_oostende) 4100 0.018 0.903168 0.9801) :path true .
9
+ # ({
10
+ # :i1 :location :Gent .
11
+ # } {
12
+ # :i1 :location :Oostende .
13
+ # } (:drive_gent_kortrijk :drive_kortrijk_brugge :drive_brugge_oostende) 4100 0.018 0.903168 0.9801) :path true .
10
14
  # via the schematic forward rule:
11
15
  # {
12
- # :i1 :location ?Start .
13
- # (?Start :Oostende ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
16
+ # :i1 :location :Gent .
17
+ # ({
18
+ # :i1 :location :Gent .
19
+ # } {
20
+ # :i1 :location :Oostende .
21
+ # } ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
14
22
  # } => {
15
23
  # :i1 gps:path (?Acts ?Dur ?Cost ?Bel ?Comf) .
16
24
  # } .
@@ -20,7 +28,6 @@
20
28
  # ?Comf = 0.9801
21
29
  # ?Cost = 0.018
22
30
  # ?Dur = 4100
23
- # ?Start = :Gent
24
31
  # Therefore the derived triple above is entailed by the rules and facts.
25
32
  # ----------------------------------------------------------------------
26
33
 
@@ -31,11 +38,19 @@
31
38
  # :i1 gps:path ((:drive_gent_brugge :drive_brugge_oostende) 2400 0.01 0.9408 0.99) .
32
39
  # It holds because the following instance of the rule body is provable:
33
40
  # :i1 :location :Gent .
34
- # (:Gent :Oostende (:drive_gent_brugge :drive_brugge_oostende) 2400 0.01 0.9408 0.99) :path true .
41
+ # ({
42
+ # :i1 :location :Gent .
43
+ # } {
44
+ # :i1 :location :Oostende .
45
+ # } (:drive_gent_brugge :drive_brugge_oostende) 2400 0.01 0.9408 0.99) :path true .
35
46
  # via the schematic forward rule:
36
47
  # {
37
- # :i1 :location ?Start .
38
- # (?Start :Oostende ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
48
+ # :i1 :location :Gent .
49
+ # ({
50
+ # :i1 :location :Gent .
51
+ # } {
52
+ # :i1 :location :Oostende .
53
+ # } ?Acts ?Dur ?Cost ?Bel ?Comf) :path true .
39
54
  # } => {
40
55
  # :i1 gps:path (?Acts ?Dur ?Cost ?Bel ?Comf) .
41
56
  # } .
@@ -45,7 +60,6 @@
45
60
  # ?Comf = 0.99
46
61
  # ?Cost = 0.01
47
62
  # ?Dur = 2400
48
- # ?Start = :Gent
49
63
  # Therefore the derived triple above is entailed by the rules and facts.
50
64
  # ----------------------------------------------------------------------
51
65
 
package/eyeling.js CHANGED
@@ -1463,6 +1463,40 @@ function unifyOpenWithList(prefix, tailv, ys, subst) {
1463
1463
  return s2;
1464
1464
  }
1465
1465
 
1466
+ function unifyFormulaTriples(xs, ys, subst) {
1467
+ if (xs.length !== ys.length) return null;
1468
+
1469
+ // Fast path: exact same sequence.
1470
+ if (triplesListEqual(xs, ys)) return { ...subst };
1471
+
1472
+ // Backtracking match (order-insensitive), *threading* the substitution through.
1473
+ const used = new Array(ys.length).fill(false);
1474
+
1475
+ function step(i, s) {
1476
+ if (i >= xs.length) return s;
1477
+ const x = xs[i];
1478
+
1479
+ for (let j = 0; j < ys.length; j++) {
1480
+ if (used[j]) continue;
1481
+ const y = ys[j];
1482
+
1483
+ // Cheap pruning when both predicates are IRIs.
1484
+ if (x.p instanceof Iri && y.p instanceof Iri && x.p.value !== y.p.value) continue;
1485
+
1486
+ const s2 = unifyTriple(x, y, s); // IMPORTANT: use `s`, not {}
1487
+ if (s2 === null) continue;
1488
+
1489
+ used[j] = true;
1490
+ const s3 = step(i + 1, s2);
1491
+ if (s3 !== null) return s3;
1492
+ used[j] = false;
1493
+ }
1494
+ return null;
1495
+ }
1496
+
1497
+ return step(0, { ...subst }); // IMPORTANT: start from the incoming subst
1498
+ }
1499
+
1466
1500
  function unifyTerm(a, b, subst) {
1467
1501
  a = applySubstTerm(a, subst);
1468
1502
  b = applySubstTerm(b, subst);
@@ -1521,11 +1555,10 @@ function unifyTerm(a, b, subst) {
1521
1555
  return s2;
1522
1556
  }
1523
1557
 
1524
- // Formulas are treated as opaque unless exactly equal
1558
+ // Formulas: unify their internal triple sets (order-insensitive)
1525
1559
  if (a instanceof FormulaTerm && b instanceof FormulaTerm) {
1526
- if (triplesListEqual(a.triples, b.triples)) return { ...subst };
1560
+ return unifyFormulaTriples(a.triples, b.triples, subst);
1527
1561
  }
1528
-
1529
1562
  return null;
1530
1563
  }
1531
1564
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.5.21",
3
+ "version": "1.5.22",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [