eyeling 1.26.4 → 1.26.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,21 @@
1
+ @prefix : <http://example.org/#> .
2
+ @prefix math: <http://www.w3.org/2000/10/swap/math#> .
3
+ @prefix pe: <https://eyereasoner.github.io/pe#> .
4
+
5
+ 5 :isIndeedMoreInterestingThan 3 .
6
+
7
+ { 5 :isIndeedMoreInterestingThan 3 . } pe:why {
8
+ { 5 :isIndeedMoreInterestingThan 3 . }
9
+ pe:by [ pe:rule "backward.n3"; pe:line 18 ];
10
+ pe:uses { 5 :moreInterestingThan 3 . }.
11
+
12
+ { 5 :moreInterestingThan 3 . }
13
+ pe:by [ pe:rule "backward.n3"; pe:line 11 ];
14
+ pe:binding
15
+ [ pe:var "X"; pe:value 5 ],
16
+ [ pe:var "Y"; pe:value 3 ];
17
+ pe:uses { 5 math:greaterThan 3 . }.
18
+
19
+ { 5 math:greaterThan 3 . }
20
+ pe:by [ pe:builtin math:greaterThan ].
21
+ }.
@@ -0,0 +1,196 @@
1
+ @prefix : <http://examples.org/#> .
2
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
3
+ @prefix pe: <https://eyereasoner.github.io/pe#> .
4
+
5
+ :result :sameInputByCompositeInjectivity (:h :a :b) .
6
+ :result :sameInputByCompositeInjectivity (:h :b :a) .
7
+
8
+ { :result :sameInputByCompositeInjectivity (:h :a :b) . } pe:why {
9
+ { :result :sameInputByCompositeInjectivity (:h :a :b) . }
10
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 234 ];
11
+ pe:binding
12
+ [ pe:var "h"; pe:value :h ],
13
+ [ pe:var "x"; pe:value :a ],
14
+ [ pe:var "y"; pe:value :b ];
15
+ pe:uses
16
+ { (:h :a :b) :sameInputUnderEqualCompositeOutput true . },
17
+ { :a log:notEqualTo :b . }.
18
+
19
+ { (:h :a :b) :sameInputUnderEqualCompositeOutput true . }
20
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 169 ];
21
+ pe:binding
22
+ [ pe:var "f"; pe:value :f ],
23
+ [ pe:var "fx"; pe:value :p ],
24
+ [ pe:var "fy"; pe:value :q ],
25
+ [ pe:var "g"; pe:value :g ],
26
+ [ pe:var "h"; pe:value :h ],
27
+ [ pe:var "u"; pe:value :r ],
28
+ [ pe:var "v"; pe:value :r ],
29
+ [ pe:var "x"; pe:value :a ],
30
+ [ pe:var "y"; pe:value :b ];
31
+ pe:uses
32
+ { :h :compositeOf (:g :f) . },
33
+ { :f :injective true . },
34
+ { :g :injective true . },
35
+ { (:f :a) :app :p . },
36
+ { (:f :b) :app :q . },
37
+ { (:g :p) :app :r . },
38
+ { (:g :q) :app :r . },
39
+ { (:r :r) :sameTerm true . },
40
+ { (:a :b) :sameTerm true . }.
41
+
42
+ { :h :compositeOf (:g :f) . }
43
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 219 ].
44
+
45
+ { :f :injective true . }
46
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 216 ].
47
+
48
+ { :g :injective true . }
49
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 217 ].
50
+
51
+ { (:f :a) :app :p . }
52
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 221 ].
53
+
54
+ { (:f :b) :app :q . }
55
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 222 ].
56
+
57
+ { (:g :p) :app :r . }
58
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 224 ].
59
+
60
+ { (:g :q) :app :r . }
61
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 225 ].
62
+
63
+ { (:r :r) :sameTerm true . }
64
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 77 ];
65
+ pe:binding [ pe:var "z"; pe:value :r ];
66
+ pe:uses { :r :inZ true . }.
67
+
68
+ { :r :inZ true . }
69
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 214 ].
70
+
71
+ { (:a :b) :sameTerm true . }
72
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 117 ];
73
+ pe:binding
74
+ [ pe:var "f"; pe:value :f ],
75
+ [ pe:var "u"; pe:value :p ],
76
+ [ pe:var "v"; pe:value :q ],
77
+ [ pe:var "x"; pe:value :a ],
78
+ [ pe:var "y"; pe:value :b ];
79
+ pe:uses
80
+ { :f :injective true . },
81
+ { (:f :a) :app :p . },
82
+ { (:f :b) :app :q . },
83
+ { (:p :q) :sameTerm true . }.
84
+
85
+ { (:p :q) :sameTerm true . }
86
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 117 ];
87
+ pe:binding
88
+ [ pe:var "f"; pe:value :g ],
89
+ [ pe:var "u"; pe:value :r ],
90
+ [ pe:var "v"; pe:value :r ],
91
+ [ pe:var "x"; pe:value :p ],
92
+ [ pe:var "y"; pe:value :q ];
93
+ pe:uses
94
+ { :g :injective true . },
95
+ { (:g :p) :app :r . },
96
+ { (:g :q) :app :r . },
97
+ { (:r :r) :sameTerm true . }.
98
+
99
+ { :a log:notEqualTo :b . }
100
+ pe:by [ pe:builtin log:notEqualTo ].
101
+ }.
102
+
103
+ { :result :sameInputByCompositeInjectivity (:h :b :a) . } pe:why {
104
+ { :result :sameInputByCompositeInjectivity (:h :b :a) . }
105
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 234 ];
106
+ pe:binding
107
+ [ pe:var "h"; pe:value :h ],
108
+ [ pe:var "x"; pe:value :b ],
109
+ [ pe:var "y"; pe:value :a ];
110
+ pe:uses
111
+ { (:h :b :a) :sameInputUnderEqualCompositeOutput true . },
112
+ { :b log:notEqualTo :a . }.
113
+
114
+ { (:h :b :a) :sameInputUnderEqualCompositeOutput true . }
115
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 169 ];
116
+ pe:binding
117
+ [ pe:var "f"; pe:value :f ],
118
+ [ pe:var "fx"; pe:value :q ],
119
+ [ pe:var "fy"; pe:value :p ],
120
+ [ pe:var "g"; pe:value :g ],
121
+ [ pe:var "h"; pe:value :h ],
122
+ [ pe:var "u"; pe:value :r ],
123
+ [ pe:var "v"; pe:value :r ],
124
+ [ pe:var "x"; pe:value :b ],
125
+ [ pe:var "y"; pe:value :a ];
126
+ pe:uses
127
+ { :h :compositeOf (:g :f) . },
128
+ { :f :injective true . },
129
+ { :g :injective true . },
130
+ { (:f :b) :app :q . },
131
+ { (:f :a) :app :p . },
132
+ { (:g :q) :app :r . },
133
+ { (:g :p) :app :r . },
134
+ { (:r :r) :sameTerm true . },
135
+ { (:b :a) :sameTerm true . }.
136
+
137
+ { :h :compositeOf (:g :f) . }
138
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 219 ].
139
+
140
+ { :f :injective true . }
141
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 216 ].
142
+
143
+ { :g :injective true . }
144
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 217 ].
145
+
146
+ { (:f :b) :app :q . }
147
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 222 ].
148
+
149
+ { (:f :a) :app :p . }
150
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 221 ].
151
+
152
+ { (:g :q) :app :r . }
153
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 225 ].
154
+
155
+ { (:g :p) :app :r . }
156
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 224 ].
157
+
158
+ { (:r :r) :sameTerm true . }
159
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 77 ];
160
+ pe:binding [ pe:var "z"; pe:value :r ];
161
+ pe:uses { :r :inZ true . }.
162
+
163
+ { :r :inZ true . }
164
+ pe:by [ pe:fact "composition-of-injective-functions-is-injective.n3"; pe:line 214 ].
165
+
166
+ { (:b :a) :sameTerm true . }
167
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 117 ];
168
+ pe:binding
169
+ [ pe:var "f"; pe:value :f ],
170
+ [ pe:var "u"; pe:value :q ],
171
+ [ pe:var "v"; pe:value :p ],
172
+ [ pe:var "x"; pe:value :b ],
173
+ [ pe:var "y"; pe:value :a ];
174
+ pe:uses
175
+ { :f :injective true . },
176
+ { (:f :b) :app :q . },
177
+ { (:f :a) :app :p . },
178
+ { (:q :p) :sameTerm true . }.
179
+
180
+ { (:q :p) :sameTerm true . }
181
+ pe:by [ pe:rule "composition-of-injective-functions-is-injective.n3"; pe:line 117 ];
182
+ pe:binding
183
+ [ pe:var "f"; pe:value :g ],
184
+ [ pe:var "u"; pe:value :r ],
185
+ [ pe:var "v"; pe:value :r ],
186
+ [ pe:var "x"; pe:value :q ],
187
+ [ pe:var "y"; pe:value :p ];
188
+ pe:uses
189
+ { :g :injective true . },
190
+ { (:g :q) :app :r . },
191
+ { (:g :p) :app :r . },
192
+ { (:r :r) :sameTerm true . }.
193
+
194
+ { :b log:notEqualTo :a . }
195
+ pe:by [ pe:builtin log:notEqualTo ].
196
+ }.
@@ -0,0 +1,26 @@
1
+ @prefix : <http://example.org/socrates#> .
2
+ @prefix pe: <https://eyereasoner.github.io/pe#> .
3
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
4
+
5
+ :Socrates :is _:sk_0 .
6
+ :Plato :is _:sk_1 .
7
+
8
+ { :Socrates :is _:sk_0 . } pe:why {
9
+ { :Socrates :is _:sk_0 . }
10
+ pe:by [ pe:rule "existential-rule.n3"; pe:line 13 ];
11
+ pe:binding [ pe:var "S"; pe:value :Socrates ];
12
+ pe:uses { :Socrates a :Human . }.
13
+
14
+ { :Socrates a :Human . }
15
+ pe:by [ pe:fact "existential-rule.n3"; pe:line 9 ].
16
+ }.
17
+
18
+ { :Plato :is _:sk_1 . } pe:why {
19
+ { :Plato :is _:sk_1 . }
20
+ pe:by [ pe:rule "existential-rule.n3"; pe:line 13 ];
21
+ pe:binding [ pe:var "S"; pe:value :Plato ];
22
+ pe:uses { :Plato a :Human . }.
23
+
24
+ { :Plato a :Human . }
25
+ pe:by [ pe:fact "existential-rule.n3"; pe:line 10 ].
26
+ }.
@@ -0,0 +1,168 @@
1
+ @prefix : <http://example.org/#> .
2
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
3
+ @prefix pe: <https://eyereasoner.github.io/pe#> .
4
+
5
+ :result :sameGreatestLowerBound (:a :b :g1 :g2) .
6
+ :result :sameGreatestLowerBound (:a :b :g2 :g1) .
7
+
8
+ { :result :sameGreatestLowerBound (:a :b :g1 :g2) . } pe:why {
9
+ { :result :sameGreatestLowerBound (:a :b :g1 :g2) . }
10
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 195 ];
11
+ pe:binding
12
+ [ pe:var "a"; pe:value :a ],
13
+ [ pe:var "b"; pe:value :b ],
14
+ [ pe:var "m"; pe:value :g1 ],
15
+ [ pe:var "n"; pe:value :g2 ];
16
+ pe:uses
17
+ { (:a :b :g1 :g2) :sameGlb true . },
18
+ { :g1 log:notEqualTo :g2 . }.
19
+
20
+ { (:a :b :g1 :g2) :sameGlb true . }
21
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 161 ];
22
+ pe:binding
23
+ [ pe:var "a"; pe:value :a ],
24
+ [ pe:var "b"; pe:value :b ],
25
+ [ pe:var "m"; pe:value :g1 ],
26
+ [ pe:var "n"; pe:value :g2 ];
27
+ pe:uses
28
+ { :g1 :glbOf (:a :b) . },
29
+ { :g2 :glbOf (:a :b) . },
30
+ { (:g1 :g2) :sameTerm true . }.
31
+
32
+ { :g1 :glbOf (:a :b) . }
33
+ pe:by [ pe:fact "greatest-lower-bound-uniqueness.n3"; pe:line 185 ].
34
+
35
+ { :g2 :glbOf (:a :b) . }
36
+ pe:by [ pe:fact "greatest-lower-bound-uniqueness.n3"; pe:line 186 ].
37
+
38
+ { (:g1 :g2) :sameTerm true . }
39
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 85 ];
40
+ pe:binding
41
+ [ pe:var "x"; pe:value :g1 ],
42
+ [ pe:var "y"; pe:value :g2 ];
43
+ pe:uses
44
+ { :g1 :leq :g2 . },
45
+ { :g2 :leq :g1 . }.
46
+
47
+ { :g1 :leq :g2 . }
48
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 126 ];
49
+ pe:binding
50
+ [ pe:var "a"; pe:value :a ],
51
+ [ pe:var "b"; pe:value :b ],
52
+ [ pe:var "l"; pe:value :g1 ],
53
+ [ pe:var "m"; pe:value :g2 ];
54
+ pe:uses
55
+ { :g2 :glbOf (:a :b) . },
56
+ { :g1 :lowerBoundOf (:a :b) . }.
57
+
58
+ { :g1 :lowerBoundOf (:a :b) . }
59
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 112 ];
60
+ pe:binding
61
+ [ pe:var "a"; pe:value :a ],
62
+ [ pe:var "b"; pe:value :b ],
63
+ [ pe:var "m"; pe:value :g1 ];
64
+ pe:uses { :g1 :glbOf (:a :b) . }.
65
+
66
+ { :g2 :leq :g1 . }
67
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 126 ];
68
+ pe:binding
69
+ [ pe:var "a"; pe:value :a ],
70
+ [ pe:var "b"; pe:value :b ],
71
+ [ pe:var "l"; pe:value :g2 ],
72
+ [ pe:var "m"; pe:value :g1 ];
73
+ pe:uses
74
+ { :g1 :glbOf (:a :b) . },
75
+ { :g2 :lowerBoundOf (:a :b) . }.
76
+
77
+ { :g2 :lowerBoundOf (:a :b) . }
78
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 112 ];
79
+ pe:binding
80
+ [ pe:var "a"; pe:value :a ],
81
+ [ pe:var "b"; pe:value :b ],
82
+ [ pe:var "m"; pe:value :g2 ];
83
+ pe:uses { :g2 :glbOf (:a :b) . }.
84
+
85
+ { :g1 log:notEqualTo :g2 . }
86
+ pe:by [ pe:builtin log:notEqualTo ].
87
+ }.
88
+
89
+ { :result :sameGreatestLowerBound (:a :b :g2 :g1) . } pe:why {
90
+ { :result :sameGreatestLowerBound (:a :b :g2 :g1) . }
91
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 195 ];
92
+ pe:binding
93
+ [ pe:var "a"; pe:value :a ],
94
+ [ pe:var "b"; pe:value :b ],
95
+ [ pe:var "m"; pe:value :g2 ],
96
+ [ pe:var "n"; pe:value :g1 ];
97
+ pe:uses
98
+ { (:a :b :g2 :g1) :sameGlb true . },
99
+ { :g2 log:notEqualTo :g1 . }.
100
+
101
+ { (:a :b :g2 :g1) :sameGlb true . }
102
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 161 ];
103
+ pe:binding
104
+ [ pe:var "a"; pe:value :a ],
105
+ [ pe:var "b"; pe:value :b ],
106
+ [ pe:var "m"; pe:value :g2 ],
107
+ [ pe:var "n"; pe:value :g1 ];
108
+ pe:uses
109
+ { :g2 :glbOf (:a :b) . },
110
+ { :g1 :glbOf (:a :b) . },
111
+ { (:g2 :g1) :sameTerm true . }.
112
+
113
+ { :g2 :glbOf (:a :b) . }
114
+ pe:by [ pe:fact "greatest-lower-bound-uniqueness.n3"; pe:line 186 ].
115
+
116
+ { :g1 :glbOf (:a :b) . }
117
+ pe:by [ pe:fact "greatest-lower-bound-uniqueness.n3"; pe:line 185 ].
118
+
119
+ { (:g2 :g1) :sameTerm true . }
120
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 85 ];
121
+ pe:binding
122
+ [ pe:var "x"; pe:value :g2 ],
123
+ [ pe:var "y"; pe:value :g1 ];
124
+ pe:uses
125
+ { :g2 :leq :g1 . },
126
+ { :g1 :leq :g2 . }.
127
+
128
+ { :g2 :leq :g1 . }
129
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 126 ];
130
+ pe:binding
131
+ [ pe:var "a"; pe:value :a ],
132
+ [ pe:var "b"; pe:value :b ],
133
+ [ pe:var "l"; pe:value :g2 ],
134
+ [ pe:var "m"; pe:value :g1 ];
135
+ pe:uses
136
+ { :g1 :glbOf (:a :b) . },
137
+ { :g2 :lowerBoundOf (:a :b) . }.
138
+
139
+ { :g2 :lowerBoundOf (:a :b) . }
140
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 112 ];
141
+ pe:binding
142
+ [ pe:var "a"; pe:value :a ],
143
+ [ pe:var "b"; pe:value :b ],
144
+ [ pe:var "m"; pe:value :g2 ];
145
+ pe:uses { :g2 :glbOf (:a :b) . }.
146
+
147
+ { :g1 :leq :g2 . }
148
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 126 ];
149
+ pe:binding
150
+ [ pe:var "a"; pe:value :a ],
151
+ [ pe:var "b"; pe:value :b ],
152
+ [ pe:var "l"; pe:value :g1 ],
153
+ [ pe:var "m"; pe:value :g2 ];
154
+ pe:uses
155
+ { :g2 :glbOf (:a :b) . },
156
+ { :g1 :lowerBoundOf (:a :b) . }.
157
+
158
+ { :g1 :lowerBoundOf (:a :b) . }
159
+ pe:by [ pe:rule "greatest-lower-bound-uniqueness.n3"; pe:line 112 ];
160
+ pe:binding
161
+ [ pe:var "a"; pe:value :a ],
162
+ [ pe:var "b"; pe:value :b ],
163
+ [ pe:var "m"; pe:value :g1 ];
164
+ pe:uses { :g1 :glbOf (:a :b) . }.
165
+
166
+ { :g2 log:notEqualTo :g1 . }
167
+ pe:by [ pe:builtin log:notEqualTo ].
168
+ }.
@@ -0,0 +1,180 @@
1
+ @prefix : <http://example.org/#> .
2
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
3
+ @prefix pe: <https://eyereasoner.github.io/pe#> .
4
+
5
+ :result :sameInverse (:x :i :j) .
6
+ :result :sameInverse (:x :j :i) .
7
+
8
+ { :result :sameInverse (:x :i :j) . } pe:why {
9
+ { :result :sameInverse (:x :i :j) . }
10
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 167 ];
11
+ pe:binding
12
+ [ pe:var "x"; pe:value :x ],
13
+ [ pe:var "y"; pe:value :i ],
14
+ [ pe:var "z"; pe:value :j ];
15
+ pe:uses
16
+ { (:x :i :j) :sameInverse true . },
17
+ { :i log:notEqualTo :j . }.
18
+
19
+ { (:x :i :j) :sameInverse true . }
20
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 138 ];
21
+ pe:binding
22
+ [ pe:var "x"; pe:value :x ],
23
+ [ pe:var "y"; pe:value :i ],
24
+ [ pe:var "z"; pe:value :j ];
25
+ pe:uses
26
+ { :i :inverseOf :x . },
27
+ { :j :inverseOf :x . },
28
+ { (:i :j) :sameTerm true . }.
29
+
30
+ { :i :inverseOf :x . }
31
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 158 ].
32
+
33
+ { :j :inverseOf :x . }
34
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 159 ].
35
+
36
+ { (:i :j) :sameTerm true . }
37
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 54 ];
38
+ pe:binding
39
+ [ pe:var "a"; pe:value :j ],
40
+ [ pe:var "ab"; pe:value :e ],
41
+ [ pe:var "b"; pe:value :x ],
42
+ [ pe:var "bc"; pe:value :e ],
43
+ [ pe:var "c"; pe:value :i ],
44
+ [ pe:var "left"; pe:value :i ],
45
+ [ pe:var "right"; pe:value :j ];
46
+ pe:uses
47
+ { (:j :x) :mul :e . },
48
+ { (:e :i) :mul :i . },
49
+ { (:x :i) :mul :e . },
50
+ { (:j :e) :mul :j . }.
51
+
52
+ { (:j :x) :mul :e . }
53
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 102 ];
54
+ pe:binding
55
+ [ pe:var "x"; pe:value :x ],
56
+ [ pe:var "y"; pe:value :j ];
57
+ pe:uses
58
+ { :x :inG true . },
59
+ { :j :inG true . },
60
+ { :j :inverseOf :x . }.
61
+
62
+ { :x :inG true . }
63
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 153 ].
64
+
65
+ { :j :inG true . }
66
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 155 ].
67
+
68
+ { (:e :i) :mul :i . }
69
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 78 ];
70
+ pe:binding [ pe:var "a"; pe:value :i ];
71
+ pe:uses { :i :inG true . }.
72
+
73
+ { :i :inG true . }
74
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 154 ].
75
+
76
+ { (:x :i) :mul :e . }
77
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 102 ];
78
+ pe:binding
79
+ [ pe:var "x"; pe:value :x ],
80
+ [ pe:var "y"; pe:value :i ];
81
+ pe:uses
82
+ { :x :inG true . },
83
+ { :i :inG true . },
84
+ { :i :inverseOf :x . }.
85
+
86
+ { (:j :e) :mul :j . }
87
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 89 ];
88
+ pe:binding [ pe:var "a"; pe:value :j ];
89
+ pe:uses { :j :inG true . }.
90
+
91
+ { :i log:notEqualTo :j . }
92
+ pe:by [ pe:builtin log:notEqualTo ].
93
+ }.
94
+
95
+ { :result :sameInverse (:x :j :i) . } pe:why {
96
+ { :result :sameInverse (:x :j :i) . }
97
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 167 ];
98
+ pe:binding
99
+ [ pe:var "x"; pe:value :x ],
100
+ [ pe:var "y"; pe:value :j ],
101
+ [ pe:var "z"; pe:value :i ];
102
+ pe:uses
103
+ { (:x :j :i) :sameInverse true . },
104
+ { :j log:notEqualTo :i . }.
105
+
106
+ { (:x :j :i) :sameInverse true . }
107
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 138 ];
108
+ pe:binding
109
+ [ pe:var "x"; pe:value :x ],
110
+ [ pe:var "y"; pe:value :j ],
111
+ [ pe:var "z"; pe:value :i ];
112
+ pe:uses
113
+ { :j :inverseOf :x . },
114
+ { :i :inverseOf :x . },
115
+ { (:j :i) :sameTerm true . }.
116
+
117
+ { :j :inverseOf :x . }
118
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 159 ].
119
+
120
+ { :i :inverseOf :x . }
121
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 158 ].
122
+
123
+ { (:j :i) :sameTerm true . }
124
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 54 ];
125
+ pe:binding
126
+ [ pe:var "a"; pe:value :i ],
127
+ [ pe:var "ab"; pe:value :e ],
128
+ [ pe:var "b"; pe:value :x ],
129
+ [ pe:var "bc"; pe:value :e ],
130
+ [ pe:var "c"; pe:value :j ],
131
+ [ pe:var "left"; pe:value :j ],
132
+ [ pe:var "right"; pe:value :i ];
133
+ pe:uses
134
+ { (:i :x) :mul :e . },
135
+ { (:e :j) :mul :j . },
136
+ { (:x :j) :mul :e . },
137
+ { (:i :e) :mul :i . }.
138
+
139
+ { (:i :x) :mul :e . }
140
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 102 ];
141
+ pe:binding
142
+ [ pe:var "x"; pe:value :x ],
143
+ [ pe:var "y"; pe:value :i ];
144
+ pe:uses
145
+ { :x :inG true . },
146
+ { :i :inG true . },
147
+ { :i :inverseOf :x . }.
148
+
149
+ { :x :inG true . }
150
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 153 ].
151
+
152
+ { :i :inG true . }
153
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 154 ].
154
+
155
+ { (:e :j) :mul :j . }
156
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 78 ];
157
+ pe:binding [ pe:var "a"; pe:value :j ];
158
+ pe:uses { :j :inG true . }.
159
+
160
+ { :j :inG true . }
161
+ pe:by [ pe:fact "group-inverse-uniqueness.n3"; pe:line 155 ].
162
+
163
+ { (:x :j) :mul :e . }
164
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 102 ];
165
+ pe:binding
166
+ [ pe:var "x"; pe:value :x ],
167
+ [ pe:var "y"; pe:value :j ];
168
+ pe:uses
169
+ { :x :inG true . },
170
+ { :j :inG true . },
171
+ { :j :inverseOf :x . }.
172
+
173
+ { (:i :e) :mul :i . }
174
+ pe:by [ pe:rule "group-inverse-uniqueness.n3"; pe:line 89 ];
175
+ pe:binding [ pe:var "a"; pe:value :i ];
176
+ pe:uses { :i :inG true . }.
177
+
178
+ { :j log:notEqualTo :i . }
179
+ pe:by [ pe:builtin log:notEqualTo ].
180
+ }.
@@ -0,0 +1,152 @@
1
+ @prefix : <http://example.org/#> .
2
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
3
+ @prefix pe: <https://eyereasoner.github.io/pe#> .
4
+ @prefix string: <http://www.w3.org/2000/10/swap/string#> .
5
+
6
+ :result1 :is ("Huey" "Dewey" "Louie") .
7
+ :result2 :is (("Huey") ("Dewey") ("Louie")) .
8
+ :result3 :is ("Huey" "Dewey") .
9
+
10
+ { :result1 :is ("Huey" "Dewey" "Louie") . } pe:why {
11
+ { :result1 :is ("Huey" "Dewey" "Louie") . }
12
+ pe:by [ pe:rule "log-collect-all-in.n3"; pe:line 13 ];
13
+ pe:binding
14
+ [ pe:var "allParams"; pe:value ("Huey" "Dewey" "Louie") ],
15
+ [ pe:var "filteredParams"; pe:value ("Huey" "Dewey") ],
16
+ [ pe:var "nestedParams"; pe:value (("Huey") ("Dewey") ("Louie")) ];
17
+ pe:uses
18
+ {
19
+ (?param {
20
+ :Let :param ?param .
21
+ } ("Huey" "Dewey" "Louie")) log:collectAllIn ?_b1 .
22
+ },
23
+ {
24
+ ((?param) {
25
+ :Let :param ?param .
26
+ } (("Huey") ("Dewey") ("Louie"))) log:collectAllIn ?_b1 .
27
+ },
28
+ {
29
+ (?param {
30
+ :Let :param ?param .
31
+ ?param string:lessThan "Louie" .
32
+ } ("Huey" "Dewey")) log:collectAllIn ?_b1 .
33
+ }.
34
+
35
+ {
36
+ (?param {
37
+ :Let :param ?param .
38
+ } ("Huey" "Dewey" "Louie")) log:collectAllIn ?_b1 .
39
+ }
40
+ pe:by [ pe:builtin log:collectAllIn ].
41
+
42
+ {
43
+ ((?param) {
44
+ :Let :param ?param .
45
+ } (("Huey") ("Dewey") ("Louie"))) log:collectAllIn ?_b1 .
46
+ }
47
+ pe:by [ pe:builtin log:collectAllIn ].
48
+
49
+ {
50
+ (?param {
51
+ :Let :param ?param .
52
+ ?param string:lessThan "Louie" .
53
+ } ("Huey" "Dewey")) log:collectAllIn ?_b1 .
54
+ }
55
+ pe:by [ pe:builtin log:collectAllIn ].
56
+ }.
57
+
58
+ { :result2 :is (("Huey") ("Dewey") ("Louie")) . } pe:why {
59
+ { :result2 :is (("Huey") ("Dewey") ("Louie")) . }
60
+ pe:by [ pe:rule "log-collect-all-in.n3"; pe:line 13 ];
61
+ pe:binding
62
+ [ pe:var "allParams"; pe:value ("Huey" "Dewey" "Louie") ],
63
+ [ pe:var "filteredParams"; pe:value ("Huey" "Dewey") ],
64
+ [ pe:var "nestedParams"; pe:value (("Huey") ("Dewey") ("Louie")) ];
65
+ pe:uses
66
+ {
67
+ (?param {
68
+ :Let :param ?param .
69
+ } ("Huey" "Dewey" "Louie")) log:collectAllIn ?_b1 .
70
+ },
71
+ {
72
+ ((?param) {
73
+ :Let :param ?param .
74
+ } (("Huey") ("Dewey") ("Louie"))) log:collectAllIn ?_b1 .
75
+ },
76
+ {
77
+ (?param {
78
+ :Let :param ?param .
79
+ ?param string:lessThan "Louie" .
80
+ } ("Huey" "Dewey")) log:collectAllIn ?_b1 .
81
+ }.
82
+
83
+ {
84
+ (?param {
85
+ :Let :param ?param .
86
+ } ("Huey" "Dewey" "Louie")) log:collectAllIn ?_b1 .
87
+ }
88
+ pe:by [ pe:builtin log:collectAllIn ].
89
+
90
+ {
91
+ ((?param) {
92
+ :Let :param ?param .
93
+ } (("Huey") ("Dewey") ("Louie"))) log:collectAllIn ?_b1 .
94
+ }
95
+ pe:by [ pe:builtin log:collectAllIn ].
96
+
97
+ {
98
+ (?param {
99
+ :Let :param ?param .
100
+ ?param string:lessThan "Louie" .
101
+ } ("Huey" "Dewey")) log:collectAllIn ?_b1 .
102
+ }
103
+ pe:by [ pe:builtin log:collectAllIn ].
104
+ }.
105
+
106
+ { :result3 :is ("Huey" "Dewey") . } pe:why {
107
+ { :result3 :is ("Huey" "Dewey") . }
108
+ pe:by [ pe:rule "log-collect-all-in.n3"; pe:line 13 ];
109
+ pe:binding
110
+ [ pe:var "allParams"; pe:value ("Huey" "Dewey" "Louie") ],
111
+ [ pe:var "filteredParams"; pe:value ("Huey" "Dewey") ],
112
+ [ pe:var "nestedParams"; pe:value (("Huey") ("Dewey") ("Louie")) ];
113
+ pe:uses
114
+ {
115
+ (?param {
116
+ :Let :param ?param .
117
+ } ("Huey" "Dewey" "Louie")) log:collectAllIn ?_b1 .
118
+ },
119
+ {
120
+ ((?param) {
121
+ :Let :param ?param .
122
+ } (("Huey") ("Dewey") ("Louie"))) log:collectAllIn ?_b1 .
123
+ },
124
+ {
125
+ (?param {
126
+ :Let :param ?param .
127
+ ?param string:lessThan "Louie" .
128
+ } ("Huey" "Dewey")) log:collectAllIn ?_b1 .
129
+ }.
130
+
131
+ {
132
+ (?param {
133
+ :Let :param ?param .
134
+ } ("Huey" "Dewey" "Louie")) log:collectAllIn ?_b1 .
135
+ }
136
+ pe:by [ pe:builtin log:collectAllIn ].
137
+
138
+ {
139
+ ((?param) {
140
+ :Let :param ?param .
141
+ } (("Huey") ("Dewey") ("Louie"))) log:collectAllIn ?_b1 .
142
+ }
143
+ pe:by [ pe:builtin log:collectAllIn ].
144
+
145
+ {
146
+ (?param {
147
+ :Let :param ?param .
148
+ ?param string:lessThan "Louie" .
149
+ } ("Huey" "Dewey")) log:collectAllIn ?_b1 .
150
+ }
151
+ pe:by [ pe:builtin log:collectAllIn ].
152
+ }.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.26.4",
3
+ "version": "1.26.5",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -52,20 +52,53 @@ function normalizeMarkdownForCompare(text) {
52
52
  // Normalize N3 output for comparison.
53
53
  // Eyeling (and other N3 tools) may emit the same closure with different
54
54
  // triple ordering. Examples tests should verify content, not presentation.
55
- function normalizeN3ForCompare(n3Text) {
56
- return stripTrailingWhitespace(n3Text)
55
+ function normalizeN3ForCompare(n3Text, sourceText = '', expectedPath = '') {
56
+ let value = stripTrailingWhitespace(n3Text);
57
+
58
+ // get-uuid.n3 intentionally uses log:skolem and relative IRIs, so its
59
+ // output depends on the checkout path and generated skolem seed. Compare the
60
+ // shape of the generated triples rather than those environment-specific bits.
61
+ if (/\blog:skolem\b/.test(sourceText) || path.basename(expectedPath) === 'get-uuid.n3') {
62
+ value = value
63
+ .replace(/<urn:uuid:[^>]+>/g, '<urn:uuid:__UUID__>')
64
+ .replace(/<file:\/\/[^>\s]*\/examples\/([^/>]+)>/g, '<file://__EXAMPLES__/$1>');
65
+ }
66
+
67
+ return value
57
68
  .split('\n')
58
69
  .filter((l) => l.length > 0)
59
70
  .sort((a, b) => a.localeCompare(b))
60
71
  .join('\n');
61
72
  }
62
73
 
63
- function normalizeForCompare(text, expectedPath) {
74
+ function normalizeForCompare(text, expectedPath, sourceText = '') {
64
75
  const ext = path.extname(expectedPath);
65
76
  const value = text;
66
77
  if (ext === '.md') return normalizeMarkdownForCompare(value);
67
78
  if (ext === '.txt') return normalizeTextForCompare(value);
68
- return normalizeN3ForCompare(value);
79
+ return normalizeN3ForCompare(value, sourceText, expectedPath);
80
+ }
81
+
82
+ function normalizeProofForCompare(text, expectedPath, sourceText) {
83
+ let value = normalizeForCompare(text, expectedPath, sourceText);
84
+
85
+ // Some proof goldens intentionally cover volatile builtins such as
86
+ // time:localTime. Keep those examples useful by comparing proof structure
87
+ // while masking only the volatile literal values.
88
+ if (/\btime:localTime\b/.test(sourceText)) {
89
+ value = value
90
+ .replace(/"[^"\n]*"\^\^xsd:dateTime/g, '"__DATETIME__"^^xsd:dateTime')
91
+ .replace(/"PT[0-9]+(?:\.[0-9]+)?S"\^\^xsd:duration/g, '"__DURATION__"^^xsd:duration');
92
+ }
93
+
94
+ return value;
95
+ }
96
+
97
+ function compareGeneratedOutput({ expectedPath, generatedPath, sourceText, proof }) {
98
+ const expectedText = fs.readFileSync(expectedPath, 'utf8');
99
+ const generatedText = fs.readFileSync(generatedPath, 'utf8');
100
+ const normalize = proof ? normalizeProofForCompare : normalizeForCompare;
101
+ return normalize(expectedText, expectedPath, sourceText) === normalize(generatedText, expectedPath, sourceText);
69
102
  }
70
103
 
71
104
  // Expectation logic (robust, long-term):
@@ -141,6 +174,42 @@ function resolveExampleBuiltinPath(root, inputFile) {
141
174
  return { abs, rel };
142
175
  }
143
176
 
177
+ function runExampleToFile({ root, examplesDir, eyelingJsPath, nodePath, file, generatedPath, proof = false }) {
178
+ const builtin = resolveExampleBuiltinPath(root, file);
179
+ const trigInput = resolveExampleTrigInput(root, file);
180
+ const rdfMode = !!trigInput;
181
+ const modeFlag = proof ? '-p' : '-d';
182
+ const outFd = fs.openSync(generatedPath, 'w');
183
+
184
+ try {
185
+ if (builtin) {
186
+ const args = [eyelingJsPath, modeFlag];
187
+ if (rdfMode) args.push('-r');
188
+ args.push('--builtin', builtin.rel, path.join('examples', file));
189
+ if (trigInput) args.push(path.join('examples', trigInput.rel));
190
+ return cp.spawnSync(nodePath, args, {
191
+ cwd: root,
192
+ stdio: ['ignore', outFd, 'pipe'], // stdout -> file, stderr captured
193
+ maxBuffer: 200 * 1024 * 1024,
194
+ encoding: 'utf8',
195
+ });
196
+ }
197
+
198
+ const args = [eyelingJsPath, modeFlag];
199
+ if (rdfMode) args.push('-r');
200
+ args.push(file);
201
+ if (trigInput) args.push(trigInput.rel);
202
+ return cp.spawnSync(nodePath, args, {
203
+ cwd: examplesDir,
204
+ stdio: ['ignore', outFd, 'pipe'], // stdout -> file, stderr captured
205
+ maxBuffer: 200 * 1024 * 1024,
206
+ encoding: 'utf8',
207
+ });
208
+ } finally {
209
+ fs.closeSync(outFd);
210
+ }
211
+ }
212
+
144
213
  function main() {
145
214
  const suiteStart = Date.now();
146
215
 
@@ -148,6 +217,7 @@ function main() {
148
217
  const root = path.resolve(__dirname, '..');
149
218
  const examplesDir = path.join(root, 'examples');
150
219
  const outputDir = path.join(examplesDir, 'output');
220
+ const proofDir = path.join(examplesDir, 'proof');
151
221
  const eyelingJsPath = path.join(root, 'eyeling.js');
152
222
  const nodePath = process.execPath;
153
223
 
@@ -164,8 +234,15 @@ function main() {
164
234
  .readdirSync(examplesDir)
165
235
  .filter((f) => f.endsWith('.n3'))
166
236
  .sort((a, b) => a.localeCompare(b));
167
-
168
- info(`Running ${files.length} examples tests`);
237
+ const proofFiles = fs.existsSync(proofDir)
238
+ ? fs
239
+ .readdirSync(proofDir)
240
+ .filter((f) => f.endsWith('.n3') && fs.existsSync(path.join(examplesDir, f)))
241
+ .sort((a, b) => a.localeCompare(b))
242
+ : [];
243
+ const totalTests = files.length + proofFiles.length;
244
+
245
+ info(`Running ${files.length} examples tests and ${proofFiles.length} proof golden tests`);
169
246
  console.log(`${C.dim}${getEyelingVersion(nodePath, eyelingJsPath, root)}; node ${process.version}${C.n}`);
170
247
 
171
248
  if (files.length === 0) {
@@ -178,6 +255,7 @@ function main() {
178
255
 
179
256
  // Pretty, stable numbering (e.g., 001..100 when running 100 tests)
180
257
  const idxWidth = String(files.length).length;
258
+ const proofIdxWidth = String(Math.max(proofFiles.length, 1)).length;
181
259
 
182
260
  for (let i = 0; i < files.length; i++) {
183
261
  const idx = String(i + 1).padStart(idxWidth, '0');
@@ -221,38 +299,7 @@ function main() {
221
299
  // node eyeling.js --builtin examples/builtin/foo.js examples/foo.n3
222
300
  // A matching examples/input/<stem>.trig sidecar is external RDF/TriG
223
301
  // evidence for this example, so include it and run in -r mode automatically.
224
- const builtin = resolveExampleBuiltinPath(root, file);
225
- const trigInput = resolveExampleTrigInput(root, file);
226
- const rdfMode = !!trigInput;
227
- const outFd = fs.openSync(generatedPath, 'w');
228
- let r;
229
- try {
230
- if (builtin) {
231
- const args = [eyelingJsPath, '-d'];
232
- if (rdfMode) args.push('-r');
233
- args.push('--builtin', builtin.rel, path.join('examples', file));
234
- if (trigInput) args.push(path.join('examples', trigInput.rel));
235
- r = cp.spawnSync(nodePath, args, {
236
- cwd: root,
237
- stdio: ['ignore', outFd, 'pipe'], // stdout -> file, stderr captured
238
- maxBuffer: 200 * 1024 * 1024,
239
- encoding: 'utf8',
240
- });
241
- } else {
242
- const args = [eyelingJsPath, '-d'];
243
- if (rdfMode) args.push('-r');
244
- args.push(file);
245
- if (trigInput) args.push(trigInput.rel);
246
- r = cp.spawnSync(nodePath, args, {
247
- cwd: examplesDir,
248
- stdio: ['ignore', outFd, 'pipe'], // stdout -> file, stderr captured
249
- maxBuffer: 200 * 1024 * 1024,
250
- encoding: 'utf8',
251
- });
252
- }
253
- } finally {
254
- fs.closeSync(outFd);
255
- }
302
+ const r = runExampleToFile({ root, examplesDir, eyelingJsPath, nodePath, file, generatedPath });
256
303
 
257
304
  const rc = r.status == null ? 1 : r.status;
258
305
 
@@ -261,12 +308,7 @@ function main() {
261
308
  // Compare output. N3 outputs are order-insensitive; Markdown outputs are order-sensitive.
262
309
  let diffOk = false;
263
310
  try {
264
- const expectedText = fs.readFileSync(expectedPath, 'utf8');
265
- const generatedText = fs.readFileSync(generatedPath, 'utf8');
266
- if (expectedText == null) throw new Error('missing expected output');
267
- diffOk =
268
- normalizeForCompare(expectedText, expectedPath) ===
269
- normalizeForCompare(generatedText, expectedPath);
311
+ diffOk = compareGeneratedOutput({ expectedPath, generatedPath, sourceText: n3Text, proof: false });
270
312
  } catch {
271
313
  diffOk = false;
272
314
  }
@@ -302,15 +344,76 @@ function main() {
302
344
  if (tmpDir) rmrf(tmpDir);
303
345
  }
304
346
 
347
+
348
+ for (let i = 0; i < proofFiles.length; i++) {
349
+ const idx = String(i + 1).padStart(proofIdxWidth, '0');
350
+ const file = proofFiles[i];
351
+ const start = Date.now();
352
+ const filePath = path.join(examplesDir, file);
353
+ const expectedPath = path.join(proofDir, file);
354
+
355
+ let n3Text;
356
+ try {
357
+ n3Text = fs.readFileSync(filePath, 'utf8');
358
+ } catch (e) {
359
+ const ms = Date.now() - start;
360
+ fail(`proof ${idx} ${file} ${msTag(ms)}`);
361
+ fail(`Cannot read proof input: ${e.message}`);
362
+ failed++;
363
+ continue;
364
+ }
365
+
366
+ const expectedRc = expectedExitCode(n3Text);
367
+ const tmpDir = mkTmpDir();
368
+ const generatedPath = path.join(tmpDir, 'generated.n3');
369
+ const r = runExampleToFile({ root, examplesDir, eyelingJsPath, nodePath, file, generatedPath, proof: true });
370
+ const rc = r.status == null ? 1 : r.status;
371
+ const ms = Date.now() - start;
372
+
373
+ let diffOk = false;
374
+ try {
375
+ diffOk = compareGeneratedOutput({ expectedPath, generatedPath, sourceText: n3Text, proof: true });
376
+ } catch {
377
+ diffOk = false;
378
+ }
379
+
380
+ const rcOk = rc === expectedRc;
381
+
382
+ if (diffOk && rcOk) {
383
+ if (expectedRc === 0) {
384
+ ok(`proof ${idx} ${file} ${msTag(ms)}`);
385
+ } else {
386
+ ok(`proof ${idx} ${file} (expected exit ${expectedRc}) ${msTag(ms)}`);
387
+ }
388
+ passed++;
389
+ } else {
390
+ fail(`proof ${idx} ${file} ${msTag(ms)}`);
391
+ if (!rcOk) {
392
+ fail(`Exit code ${rc}, expected ${expectedRc}`);
393
+ }
394
+ if (!diffOk) {
395
+ fail('Proof output differs');
396
+ }
397
+ showDiff({
398
+ examplesDir,
399
+ expectedPath,
400
+ generatedPath,
401
+ });
402
+ failed++;
403
+ }
404
+
405
+ if (tmpDir) rmrf(tmpDir);
406
+ }
407
+
305
408
  console.log('');
306
409
  const suiteMs = Date.now() - suiteStart;
307
410
  info(`Total elapsed: ${suiteMs} ms (${(suiteMs / 1000).toFixed(2)} s)`);
308
411
 
309
412
  if (failed === 0) {
310
- ok(`All examples tests passed (${passed}/${files.length})`);
413
+ ok(`All examples tests passed (${passed}/${totalTests})`);
311
414
  process.exit(0);
312
415
  } else {
313
- fail(`Some examples tests failed (${passed}/${files.length})`);
416
+ fail(`Some examples tests failed (${passed}/${totalTests})`);
314
417
  // keep exit code 2 (matches historical behavior of examples/test)
315
418
  process.exit(2);
316
419
  }