eyeling 1.14.13 → 1.15.0

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.
Files changed (29) hide show
  1. package/examples/check/input/deep-taxonomy-100000.c +20 -0
  2. package/examples/check/input/gps.c +127 -0
  3. package/examples/check/input/high-trust-rdf-bloom-envelope.c +148 -0
  4. package/examples/check/input/high-trust-rdf-bloom-tamper-contrast.c +247 -0
  5. package/examples/check/input/odrl-dpv-risk-ranked.c +275 -0
  6. package/examples/check/output/deep-taxonomy-100000.n3 +300004 -0
  7. package/examples/check/output/gps.n3 +6 -0
  8. package/examples/check/output/high-trust-rdf-bloom-envelope.n3 +7 -0
  9. package/examples/check/output/high-trust-rdf-bloom-tamper-contrast.n3 +27 -0
  10. package/examples/check/output/odrl-dpv-risk-ranked.n3 +13 -0
  11. package/examples/decimal-ebike-motor-thermal-envelope.n3 +286 -0
  12. package/examples/decimal-transcendental-servo-envelope.n3 +197 -0
  13. package/examples/deck/high-trust-rdf-bloom-envelope.md +371 -0
  14. package/examples/deck/schema-foaf-mapping.md +3 -1
  15. package/examples/high-trust-rdf-bloom-envelope.n3 +281 -0
  16. package/examples/high-trust-rdf-bloom-tamper-contrast.n3 +395 -0
  17. package/examples/integer-first-control-tank-level.n3 +209 -0
  18. package/examples/integer-first-sqrt2-mediants.n3 +174 -0
  19. package/examples/output/decimal-ebike-motor-thermal-envelope.n3 +25 -0
  20. package/examples/output/decimal-transcendental-servo-envelope.n3 +29 -0
  21. package/examples/output/high-trust-rdf-bloom-envelope.n3 +7 -0
  22. package/examples/output/high-trust-rdf-bloom-tamper-contrast.n3 +27 -0
  23. package/examples/output/integer-first-control-tank-level.n3 +70 -0
  24. package/examples/output/integer-first-sqrt2-mediants.n3 +57 -0
  25. package/eyeling.js +90 -1
  26. package/lib/lexer.js +90 -1
  27. package/package.json +3 -2
  28. package/test/api.test.js +221 -0
  29. package/test/check.test.js +174 -0
