eyeling 1.12.7 → 1.12.8

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/HANDBOOK.md CHANGED
@@ -1972,7 +1972,7 @@ In that sense, N3 is less a bid to make the web “smarter” than a bid to make
1972
1972
 
1973
1973
  ## Appendix C — N3 beyond Prolog: logic for RDF-style graphs
1974
1974
 
1975
- Notation3 (N3) rule sets often look similar to Prolog at the surface: they use variables, unification, and implication-style rules (“if these patterns match, then these patterns follow”). N3 is typically used in a different setting, though: instead of a single program operating over a single local database, N3 rules and data are commonly written as documents that can be published, shared, merged, and referenced across systems.
1975
+ Notation3 (N3) rule sets often look similar to Prolog at the surface: they use variables, unification, and implication-style rules (“if these patterns match, then these patterns follow”). N3 is typically used in a different setting: instead of a single program operating over a single local database, N3 rules and data are commonly written as documents that can be published, shared, merged, and referenced across systems.
1976
1976
 
1977
1977
  In practice, that setting is reflected in several common features of N3-style rule writing:
1978
1978
 
@@ -0,0 +1,117 @@
1
+ # ==================
2
+ # Collatz conjecture
3
+ # ==================
4
+ #
5
+ # Collatz iteration:
6
+ # - if n is even: n ↦ n/2
7
+ # - if n is odd : n ↦ 3n + 1
8
+ #
9
+ # The conjecture states that starting from any positive integer n,
10
+ # repeated application of the rule eventually reaches 1.
11
+ #
12
+ # This N3 program:
13
+ # 1) enumerates test inputs N = 1000, 999, ..., 1 via a backward :repeat relation
14
+ # 2) computes the full Collatz trajectory for each N as an RDF list
15
+ # 3) materializes only the final results as :collatzTrajectory triples
16
+ #
17
+ # See https://en.wikipedia.org/wiki/Collatz_conjecture
18
+
19
+ @prefix : <http://example.org/collatz#> .
20
+ @prefix math: <http://www.w3.org/2000/10/swap/math#> .
21
+ @prefix list: <http://www.w3.org/2000/10/swap/list#> .
22
+
23
+ # -----------------------------------------
24
+ # Query / materialization of the test suite
25
+ # -----------------------------------------
26
+ #
27
+ # Generate N in {1000..1} and ask the backward-defined :collatz predicate
28
+ # for the full trajectory list ?M.
29
+ #
30
+ # Note: we derive N as (1000 - N0) so that N0 ranges over 0..999.
31
+ # This keeps :repeat as a generic “0..N-1” generator.
32
+ #
33
+ # Output predicate is renamed to :collatzTrajectory to keep results separate
34
+ # from the intensional (backward) definition of :collatz.
35
+ {
36
+ 1000 :repeat ?N0 .
37
+ (1000 ?N0) math:difference ?N .
38
+ ?N :collatz ?M .
39
+ }
40
+ =>
41
+ {
42
+ ?N :collatzTrajectory ?M .
43
+ } .
44
+
45
+ # ------------------------
46
+ # Backward range generator
47
+ # ------------------------
48
+ #
49
+ # ?N :repeat ?I enumerates all integers I in the half-open interval:
50
+ # I ∈ [0 .. N-1]
51
+
52
+ # Base case: repeat(1) = {0}
53
+ { ?N :repeat 0 }
54
+ <=
55
+ { ?N math:equalTo 1. } .
56
+
57
+ # For N>1, also include the last value (N-1)
58
+ { ?N :repeat ?I }
59
+ <=
60
+ {
61
+ ?N math:greaterThan 1.
62
+ (?N 1) math:difference ?I. # I = N - 1
63
+ } .
64
+
65
+ # And for N>1, inherit everything from repeat(N-1)
66
+ # (this is the recursive “rest of the range”)
67
+ { ?N :repeat ?I }
68
+ <=
69
+ {
70
+ ?N math:greaterThan 1.
71
+ (?N 1) math:difference ?N1. # N1 = N - 1
72
+ ?N1 :repeat ?I.
73
+ } .
74
+
75
+ # -------------------------
76
+ # Backward Collatz relation
77
+ # -------------------------
78
+ #
79
+ # ?N0 :collatz ?M relates a start value ?N0 to its full Collatz trajectory ?M.
80
+ # The trajectory is represented as an RDF list:
81
+ # - for N0=1: (1)
82
+ # - for N0>1: (N0 ... 1)
83
+ #
84
+ # The recursion is guarded with “N0 > 1” so the base case terminates cleanly.
85
+
86
+ # Base case: 1 terminates immediately
87
+ { ?N0 :collatz (1) }
88
+ <=
89
+ { ?N0 math:equalTo 1. } .
90
+
91
+ # Even step: N0 > 1 and N0 mod 2 = 0 => N1 = N0/2
92
+ # The resulting list is constructed as: (N0) :: collatz(N1)
93
+ { ?N0 :collatz ?M }
94
+ <=
95
+ {
96
+ ?N0 math:greaterThan 1.
97
+ (?N0 2) math:remainder 0.
98
+ (?N0 2) math:integerQuotient ?N1. # N1 = floor(N0/2) (safe because even)
99
+
100
+ ?N1 :collatz ?J.
101
+ ?M list:firstRest (?N0 ?J). # M = [N0 | J]
102
+ } .
103
+
104
+ # Odd step: N0 > 1 and N0 mod 2 = 1 => N1 = 3*N0 + 1
105
+ # Again: (N0) :: collatz(N1)
106
+ { ?N0 :collatz ?M }
107
+ <=
108
+ {
109
+ ?N0 math:greaterThan 1.
110
+ (?N0 2) math:remainder 1.
111
+ (3 ?N0) math:product ?T.
112
+ (?T 1) math:sum ?N1. # N1 = 3*N0 + 1
113
+
114
+ ?N1 :collatz ?J.
115
+ ?M list:firstRest (?N0 ?J). # M = [N0 | J]
116
+ } .
117
+
@@ -0,0 +1,316 @@
1
+ # ==============================
2
+ # Digital Product Passport (DPP)
3
+ # ==============================
4
+ #
5
+ # This file mixes:
6
+ # (A) DPP "facts" (the passport itself)
7
+ # (B) A few N3 rules that derive computed indicators and a summary string
8
+ #
9
+ # Units
10
+ # - Mass is in grams (integers)
11
+ # - Footprint values are in gCO2e (integers)
12
+
13
+ @prefix : <http://example.org/dpp#> .
14
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
15
+ @prefix math: <http://www.w3.org/2000/10/swap/math#> .
16
+ @prefix list: <http://www.w3.org/2000/10/swap/list#> .
17
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
18
+ @prefix string: <http://www.w3.org/2000/10/swap/string#> .
19
+
20
+ # --------------------
21
+ # 1) Actors and places
22
+ # --------------------
23
+
24
+ :AcmeElectronics
25
+ a :Organization;
26
+ :legalName "Acme Electronics NV";
27
+ :vatId "BE0123456789";
28
+ :country "BE".
29
+
30
+ :FactoryBE01
31
+ a :Site;
32
+ :siteName "Acme Assembly Plant BE-01";
33
+ :country "BE".
34
+
35
+ :RepairShop1
36
+ a :Organization;
37
+ :legalName "FixFast Repairs";
38
+ :country "BE".
39
+
40
+ # --------------------------
41
+ # 2) Product + Passport root
42
+ # --------------------------
43
+
44
+ :Passport-ACME-X1000-SN123
45
+ a :DigitalProductPassport;
46
+ :describesProduct :ACME-X1000-SN123;
47
+ :passportVersion "1.0";
48
+ :issuedAt "2026-02-10"^^xsd:date;
49
+ :publicEndpoint <https://example.org/dpp/ACME-X1000-SN123>;
50
+ :accessPolicy :Policy-ACME-DPP.
51
+
52
+ :Policy-ACME-DPP
53
+ a :AccessPolicy;
54
+ :hasSection :Section-Public, :Section-Restricted.
55
+
56
+ :Section-Public
57
+ a :PassportSection;
58
+ :accessLevel :public.
59
+
60
+ :Section-Restricted
61
+ a :PassportSection;
62
+ :accessLevel :restricted;
63
+ :intendedAudience "authorities, auditors, service partners".
64
+
65
+ # ----------------------------------
66
+ # 3) Product identity & traceability
67
+ # ----------------------------------
68
+
69
+ :ACME-X1000-SN123
70
+ a :ProductInstance;
71
+ :model "ACME X1000";
72
+ :serialNumber "SN123";
73
+ :batchId "BATCH-2026-01";
74
+ :madeBy :AcmeElectronics;
75
+ :madeAtSite :FactoryBE01;
76
+ :manufactureDate "2026-01-15"^^xsd:date;
77
+ :category :Smartphone;
78
+ :dpp :Passport-ACME-X1000-SN123;
79
+ :digitalLink "https://example.org/dpp/ACME-X1000-SN123".
80
+
81
+ # ------------------------------
82
+ # 4) Composition (bill of parts)
83
+ # ------------------------------
84
+
85
+ :ACME-X1000-SN123
86
+ :hasComponent :BatteryPack-01, :Chassis-01, :Mainboard-01;
87
+ :componentList ( :BatteryPack-01 :Chassis-01 :Mainboard-01 ).
88
+
89
+ :BatteryPack-01
90
+ a :Component;
91
+ :componentType :Battery;
92
+ :massG 48;
93
+ :recycledMassG 0;
94
+ :replaceable true;
95
+ :containsMaterial :Lithium, :Cobalt, :Nickel.
96
+
97
+ :Chassis-01
98
+ a :Component;
99
+ :componentType :Housing;
100
+ :massG 32;
101
+ :recycledMassG 12;
102
+ :containsMaterial :Aluminium.
103
+
104
+ :Mainboard-01
105
+ a :Component;
106
+ :componentType :Electronics;
107
+ :massG 25;
108
+ :recycledMassG 2;
109
+ :containsMaterial :Copper, :GoldTrace.
110
+
111
+ # Materials (toy taxonomy)
112
+ :Lithium a :Material; :criticalRawMaterial true.
113
+ :Cobalt a :Material; :criticalRawMaterial true.
114
+ :Nickel a :Material; :criticalRawMaterial false.
115
+ :Aluminium a :Material; :criticalRawMaterial false.
116
+ :Copper a :Material; :criticalRawMaterial false.
117
+ :GoldTrace a :Material; :criticalRawMaterial false.
118
+
119
+ # -----------------------------------------------------
120
+ # 5) Documents / claims (public vs restricted sections)
121
+ # -----------------------------------------------------
122
+
123
+ :Passport-ACME-X1000-SN123
124
+ :inSection :Section-Public;
125
+ :hasDocument :Doc-UserManual, :Doc-RepairGuide, :Doc-SpareParts.
126
+
127
+ :Doc-UserManual
128
+ a :Document;
129
+ :docType :UserManual;
130
+ :url <https://example.org/docs/acme-x1000/user-manual.pdf>.
131
+
132
+ :Doc-RepairGuide
133
+ a :Document;
134
+ :docType :RepairGuide;
135
+ :url <https://example.org/docs/acme-x1000/repair-guide.pdf>;
136
+ :declares :BatteryReplacementSupported.
137
+
138
+ :BatteryReplacementSupported
139
+ a :Claim;
140
+ :claimText "Battery is user-replaceable with standard tools.".
141
+
142
+ :Doc-SpareParts
143
+ a :Document;
144
+ :docType :SparePartsCatalog;
145
+ :url <https://example.org/spares/acme-x1000>.
146
+
147
+ :Passport-ACME-X1000-SN123
148
+ :inSection :Section-Restricted;
149
+ :hasDocument :Doc-DoC-CE, :Doc-SubstanceDeclaration.
150
+
151
+ :Doc-DoC-CE
152
+ a :Document;
153
+ :docType :DeclarationOfConformity;
154
+ :url <https://example.org/docs/acme-x1000/ce-doc.pdf>.
155
+
156
+ :Doc-SubstanceDeclaration
157
+ a :Document;
158
+ :docType :SubstanceDeclaration;
159
+ :url <https://example.org/docs/acme-x1000/substances.json>.
160
+
161
+ # --------------------------------
162
+ # 6) Lifecycle events (provenance)
163
+ # --------------------------------
164
+
165
+ :Event-Mfg-01
166
+ a :ManufacturingEvent;
167
+ :forProduct :ACME-X1000-SN123;
168
+ :performedBy :AcmeElectronics;
169
+ :atSite :FactoryBE01;
170
+ :onDate "2026-01-15"^^xsd:date.
171
+
172
+ :Event-Sale-01
173
+ a :SaleEvent;
174
+ :forProduct :ACME-X1000-SN123;
175
+ :onDate "2026-01-25"^^xsd:date;
176
+ :country "BE".
177
+
178
+ :Event-Repair-01
179
+ a :RepairEvent;
180
+ :forProduct :ACME-X1000-SN123;
181
+ :performedBy :RepairShop1;
182
+ :onDate "2026-02-05"^^xsd:date;
183
+ :replacedComponent :BatteryPack-01;
184
+ :inSection :Section-Restricted.
185
+
186
+ # ---------------------------------
187
+ # 7) Environmental footprint inputs
188
+ # ---------------------------------
189
+
190
+ :ACME-X1000-SN123
191
+ :mfgFootprint_gCO2e 32000;
192
+ :transportFootprint_gCO2e 2500;
193
+ :usePhaseFootprint_gCO2e 18000.
194
+
195
+ # ------------------------------------------
196
+ # 8) Rules: derive indicators + summary line
197
+ # ------------------------------------------
198
+
199
+ # 8.1 Fold over the explicit component list to compute total mass and recycled mass.
200
+ #
201
+ # List-level totals are attached to the list node itself:
202
+ # ?L :sumMassG ?m.
203
+ # ?L :sumRecycledG ?r.
204
+ #
205
+ # Then we attach them to the product that owns the list.
206
+
207
+ # Empty list totals
208
+ { () :sumMassG 0. } <= { true. } .
209
+ { () :sumRecycledG 0. } <= { true. } .
210
+
211
+ # Non-empty list: sum(list) = head + sum(tail)
212
+ { ?L :sumMassG ?mTot. }
213
+ <=
214
+ {
215
+ ?L list:firstRest (?C ?Rest).
216
+
217
+ ?C :massG ?m.
218
+
219
+ ?Rest :sumMassG ?mRest.
220
+ (?m ?mRest) math:sum ?mTot.
221
+ } .
222
+
223
+ { ?L :sumRecycledG ?rTot. }
224
+ <=
225
+ {
226
+ ?L list:firstRest (?C ?Rest).
227
+
228
+ ?C :recycledMassG ?r.
229
+
230
+ ?Rest :sumRecycledG ?rRest.
231
+ (?r ?rRest) math:sum ?rTot.
232
+ } .
233
+
234
+ # Attach totals to the product
235
+ {
236
+ ?P :componentList ?L.
237
+ ?L :sumMassG ?mTot.
238
+ ?L :sumRecycledG ?rTot.
239
+ }
240
+ =>
241
+ {
242
+ ?P :totalMassG ?mTot.
243
+ ?P :recycledMassG ?rTot.
244
+ } .
245
+
246
+ # 8.2 Recycled content percentage (integer % floor)
247
+ # pct = floor( recycledMassG * 100 / totalMassG )
248
+ {
249
+ ?P :totalMassG ?mTot.
250
+ ?P :recycledMassG ?rTot.
251
+ (?rTot 100) math:product ?r100.
252
+ (?r100 ?mTot) math:integerQuotient ?pct.
253
+ }
254
+ =>
255
+ {
256
+ ?P :recycledContentPct ?pct.
257
+ } .
258
+
259
+ # 8.3 Lifecycle footprint total (gCO2e)
260
+ {
261
+ ?P :mfgFootprint_gCO2e ?a.
262
+ ?P :transportFootprint_gCO2e ?b.
263
+ ?P :usePhaseFootprint_gCO2e ?c.
264
+ (?a ?b) math:sum ?ab.
265
+ (?ab ?c) math:sum ?tot.
266
+ }
267
+ =>
268
+ {
269
+ ?P :lifecycleFootprint_gCO2e ?tot.
270
+ } .
271
+
272
+ # 8.4 Simple "circularity hint": battery replaceable + spare parts catalog exists
273
+ {
274
+ ?P :hasComponent ?B.
275
+ ?B :componentType :Battery.
276
+ ?B :replaceable true.
277
+
278
+ ?Passport :describesProduct ?P.
279
+ ?Passport :hasDocument ?Doc.
280
+ ?Doc :docType :SparePartsCatalog.
281
+ }
282
+ =>
283
+ {
284
+ ?P :circularityHint :repairFriendly.
285
+ } .
286
+
287
+ # 8.5 Flag: contains a critical raw material
288
+ {
289
+ ?P :hasComponent ?C.
290
+ ?C :containsMaterial ?M.
291
+ ?M :criticalRawMaterial true.
292
+ }
293
+ =>
294
+ {
295
+ ?P :containsCriticalRawMaterial true.
296
+ } .
297
+
298
+ # 8.6 Optional compact summary line (one per product)
299
+ #
300
+ # Example:
301
+ # ACME X1000 SN123 | recycled=13% | lifecycle=52500 gCO2e | CRM=true | hint=repairFriendly
302
+ {
303
+ ?P :model ?model.
304
+ ?P :serialNumber ?sn.
305
+ ?P :recycledContentPct ?pct.
306
+ ?P :lifecycleFootprint_gCO2e ?co2.
307
+ ?P :containsCriticalRawMaterial ?crm.
308
+ ?P :circularityHint ?hint.
309
+
310
+ ("%s %s | recycled=%s%% | lifecycle=%s gCO2e | CRM=%s | hint=%s\n"
311
+ ?model ?sn ?pct ?co2 ?crm ?hint) string:format ?line.
312
+ }
313
+ =>
314
+ {
315
+ ?P log:outputString ?line.
316
+ } .
@@ -0,0 +1,107 @@
1
+ # ===================================================================================
2
+ # A tiny RDF(+rules) knowledge base about:
3
+ # "Incompleteness: The Proof and Paradox of Kurt Gödel" — Rebecca Newberger Goldstein
4
+ # ===================================================================================
5
+
6
+ @prefix ex: <http://example.org/incompleteness/> .
7
+ @prefix schema: <http://schema.org/> .
8
+ @prefix dct: <http://purl.org/dc/terms/> .
9
+ @prefix bibo: <http://purl.org/ontology/bibo/> .
10
+ @prefix foaf: <http://xmlns.com/foaf/0.1/> .
11
+ @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
12
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
13
+
14
+ # -----
15
+ # Facts
16
+ # -----
17
+
18
+ ex:book2005
19
+ a schema:Book, bibo:Book ;
20
+ dct:title "Incompleteness: The Proof and Paradox of Kurt Gödel"@en ;
21
+ schema:name "Incompleteness: The Proof and Paradox of Kurt Gödel"@en ;
22
+ schema:author ex:rebeccaGoldstein ;
23
+ schema:publisher ex:wwNorton ;
24
+ dct:issued "2005"^^xsd:gYear ;
25
+ schema:inLanguage "en" ;
26
+ schema:numberOfPages 296 ;
27
+ bibo:isbn10 "0393051692" ;
28
+ bibo:isbn13 "9780393051698" ;
29
+ bibo:oclcnum "860568768" ;
30
+ schema:about ex:kurtGodel,
31
+ ex:godelIncompletenessTheorems,
32
+ ex:hilbertsProgram,
33
+ ex:platonismInMath ;
34
+ schema:genre "biography", "mathematics", "philosophy of mathematics" ;
35
+ schema:description
36
+ "A biographical and intellectual portrait of Gödel, explaining the incompleteness theorems and their philosophical context."@en .
37
+
38
+ ex:rebeccaGoldstein
39
+ a foaf:Person, schema:Person ;
40
+ foaf:name "Rebecca Newberger Goldstein" .
41
+
42
+ ex:kurtGodel
43
+ a foaf:Person, schema:Person ;
44
+ foaf:name "Kurt Gödel" .
45
+
46
+ ex:wwNorton
47
+ a schema:Organization ;
48
+ schema:name "W. W. Norton & Company" ;
49
+ schema:location "New York" .
50
+
51
+ # ----------------------------
52
+ # Topic concepts (simple SKOS)
53
+ # ----------------------------
54
+
55
+ ex:godelIncompletenessTheorems
56
+ a skos:Concept ;
57
+ skos:prefLabel "Gödel's incompleteness theorems"@en ;
58
+ skos:broader ex:mathematicalLogic .
59
+
60
+ ex:hilbertsProgram
61
+ a skos:Concept ;
62
+ skos:prefLabel "Hilbert's program"@en ;
63
+ skos:broader ex:foundationsOfMathematics .
64
+
65
+ ex:platonismInMath
66
+ a skos:Concept ;
67
+ skos:prefLabel "Platonism in mathematics"@en ;
68
+ skos:broader ex:philosophyOfMathematics .
69
+
70
+ ex:mathematicalLogic
71
+ a skos:Concept ;
72
+ skos:prefLabel "Mathematical logic"@en .
73
+
74
+ ex:foundationsOfMathematics
75
+ a skos:Concept ;
76
+ skos:prefLabel "Foundations of mathematics"@en .
77
+
78
+ ex:philosophyOfMathematics
79
+ a skos:Concept ;
80
+ skos:prefLabel "Philosophy of mathematics"@en .
81
+
82
+ # -----------------------
83
+ # Rules (N3 implications)
84
+ # -----------------------
85
+
86
+ # 1) Invert author → made
87
+ { ?book schema:author ?person . }
88
+ => { ?person foaf:made ?book . } .
89
+
90
+ # 2) If a book is about a person, infer reverse subjectOf
91
+ { ?book schema:about ?person .
92
+ ?person a foaf:Person . }
93
+ => { ?person schema:subjectOf ?book . } .
94
+
95
+ # 3) If it’s about incompleteness theorems, tag it as mathematical logic
96
+ { ?book schema:about ex:godelIncompletenessTheorems . }
97
+ => { ?book dct:subject ex:mathematicalLogic . } .
98
+
99
+ # 4) Tiny “recommendation” rule (demo of deriving new facts)
100
+ { ?book dct:subject ex:mathematicalLogic ;
101
+ schema:inLanguage "en" . }
102
+ => { ?book ex:recommendedFor ex:logicLearnerEn . } .
103
+
104
+ ex:logicLearnerEn
105
+ a skos:Concept ;
106
+ skos:prefLabel "English-reading logic learner"@en .
107
+
@@ -0,0 +1,117 @@
1
+ # ======================================
2
+ # Goldbach conjecture (bounded checker)
3
+ # ======================================
4
+ # Strong (even) Goldbach:
5
+ # Every even integer E > 2 can be written as E = P + Q with P,Q prime.
6
+ #
7
+ # Performance notes (Eyeling):
8
+ # - Avoid forward "successor" rules that generate 0..N step-by-step across many
9
+ # saturation passes. Eyeling re-runs forward rules until fixpoint.
10
+ # - Use a backward range predicate (:repeat) so enumeration happens inside one
11
+ # backward proof search.
12
+ # - Cache primes as facts (:isPrime true) once; then Goldbach checking is cheap.
13
+
14
+ @prefix : <http://example.org/goldbach#> .
15
+ @prefix math: <http://www.w3.org/2000/10/swap/math#> .
16
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
17
+ @prefix string:<http://www.w3.org/2000/10/swap/string#> .
18
+
19
+ :cfg :maxEven 1000 .
20
+
21
+ # -------------------------------------------------
22
+ # Backward range: ?N :repeat ?I gives I in [0..N-1]
23
+ # -------------------------------------------------
24
+
25
+ { ?N :repeat 0 }
26
+ <=
27
+ { ?N math:equalTo 1 } .
28
+
29
+ { ?N :repeat ?I }
30
+ <=
31
+ {
32
+ ?N math:greaterThan 1.
33
+ (?N 1) math:difference ?N1.
34
+ ?N1 :repeat ?I.
35
+ } .
36
+
37
+ { ?N :repeat ?I }
38
+ <=
39
+ {
40
+ ?N math:greaterThan 1.
41
+ (?N 1) math:difference ?I.
42
+ } .
43
+
44
+ # --------------------------------------------
45
+ # Backward primality (trial division by odd D)
46
+ # --------------------------------------------
47
+
48
+ { 2 :prime true } <= { true } .
49
+
50
+ { ?N :prime true }
51
+ <=
52
+ {
53
+ ?N math:greaterThan 2.
54
+ (?N 2) math:remainder 1.
55
+ (?N 3) :primeTrial true.
56
+ } .
57
+
58
+ { (?N ?D) :primeTrial true }
59
+ <=
60
+ {
61
+ (?D ?D) math:product ?DD.
62
+ ?DD math:greaterThan ?N.
63
+ } .
64
+
65
+ { (?N ?D) :primeTrial true }
66
+ <=
67
+ {
68
+ (?D ?D) math:product ?DD.
69
+ ?DD math:notGreaterThan ?N.
70
+
71
+ (?N ?D) math:remainder ?R.
72
+ ?R math:notEqualTo 0.
73
+
74
+ (?D 2) math:sum ?D2.
75
+ (?N ?D2) :primeTrial true.
76
+ } .
77
+
78
+ # ------------------------------------------------------
79
+ # 1) Cache primes up to maxEven (enumerated via :repeat)
80
+ # ------------------------------------------------------
81
+
82
+ {
83
+ :cfg :maxEven ?Max.
84
+ (?Max 1) math:difference ?R. # R = Max-1
85
+ ?R :repeat ?I. # I in [0..Max-2]
86
+ (?I 2) math:sum ?N. # N in [2..Max]
87
+ ?N :prime true.
88
+ }
89
+ =>
90
+ {
91
+ ?N :isPrime true.
92
+ } .
93
+
94
+ # ---------------------------------------------
95
+ # 2) Goldbach OK for all even E in [4..maxEven]
96
+ # Enumerate E by K in [2..Max/2] then E=2*K
97
+ # ---------------------------------------------
98
+
99
+ {
100
+ :cfg :maxEven ?Max.
101
+ (?Max 2) math:integerQuotient ?MaxK. # MaxK = Max/2
102
+ (?MaxK 1) math:difference ?RK. # RK = MaxK-1
103
+ ?RK :repeat ?I. # I in [0..MaxK-2]
104
+ (?I 2) math:sum ?K. # K in [2..MaxK]
105
+ (?K 2) math:product ?E. # E = 2*K (even, >=4)
106
+
107
+ (?E 2) math:integerQuotient ?Half. # Half = E/2
108
+ ?P :isPrime true.
109
+ ?P math:notGreaterThan ?Half.
110
+ (?E ?P) math:difference ?Q.
111
+ ?Q :isPrime true.
112
+ }
113
+ =>
114
+ {
115
+ ?E :goldbachOk true.
116
+ } .
117
+