@@ -0,0 +1,395 @@
1
+ # =============================================================================
2
+ # High-trust RDF Bloom filter hardening: trusted artifact vs tampered artifact
3
+ #
4
+ # Why this example exists:
5
+ # It stresses why the hardening matters. The file contains two artifacts:
6
+ #
7
+ # 1) a trusted artifact with sane parameters and a matching decimal
8
+ # certificate for exp(-lambda)
9
+ # 2) a tampered artifact with bogus numbers that can still look "cheap"
10
+ # under weak budget-only checks because a malformed upper bound becomes a
11
+ # large negative number
12
+ #
13
+ # Main lesson:
14
+ # Weak checks can be fooled by malformed intermediate values.
15
+ # Hardened checks make acceptance depend on explicit sanity conditions and on
16
+ # a certificate that is well-formed and tied to the computed lambda.
17
+ #
18
+ # What the file demonstrates:
19
+ # * :trustedArtifact is accepted under both the weak and hardened rules
20
+ # * :tamperedArtifact can pass the weak budget-only path
21
+ # * :tamperedArtifact is rejected by the hardened path, with explicit reasons
22
+ # =============================================================================
23
+
24
+ @prefix : <http://example.org/high-trust-rdf#>.
25
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
26
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
27
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
28
+
29
+ # -----------------
30
+ # Trusted artifact
31
+ # -----------------
32
+
33
+ :trustedArtifact a :HighTrustRdfArtifact;
34
+ :canonicalTripleCount 1200;
35
+ :spoIndexTripleCount 1200;
36
+ :bloomBits 16384;
37
+ :hashFunctions 7;
38
+ :negativeLookupsPerBatch 50000;
39
+ :fpRateBudget 0.002;
40
+ :extraExactLookupsBudget 100.0;
41
+ :exactTranscendentalSymbol "exp(-k*n/m)";
42
+ :certifiedLambda 0.5126953125;
43
+ :expMinusLambdaLower 0.5988792348;
44
+ :expMinusLambdaUpper 0.5988792349;
45
+ :maybePositivePolicy :ConfirmAgainstCanonicalGraph;
46
+ :definiteNegativePolicy :ReturnAbsent.
47
+
48
+ # ------------------
49
+ # Tampered artifact
50
+ # ------------------
51
+
52
+ :tamperedArtifact a :HighTrustRdfArtifact;
53
+ :canonicalTripleCount 1200;
54
+ :spoIndexTripleCount 1200;
55
+ :bloomBits -12;
56
+ :hashFunctions 7;
57
+ :negativeLookupsPerBatch 1;
58
+ :fpRateBudget 0.1;
59
+ :extraExactLookupsBudget 100.0;
60
+ :exactTranscendentalSymbol "whatever an attacker writes here";
61
+ :certifiedLambda 0.5126953125;
62
+ :expMinusLambdaLower 42;
63
+ :expMinusLambdaUpper -42;
64
+ :maybePositivePolicy :ConfirmAgainstCanonicalGraph;
65
+ :definiteNegativePolicy :ReturnAbsent.
66
+
67
+ # -------------------------------------------------
68
+ # Exact structural agreement of graph and SPO index
69
+ # -------------------------------------------------
70
+
71
+ {
72
+ ?a :canonicalTripleCount ?n;
73
+ :spoIndexTripleCount ?n.
74
+ }
75
+ =>
76
+ {
77
+ ?a :indexAgreement true.
78
+ ?a :tripleCount ?n.
79
+ }.
80
+
81
+ # -------------------------------------------
82
+ # Exact load factor lambda = k*n/m as decimal
83
+ # -------------------------------------------
84
+
85
+ {
86
+ ?a :tripleCount ?n;
87
+ :hashFunctions ?k;
88
+ :bloomBits ?m.
89
+ ( ?k ?n ) math:product ?kn.
90
+ ( ?kn ?m ) math:quotient ?lambda.
91
+ }
92
+ =>
93
+ {
94
+ ?a :lambda ?lambda.
95
+ }.
96
+
97
+ # ==========================
98
+ # Weak path (pre-hardening)
99
+ # ==========================
100
+ # This path deliberately computes a budget envelope from whatever numbers were
101
+ # supplied, without first proving that they form a sane certificate.
102
+
103
+ {
104
+ ?a :hashFunctions ?k;
105
+ :expMinusLambdaLower ?eLo;
106
+ :expMinusLambdaUpper ?eHi.
107
+ ( 1.0 ?eHi ) math:difference ?oneMinusLo.
108
+ ( 1.0 ?eLo ) math:difference ?oneMinusHi.
109
+ ( ?oneMinusLo ?k ) math:exponentiation ?fpLo.
110
+ ( ?oneMinusHi ?k ) math:exponentiation ?fpHi.
111
+ }
112
+ =>
113
+ {
114
+ ?a :weakFpRateLower ?fpLo;
115
+ :weakFpRateUpper ?fpHi.
116
+ }.
117
+
118
+ {
119
+ ?a :weakFpRateUpper ?fpHi;
120
+ :fpRateBudget ?budget.
121
+ ?fpHi math:lessThan ?budget.
122
+ }
123
+ =>
124
+ {
125
+ ?a :weakWithinFpRateBudget true.
126
+ }.
127
+
128
+ {
129
+ ?a :negativeLookupsPerBatch ?q;
130
+ :weakFpRateUpper ?fpHi.
131
+ ( ?q ?fpHi ) math:product ?extraHi.
132
+ }
133
+ =>
134
+ {
135
+ ?a :weakExpectedExtraExactLookupsUpper ?extraHi.
136
+ }.
137
+
138
+ {
139
+ ?a :weakExpectedExtraExactLookupsUpper ?extraHi;
140
+ :extraExactLookupsBudget ?budget.
141
+ ?extraHi math:lessThan ?budget.
142
+ }
143
+ =>
144
+ {
145
+ ?a :weakWithinExactLookupBudget true.
146
+ }.
147
+
148
+ {
149
+ ?a :indexAgreement true;
150
+ :weakWithinFpRateBudget true;
151
+ :weakWithinExactLookupBudget true;
152
+ :maybePositivePolicy :ConfirmAgainstCanonicalGraph;
153
+ :definiteNegativePolicy :ReturnAbsent.
154
+ }
155
+ =>
156
+ {
157
+ ?a :weakDecision :AcceptUnderWeakBudgetOnlyRules.
158
+ }.
159
+
160
+ # ==============================
161
+ # Hardened path (current design)
162
+ # ==============================
163
+
164
+ # Parameter sanity is explicit and required.
165
+ {
166
+ ?a :canonicalTripleCount ?n;
167
+ :spoIndexTripleCount ?s;
168
+ :bloomBits ?m;
169
+ :hashFunctions ?k;
170
+ :negativeLookupsPerBatch ?q;
171
+ :fpRateBudget ?r;
172
+ :extraExactLookupsBudget ?e.
173
+ ?n math:greaterThan 0.
174
+ ?s math:greaterThan 0.
175
+ ?m math:greaterThan 0.
176
+ ?k math:greaterThan 0.
177
+ ?q math:greaterThan 0.
178
+ ?r math:greaterThan 0.
179
+ ?e math:greaterThan 0.
180
+ }
181
+ =>
182
+ {
183
+ ?a :parameterSanity true.
184
+ }.
185
+
186
+ # A matching and well-formed interval certificate is explicit and required.
187
+ {
188
+ ?a :lambda ?lambda;
189
+ :certifiedLambda ?lambda;
190
+ :expMinusLambdaLower ?lo;
191
+ :expMinusLambdaUpper ?hi.
192
+ ?lambda math:greaterThan 0.
193
+ ?lo math:lessThan ?hi.
194
+ ?lo math:greaterThan 0.
195
+ ?hi math:lessThan 1.
196
+ }
197
+ =>
198
+ {
199
+ ?a :expIntervalCertificate :CertifiedDecimalInterval.
200
+ }.
201
+
202
+ # Hardened envelope uses only a certified interval.
203
+ {
204
+ ?a :expIntervalCertificate :CertifiedDecimalInterval;
205
+ :hashFunctions ?k;
206
+ :expMinusLambdaLower ?eLo;
207
+ :expMinusLambdaUpper ?eHi.
208
+ ( 1.0 ?eHi ) math:difference ?oneMinusLo.
209
+ ( 1.0 ?eLo ) math:difference ?oneMinusHi.
210
+ ( ?oneMinusLo ?k ) math:exponentiation ?fpLo.
211
+ ( ?oneMinusHi ?k ) math:exponentiation ?fpHi.
212
+ }
213
+ =>
214
+ {
215
+ ?a :fpRateLower ?fpLo;
216
+ :fpRateUpper ?fpHi.
217
+ }.
218
+
219
+ {
220
+ ?a :fpRateUpper ?fpHi;
221
+ :fpRateBudget ?budget.
222
+ ?fpHi math:greaterThan 0.
223
+ ?fpHi math:lessThan ?budget.
224
+ }
225
+ =>
226
+ {
227
+ ?a :withinFpRateBudget true.
228
+ }.
229
+
230
+ {
231
+ ?a :negativeLookupsPerBatch ?q;
232
+ :fpRateUpper ?fpHi.
233
+ ( ?q ?fpHi ) math:product ?extraHi.
234
+ }
235
+ =>
236
+ {
237
+ ?a :expectedExtraExactLookupsUpper ?extraHi.
238
+ }.
239
+
240
+ {
241
+ ?a :expectedExtraExactLookupsUpper ?extraHi;
242
+ :extraExactLookupsBudget ?budget.
243
+ ?extraHi math:greaterThan 0.
244
+ ?extraHi math:lessThan ?budget.
245
+ }
246
+ =>
247
+ {
248
+ ?a :withinExactLookupBudget true.
249
+ }.
250
+
251
+ {
252
+ ?a :parameterSanity true;
253
+ :indexAgreement true;
254
+ :expIntervalCertificate :CertifiedDecimalInterval;
255
+ :withinFpRateBudget true;
256
+ :withinExactLookupBudget true;
257
+ :maybePositivePolicy :ConfirmAgainstCanonicalGraph;
258
+ :definiteNegativePolicy :ReturnAbsent.
259
+ }
260
+ =>
261
+ {
262
+ ?a :hardenedDecision :AcceptForHighTrustUse.
263
+ }.
264
+
265
+ # ======================================
266
+ # Explicit tamper evidence / reject path
267
+ # ======================================
268
+ # These rules make hardening visible in the output.
269
+
270
+ {
271
+ ?a :bloomBits ?m.
272
+ ?m math:notGreaterThan 0.
273
+ }
274
+ =>
275
+ {
276
+ ?a :rejectReason :NonPositiveBloomBits.
277
+ }.
278
+
279
+ {
280
+ ?a :lambda ?lambda;
281
+ :certifiedLambda ?certified.
282
+ ?certified math:notEqualTo ?lambda.
283
+ }
284
+ =>
285
+ {
286
+ ?a :rejectReason :CertifiedLambdaMismatch.
287
+ }.
288
+
289
+ {
290
+ ?a :expMinusLambdaLower ?lo;
291
+ :expMinusLambdaUpper ?hi.
292
+ ?hi math:notGreaterThan ?lo.
293
+ }
294
+ =>
295
+ {
296
+ ?a :rejectReason :MalformedIntervalOrdering.
297
+ }.
298
+
299
+ {
300
+ ?a :expMinusLambdaLower ?lo.
301
+ ?lo math:notGreaterThan 0.
302
+ }
303
+ =>
304
+ {
305
+ ?a :rejectReason :NonPositiveIntervalLowerBound.
306
+ }.
307
+
308
+ {
309
+ ?a :expMinusLambdaUpper ?hi.
310
+ ?hi math:notLessThan 1.
311
+ }
312
+ =>
313
+ {
314
+ ?a :rejectReason :IntervalUpperBoundNotBelowOne.
315
+ }.
316
+
317
+ {
318
+ ?a :rejectReason ?why.
319
+ }
320
+ =>
321
+ {
322
+ ?a :hardenedDecision :RejectForHighTrustUse.
323
+ }.
324
+
325
+
326
+ # ---------------------------------
327
+ # Explicit contrast for wide readers
328
+ # ---------------------------------
329
+
330
+ {
331
+ :trustedArtifact :weakDecision :AcceptUnderWeakBudgetOnlyRules;
332
+ :hardenedDecision :AcceptForHighTrustUse.
333
+ }
334
+ =>
335
+ {
336
+ :result :trustedArtifactBehavesAsExpected true.
337
+ }.
338
+
339
+ {
340
+ :tamperedArtifact :weakDecision :AcceptUnderWeakBudgetOnlyRules;
341
+ :hardenedDecision :RejectForHighTrustUse.
342
+ }
343
+ =>
344
+ {
345
+ :result :tamperedArtifactShowsWhyHardeningMatters true.
346
+ }.
347
+
348
+ {
349
+ ?a :weakDecision ?weak;
350
+ :hardenedDecision ?hard.
351
+ }
352
+ log:query
353
+ {
354
+ :result :decision [
355
+ :artifact ?a;
356
+ :weak ?weak;
357
+ :hardened ?hard
358
+ ].
359
+ }.
360
+
361
+ # ---------------
362
+ # Readable output
363
+ # ---------------
364
+
365
+ {
366
+ ?a :lambda ?lambda;
367
+ :certifiedLambda ?certifiedLambda;
368
+ :weakFpRateUpper ?weakFpHi;
369
+ :weakExpectedExtraExactLookupsUpper ?weakExtraHi;
370
+ :weakDecision ?weakDecision;
371
+ :hardenedDecision ?hardDecision.
372
+ }
373
+ log:query
374
+ {
375
+ :result :summary (
376
+ ?a
377
+ "lambda" ?lambda
378
+ "certified-lambda" ?certifiedLambda
379
+ "weak-fp-upper" ?weakFpHi
380
+ "weak-extra-exact-upper" ?weakExtraHi
381
+ "weak-decision" ?weakDecision
382
+ "hardened-decision" ?hardDecision
383
+ ).
384
+ }.
385
+
386
+ {
387
+ ?a :rejectReason ?why.
388
+ }
389
+ log:query
390
+ {
391
+ :result :rejectReason [
392
+ :artifact ?a;
393
+ :why ?why
394
+ ].
395
+ }.
@@ -0,0 +1,209 @@
1
+ # =======================================================================================
2
+ # Integer-first sampled tank-level control
3
+ #
4
+ # Why this example exists:
5
+ # It shows a control-engineering pattern in a genuinely integer-first style.
6
+ # The plant state is a water level in integer millimetres. The controller reads that
7
+ # level once per sample, chooses an integer valve opening, and the plant updates by an
8
+ # exact integer balance law.
9
+ #
10
+ # Plant and controller:
11
+ # level(k+1) = level(k) + valve(k) - outflow
12
+ # with outflow = 2 mm/sample and valve in {0,1,2,3,4}.
13
+ #
14
+ # Control law around setpoint 20 mm:
15
+ # level < 16 -> valve = 4 (net +2)
16
+ # 16 <= level < 19 -> valve = 3 (net +1)
17
+ # 19 <= level <= 21 -> valve = 2 (net 0)
18
+ # 21 < level <= 24 -> valve = 1 (net -1)
19
+ # 24 < level -> valve = 0 (net -2)
20
+ #
21
+ # What is certified:
22
+ # * every closed-loop transition is exact integer arithmetic
23
+ # * the absolute error to the setpoint shrinks whenever it is still > 1
24
+ # * once the level enters the hold band [19,21], it stays there exactly
25
+ #
26
+ # This is “integer-first” because the certifying part of the reasoning uses only counts,
27
+ # comparisons, sums, and differences. No floating point is needed to explain why the loop
28
+ # behaves safely.
29
+ # =======================================================================================
30
+
31
+ @prefix : <http://example.org/integer-control#>.
32
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
33
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
34
+
35
+ # ----------
36
+ # Parameters
37
+ # ----------
38
+
39
+ :controller a :SampledTankController;
40
+ :setpoint 20;
41
+ :outflow 2;
42
+ :maxStep 8.
43
+
44
+ :trialLow a :ClosedLoopTrial; :initialLevel 12.
45
+ :trialHigh a :ClosedLoopTrial; :initialLevel 28.
46
+ :trialNominal a :ClosedLoopTrial; :initialLevel 20.
47
+
48
+ # -----------------
49
+ # Initial condition
50
+ # -----------------
51
+
52
+ { ?trial a :ClosedLoopTrial; :initialLevel ?level0. }
53
+ =>
54
+ { ?trial :levelAt (0 ?level0). }.
55
+
56
+ # ------------------------------
57
+ # Integer control law by regions
58
+ # ------------------------------
59
+
60
+ { ?trial :levelAt (?k ?level). ?level math:lessThan 16. }
61
+ =>
62
+ { ?trial :valveAt (?k 4). }.
63
+
64
+ {
65
+ ?trial :levelAt (?k ?level).
66
+ ?level math:notLessThan 16.
67
+ ?level math:lessThan 19.
68
+ }
69
+ =>
70
+ { ?trial :valveAt (?k 3). }.
71
+
72
+ {
73
+ ?trial :levelAt (?k ?level).
74
+ ?level math:notLessThan 19.
75
+ ?level math:notGreaterThan 21.
76
+ }
77
+ =>
78
+ { ?trial :valveAt (?k 2). }.
79
+
80
+ {
81
+ ?trial :levelAt (?k ?level).
82
+ ?level math:greaterThan 21.
83
+ ?level math:notGreaterThan 24.
84
+ }
85
+ =>
86
+ { ?trial :valveAt (?k 1). }.
87
+
88
+ { ?trial :levelAt (?k ?level). ?level math:greaterThan 24. }
89
+ =>
90
+ { ?trial :valveAt (?k 0). }.
91
+
92
+ # -----------------------
93
+ # Exact plant propagation
94
+ # -----------------------
95
+
96
+ {
97
+ :controller :maxStep ?max; :outflow ?outflow.
98
+ ?trial a :ClosedLoopTrial.
99
+ ?trial :levelAt (?k ?level).
100
+ ?trial :valveAt (?k ?valve).
101
+ ?k math:lessThan ?max.
102
+
103
+ ( ?k 1 ) math:sum ?k1.
104
+ ( ?level ?valve ) math:sum ?inflowed.
105
+ ( ?inflowed ?outflow ) math:difference ?nextLevel.
106
+ }
107
+ =>
108
+ { ?trial :levelAt (?k1 ?nextLevel). }.
109
+
110
+ # ------------------------------------
111
+ # Exact absolute error to the setpoint
112
+ # ------------------------------------
113
+
114
+ {
115
+ :controller :setpoint ?sp.
116
+ ?trial :levelAt (?k ?level).
117
+ ?level math:lessThan ?sp.
118
+ ( ?sp ?level ) math:difference ?error.
119
+ }
120
+ =>
121
+ {
122
+ ?trial :errorAt (?k ?error).
123
+ ?trial :sideAt (?k :below).
124
+ }.
125
+
126
+ {
127
+ :controller :setpoint ?sp.
128
+ ?trial :levelAt (?k ?level).
129
+ ?level math:notLessThan ?sp.
130
+ ( ?level ?sp ) math:difference ?error.
131
+ }
132
+ =>
133
+ {
134
+ ?trial :errorAt (?k ?error).
135
+ ?trial :sideAt (?k :aboveOrOn).
136
+ }.
137
+
138
+ # -----------------------------------------------------------
139
+ # If the absolute error is still > 1, the next one is smaller
140
+ # -----------------------------------------------------------
141
+
142
+ {
143
+ ?trial :errorAt (?k ?error).
144
+ ?error math:greaterThan 1.
145
+ ( ?k 1 ) math:sum ?k1.
146
+ ?trial :errorAt (?k1 ?nextError).
147
+ ?nextError math:lessThan ?error.
148
+ }
149
+ =>
150
+ { ?trial :strictImprovementAt ?k. }.
151
+
152
+ # -----------------------------------------------------------
153
+ # In the hold band [19,21], valve = 2 and the level is fixed
154
+ # -----------------------------------------------------------
155
+
156
+ {
157
+ ?trial :levelAt (?k ?level).
158
+ ?trial :valveAt (?k 2).
159
+ ?level math:notLessThan 19.
160
+ ?level math:notGreaterThan 21.
161
+ ( ?k 1 ) math:sum ?k1.
162
+ ?trial :levelAt (?k1 ?nextLevel).
163
+ ?nextLevel math:equalTo ?level.
164
+ }
165
+ =>
166
+ {
167
+ ?trial :holdBandAt ?k.
168
+ ?trial :invariantStepAt ?k.
169
+ }.
170
+
171
+ # ----------------
172
+ # Compact queries
173
+ # ----------------
174
+
175
+ {
176
+ ?trial :levelAt (?k ?level).
177
+ ?trial :valveAt (?k ?valve).
178
+ ?trial :errorAt (?k ?error).
179
+ }
180
+ log:query
181
+ {
182
+ :result :trace (?trial ?k ?level ?valve ?error).
183
+ }.
184
+
185
+ {
186
+ ?trial :strictImprovementAt ?k.
187
+ }
188
+ log:query
189
+ {
190
+ :result :strictImprovement (?trial ?k true).
191
+ }.
192
+
193
+ {
194
+ ?trial :holdBandAt ?k.
195
+ }
196
+ log:query
197
+ {
198
+ :result :holdBand (?trial ?k true).
199
+ }.
200
+
201
+ {
202
+ ?trial :levelAt (?k ?level).
203
+ ?level math:notLessThan 19.
204
+ ?level math:notGreaterThan 21.
205
+ }
206
+ log:query
207
+ {
208
+ :result :insideBand (?trial ?k ?level).
209
+ }.