eyeling 1.14.4 → 1.14.6
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 +0 -6
- package/examples/deck/schema-foaf-mapping.md +219 -0
- package/examples/genetic-algorithm-knapsack.n3 +260 -0
- package/examples/n3-delegation-access.n3 +153 -0
- package/examples/n3-speaks-for-itself.n3 +118 -0
- package/examples/output/genetic-algorithm-knapsack.n3 +3 -0
- package/examples/output/n3-delegation-access.n3 +31 -0
- package/examples/output/n3-speaks-for-itself.n3 +52 -0
- package/examples/output/schema-foaf-mapping.n3 +7 -0
- package/examples/output/transcendental-families.n3 +210 -0
- package/examples/output/transcendental-lab.n3 +113 -0
- package/examples/output/transcendental-names-and-families.n3 +140 -0
- package/examples/output/transcendental-numbers-stretched.n3 +260 -0
- package/examples/output/transcendental-numbers.n3 +44 -0
- package/examples/schema-foaf-mapping.n3 +52 -0
- package/examples/transcendental-families.n3 +309 -0
- package/examples/transcendental-lab.n3 +262 -0
- package/examples/transcendental-names-and-families.n3 +263 -0
- package/examples/transcendental-numbers-stretched.n3 +305 -0
- package/examples/transcendental-numbers.n3 +186 -0
- package/eyeling-builtins.ttl +0 -3
- package/eyeling.js +0 -21
- package/lib/builtins.js +0 -21
- package/package.json +1 -1
package/HANDBOOK.md
CHANGED
|
@@ -1549,12 +1549,6 @@ Returns a copy of `s` with the character at index `i` (0-based) replaced by:
|
|
|
1549
1549
|
|
|
1550
1550
|
If `i` is out of range, `out` is the original string.
|
|
1551
1551
|
|
|
1552
|
-
#### `string:hammingDistance`
|
|
1553
|
-
|
|
1554
|
-
**Shape:** `( a b ) string:hammingDistance d`
|
|
1555
|
-
|
|
1556
|
-
Returns the number of differing positions between `a` and `b`. Fails if the two strings have different lengths.
|
|
1557
|
-
|
|
1558
1552
|
### Containment and prefix/suffix tests
|
|
1559
1553
|
|
|
1560
1554
|
- `string:contains`
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Mapping two data models (beginner-friendly)
|
|
2
|
+
|
|
3
|
+
When people say “map two data models,” they mean:
|
|
4
|
+
|
|
5
|
+
> **Taking data described using one vocabulary (Model A) and expressing the same meaning using another vocabulary (Model B).**
|
|
6
|
+
|
|
7
|
+
In the Semantic Web / Linked Data world, a “data model” is often a **set of RDF terms** (classes + properties) defined by an ontology or vocabulary—like **schema.org** or **FOAF**.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why would you map vocabularies?
|
|
12
|
+
|
|
13
|
+
Even if two vocabularies describe similar things, they may use **different names** and **different structures**.
|
|
14
|
+
|
|
15
|
+
- **schema.org** is common for publishing data on the web (SEO, structured data).
|
|
16
|
+
- **FOAF (Friend of a Friend)** is common for describing people, names, online accounts, and social relationships.
|
|
17
|
+
|
|
18
|
+
Mapping lets you:
|
|
19
|
+
|
|
20
|
+
- reuse tools built for another vocabulary,
|
|
21
|
+
- integrate datasets that use different terms,
|
|
22
|
+
- keep your original data but still answer queries in the target vocabulary.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## The core idea: “same meaning, different words”
|
|
27
|
+
|
|
28
|
+
Example concept:
|
|
29
|
+
|
|
30
|
+
- In **schema.org**, a person is `schema:Person`
|
|
31
|
+
- In **FOAF**, a person is `foaf:Person`
|
|
32
|
+
|
|
33
|
+
Those two classes can represent the same real-world thing (a person), just in different vocabularies.
|
|
34
|
+
|
|
35
|
+
Similarly for properties:
|
|
36
|
+
|
|
37
|
+
- `schema:name` ≈ `foaf:name`
|
|
38
|
+
- `schema:givenName` ≈ `foaf:givenName`
|
|
39
|
+
- `schema:familyName` ≈ `foaf:familyName`
|
|
40
|
+
|
|
41
|
+
A mapping is just a **set of rules** that says:
|
|
42
|
+
|
|
43
|
+
> “If you see X in schema.org, you can also produce Y in FOAF.”
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## What is N3 (Notation3) and what are N3 rules?
|
|
48
|
+
|
|
49
|
+
**N3** is a compact RDF syntax that also supports **rules**.
|
|
50
|
+
|
|
51
|
+
A rule looks like:
|
|
52
|
+
|
|
53
|
+
- **Left side (condition):** patterns you look for in your data
|
|
54
|
+
- **Right side (conclusion):** triples you can _generate_ when the condition matches
|
|
55
|
+
|
|
56
|
+
General shape:
|
|
57
|
+
|
|
58
|
+
```n3
|
|
59
|
+
{ # IF you find these triples...
|
|
60
|
+
...patterns...
|
|
61
|
+
}
|
|
62
|
+
=>
|
|
63
|
+
{ # THEN you may add these triples...
|
|
64
|
+
...new triples...
|
|
65
|
+
}.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This is sometimes called **forward-chaining**: you start with data you have, and rules _derive_ additional data.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Example data in schema.org (RDF/Turtle)
|
|
73
|
+
|
|
74
|
+
Imagine your dataset contains:
|
|
75
|
+
|
|
76
|
+
```turtle
|
|
77
|
+
@prefix schema: <https://schema.org/> .
|
|
78
|
+
@prefix ex: <https://example.org/> .
|
|
79
|
+
|
|
80
|
+
ex:alice a schema:Person ;
|
|
81
|
+
schema:name "Alice Example" ;
|
|
82
|
+
schema:givenName "Alice" ;
|
|
83
|
+
schema:familyName "Example" .
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This says:
|
|
87
|
+
|
|
88
|
+
- `ex:alice` is a `schema:Person`
|
|
89
|
+
- her full name is `"Alice Example"`
|
|
90
|
+
- her given and family names are included too
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Mapping to FOAF using N3 rules
|
|
95
|
+
|
|
96
|
+
Now we write rules that _derive_ FOAF triples.
|
|
97
|
+
|
|
98
|
+
```n3
|
|
99
|
+
@prefix schema: <https://schema.org/> .
|
|
100
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
|
101
|
+
|
|
102
|
+
# Rule 1: schema:Person -> foaf:Person
|
|
103
|
+
{
|
|
104
|
+
?p a schema:Person .
|
|
105
|
+
}
|
|
106
|
+
=>
|
|
107
|
+
{
|
|
108
|
+
?p a foaf:Person .
|
|
109
|
+
}.
|
|
110
|
+
|
|
111
|
+
# Rule 2: schema:name -> foaf:name
|
|
112
|
+
{
|
|
113
|
+
?p schema:name ?name .
|
|
114
|
+
}
|
|
115
|
+
=>
|
|
116
|
+
{
|
|
117
|
+
?p foaf:name ?name .
|
|
118
|
+
}.
|
|
119
|
+
|
|
120
|
+
# Rule 3: schema:givenName -> foaf:givenName
|
|
121
|
+
{
|
|
122
|
+
?p schema:givenName ?gn .
|
|
123
|
+
}
|
|
124
|
+
=>
|
|
125
|
+
{
|
|
126
|
+
?p foaf:givenName ?gn .
|
|
127
|
+
}.
|
|
128
|
+
|
|
129
|
+
# Rule 4: schema:familyName -> foaf:familyName
|
|
130
|
+
{
|
|
131
|
+
?p schema:familyName ?fn .
|
|
132
|
+
}
|
|
133
|
+
=>
|
|
134
|
+
{
|
|
135
|
+
?p foaf:familyName ?fn .
|
|
136
|
+
}.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Read Rule 2 in plain English:
|
|
140
|
+
|
|
141
|
+
> If a person `?p` has a `schema:name` value `?name`, then we can also say `?p` has a `foaf:name` value `?name`.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## What output do you get?
|
|
146
|
+
|
|
147
|
+
After applying the rules, you still have your original schema.org data, **plus** extra FOAF triples like:
|
|
148
|
+
|
|
149
|
+
```turtle
|
|
150
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
|
151
|
+
@prefix ex: <https://example.org/> .
|
|
152
|
+
|
|
153
|
+
ex:alice a foaf:Person ;
|
|
154
|
+
foaf:name "Alice Example" ;
|
|
155
|
+
foaf:givenName "Alice" ;
|
|
156
|
+
foaf:familyName "Example" .
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
So now FOAF-based tools or queries can work, even though your “source of truth” is schema.org.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Important beginner notes
|
|
164
|
+
|
|
165
|
+
### 1) Mapping usually _adds_ data (it doesn’t delete or replace)
|
|
166
|
+
|
|
167
|
+
Most rule-based mappings are “non-destructive”:
|
|
168
|
+
|
|
169
|
+
- Keep the original triples
|
|
170
|
+
- Derive additional triples in the target vocabulary
|
|
171
|
+
|
|
172
|
+
### 2) 1-to-1 mappings are the easy case
|
|
173
|
+
|
|
174
|
+
`schema:name -> foaf:name` is straightforward.
|
|
175
|
+
|
|
176
|
+
But sometimes:
|
|
177
|
+
|
|
178
|
+
- one term in schema.org maps to **multiple** terms in FOAF, or
|
|
179
|
+
- the target expects a different structure (blank nodes, split names, etc.)
|
|
180
|
+
|
|
181
|
+
### 3) “Same meaning” is a judgment call
|
|
182
|
+
|
|
183
|
+
Two properties might be _similar_ but not truly identical in all contexts. Mapping works best when you understand the intended meaning of each term.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## A simple mental checklist for mapping
|
|
188
|
+
|
|
189
|
+
1. **List the things** you have (classes + properties in schema.org)
|
|
190
|
+
2. **Decide what you want** to support (FOAF terms you need)
|
|
191
|
+
3. For each target term, ask:
|
|
192
|
+
- “Where can I get this information from in the source?”
|
|
193
|
+
|
|
194
|
+
4. Write rules:
|
|
195
|
+
- **conditions** match the source triples
|
|
196
|
+
- **conclusions** emit the target triples
|
|
197
|
+
|
|
198
|
+
5. Run a reasoner/rule engine and test with a few example resources
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Next step ideas (optional)
|
|
203
|
+
|
|
204
|
+
- Map online profiles:
|
|
205
|
+
- `schema:sameAs` could help populate `foaf:page` or related links (careful: semantics differ).
|
|
206
|
+
|
|
207
|
+
- Add type rules beyond `Person`
|
|
208
|
+
- Write rules that create structured nodes (more advanced)
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Summary
|
|
213
|
+
|
|
214
|
+
Mapping two models is about **translating meaning across vocabularies**.
|
|
215
|
+
|
|
216
|
+
- You start with data described in **schema.org**
|
|
217
|
+
- You write **N3 rules** that recognize schema.org patterns
|
|
218
|
+
- You **derive FOAF triples**
|
|
219
|
+
- The result is data that can be consumed as if it were FOAF, without rewriting your original dataset
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# ================================================================================
|
|
2
|
+
# Genetic Algorithm demo: 0/1 Knapsack via mutation + selection
|
|
3
|
+
#
|
|
4
|
+
# Goal
|
|
5
|
+
# ----
|
|
6
|
+
# Evolve a bitstring genome that selects a subset of items to maximize total VALUE
|
|
7
|
+
# while staying within a WEIGHT capacity.
|
|
8
|
+
#
|
|
9
|
+
# Representation
|
|
10
|
+
# --------------
|
|
11
|
+
# - Items: list of pairs (weight value)
|
|
12
|
+
# - Genome: a string of '0'/'1' of the same length as the item list
|
|
13
|
+
# - bit i = '1' => item i is included
|
|
14
|
+
# - bit i = '0' => item i is excluded
|
|
15
|
+
#
|
|
16
|
+
# Fitness (lower is better)
|
|
17
|
+
# -------------------------
|
|
18
|
+
# We want: feasible solutions (weight <= capacity) with high value.
|
|
19
|
+
#
|
|
20
|
+
# If weight <= capacity:
|
|
21
|
+
# fitness = 1_000_000 - value (so higher value => lower fitness)
|
|
22
|
+
# If overweight:
|
|
23
|
+
# fitness = 2_000_000 + (weight - capacity)
|
|
24
|
+
# (overweight candidates are always worse than any feasible candidate)
|
|
25
|
+
#
|
|
26
|
+
# Variation (mutation)
|
|
27
|
+
# --------------------
|
|
28
|
+
# Single-bit flip: generate all "neighbors" of the current genome by flipping
|
|
29
|
+
# exactly one position. This is deterministic (no randomness), but it still
|
|
30
|
+
# demonstrates the core GA pattern of mutation + selection.
|
|
31
|
+
#
|
|
32
|
+
# Selection
|
|
33
|
+
# ---------
|
|
34
|
+
# Compare parent + all mutants, keep the candidate with the lowest fitness.
|
|
35
|
+
# This is essentially a (1 + λ) evolutionary strategy / hill-climber.
|
|
36
|
+
#
|
|
37
|
+
# Stopping criteria
|
|
38
|
+
# -----------------
|
|
39
|
+
# Stop when either:
|
|
40
|
+
# - maxGenerations is reached, or
|
|
41
|
+
# - no mutant improves fitness (local optimum under 1-bit flips)
|
|
42
|
+
# ================================================================================
|
|
43
|
+
|
|
44
|
+
@prefix : <urn:ga:>.
|
|
45
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
46
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
47
|
+
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
|
|
48
|
+
@prefix string: <http://www.w3.org/2000/10/swap/string#>.
|
|
49
|
+
|
|
50
|
+
:cfg
|
|
51
|
+
:capacity 50;
|
|
52
|
+
:maxGenerations 64;
|
|
53
|
+
|
|
54
|
+
# Each item is (weight value). Genome bits select items by index.
|
|
55
|
+
:items (
|
|
56
|
+
(12 24)
|
|
57
|
+
(7 13)
|
|
58
|
+
(11 23)
|
|
59
|
+
(8 15)
|
|
60
|
+
(9 16)
|
|
61
|
+
(6 12)
|
|
62
|
+
(10 21)
|
|
63
|
+
(4 9)
|
|
64
|
+
(5 11)
|
|
65
|
+
(14 28)
|
|
66
|
+
(3 7)
|
|
67
|
+
(13 26)
|
|
68
|
+
).
|
|
69
|
+
|
|
70
|
+
# -------------
|
|
71
|
+
# small helpers
|
|
72
|
+
# -------------
|
|
73
|
+
|
|
74
|
+
{ ( ?N 1 ) :inc ?N1 } <= { ( ?N 1 ) math:sum ?N1 }.
|
|
75
|
+
|
|
76
|
+
# build a string of N zeros
|
|
77
|
+
{ ( 0 ) :zeros "" } <= true.
|
|
78
|
+
|
|
79
|
+
{ ( ?N ) :zeros ?S } <= {
|
|
80
|
+
?N math:greaterThan 0 .
|
|
81
|
+
( ?N 1 ) math:difference ?N1 .
|
|
82
|
+
( ?N1 ) :zeros ?Rest .
|
|
83
|
+
( "%s%s" "0" ?Rest ) string:format ?S
|
|
84
|
+
}.
|
|
85
|
+
|
|
86
|
+
# flip a bit at index i in a 0/1 string
|
|
87
|
+
{ ( ?S ?I ) :flipBit ?Out } <= {
|
|
88
|
+
( ?S ?I ) string:charAt "0" .
|
|
89
|
+
( ?S ?I "1" ) string:setCharAt ?Out
|
|
90
|
+
}.
|
|
91
|
+
|
|
92
|
+
{ ( ?S ?I ) :flipBit ?Out } <= {
|
|
93
|
+
( ?S ?I ) string:charAt "1" .
|
|
94
|
+
( ?S ?I "0" ) string:setCharAt ?Out
|
|
95
|
+
}.
|
|
96
|
+
|
|
97
|
+
# generate all single-bit mutants of S
|
|
98
|
+
{ ( ?S ?Len ) :mutants ?Out } <= {
|
|
99
|
+
( ?S 0 ?Len ) :mutantsFrom ?Out
|
|
100
|
+
}.
|
|
101
|
+
|
|
102
|
+
{ ( ?S ?I ?Len ) :mutantsFrom () } <= {
|
|
103
|
+
?I math:equalTo ?Len
|
|
104
|
+
}.
|
|
105
|
+
|
|
106
|
+
{ ( ?S ?I ?Len ) :mutantsFrom ?Out } <= {
|
|
107
|
+
?I math:lessThan ?Len .
|
|
108
|
+
( ?S ?I ) :flipBit ?Cand .
|
|
109
|
+
( ?I 1 ) :inc ?I1 .
|
|
110
|
+
( ?S ?I1 ?Len ) :mutantsFrom ?Rest .
|
|
111
|
+
( ( ?Cand ) ?Rest ) list:append ?Out
|
|
112
|
+
}.
|
|
113
|
+
|
|
114
|
+
# -----------------------------------------
|
|
115
|
+
# decode genome -> (totalWeight totalValue)
|
|
116
|
+
# -----------------------------------------
|
|
117
|
+
|
|
118
|
+
{ ( ?Bits ?Items ) :totals ( ?Wsum ?Vsum ) } <= {
|
|
119
|
+
?Bits string:length ?Len .
|
|
120
|
+
( ?Bits ?Items 0 ?Len 0 0 ) :totalsAcc ( ?Wsum ?Vsum )
|
|
121
|
+
}.
|
|
122
|
+
|
|
123
|
+
{ ( ?Bits ?Items ?I ?Len ?AccW ?AccV ) :totalsAcc ( ?AccW ?AccV ) } <= {
|
|
124
|
+
?I math:equalTo ?Len
|
|
125
|
+
}.
|
|
126
|
+
|
|
127
|
+
{ ( ?Bits ?Items ?I ?Len ?AccW ?AccV ) :totalsAcc ( ?Wsum ?Vsum ) } <= {
|
|
128
|
+
?I math:lessThan ?Len .
|
|
129
|
+
( ?Bits ?I ) string:charAt "1" .
|
|
130
|
+
|
|
131
|
+
( ?Items ?I ) list:memberAt ?Pair .
|
|
132
|
+
( ?Pair 0 ) list:memberAt ?W .
|
|
133
|
+
( ?Pair 1 ) list:memberAt ?V .
|
|
134
|
+
|
|
135
|
+
( ?AccW ?W ) math:sum ?AccW1 .
|
|
136
|
+
( ?AccV ?V ) math:sum ?AccV1 .
|
|
137
|
+
|
|
138
|
+
( ?I 1 ) :inc ?I1 .
|
|
139
|
+
( ?Bits ?Items ?I1 ?Len ?AccW1 ?AccV1 ) :totalsAcc ( ?Wsum ?Vsum )
|
|
140
|
+
}.
|
|
141
|
+
|
|
142
|
+
{ ( ?Bits ?Items ?I ?Len ?AccW ?AccV ) :totalsAcc ( ?Wsum ?Vsum ) } <= {
|
|
143
|
+
?I math:lessThan ?Len .
|
|
144
|
+
( ?Bits ?I ) string:charAt "0" .
|
|
145
|
+
|
|
146
|
+
( ?I 1 ) :inc ?I1 .
|
|
147
|
+
( ?Bits ?Items ?I1 ?Len ?AccW ?AccV ) :totalsAcc ( ?Wsum ?Vsum )
|
|
148
|
+
}.
|
|
149
|
+
|
|
150
|
+
# -------------------------
|
|
151
|
+
# fitness (lower is better)
|
|
152
|
+
# -------------------------
|
|
153
|
+
|
|
154
|
+
{ ( ?W ?V ?Cap ) :fitness ?F } <= {
|
|
155
|
+
?W math:notGreaterThan ?Cap .
|
|
156
|
+
( 1000000 ?V ) math:difference ?F
|
|
157
|
+
}.
|
|
158
|
+
|
|
159
|
+
{ ( ?W ?V ?Cap ) :fitness ?F } <= {
|
|
160
|
+
?W math:greaterThan ?Cap .
|
|
161
|
+
( ?W ?Cap ) math:difference ?Over .
|
|
162
|
+
( 2000000 ?Over ) math:sum ?F
|
|
163
|
+
}.
|
|
164
|
+
|
|
165
|
+
{ ( ?W ?Cap ) :feasible "true" } <= { ?W math:notGreaterThan ?Cap }.
|
|
166
|
+
{ ( ?W ?Cap ) :feasible "false" } <= { ?W math:greaterThan ?Cap }.
|
|
167
|
+
|
|
168
|
+
{ ( ?Bits ?Cap ?Items ) :candidateScore ( ?Fit ?Wsum ?Vsum ) } <= {
|
|
169
|
+
( ?Bits ?Items ) :totals ( ?Wsum ?Vsum ) .
|
|
170
|
+
( ?Wsum ?Vsum ?Cap ) :fitness ?Fit
|
|
171
|
+
}.
|
|
172
|
+
|
|
173
|
+
# pick best of two candidates by fitness (ties keep the left candidate)
|
|
174
|
+
{ ( ?C1 ?S1 ?W1 ?V1 ?C2 ?S2 ?W2 ?V2 ) :pickBest ( ?C1 ?S1 ?W1 ?V1 ) } <= {
|
|
175
|
+
?S1 math:notGreaterThan ?S2
|
|
176
|
+
}.
|
|
177
|
+
|
|
178
|
+
{ ( ?C1 ?S1 ?W1 ?V1 ?C2 ?S2 ?W2 ?V2 ) :pickBest ( ?C2 ?S2 ?W2 ?V2 ) } <= {
|
|
179
|
+
?S1 math:greaterThan ?S2
|
|
180
|
+
}.
|
|
181
|
+
|
|
182
|
+
# best candidate from a list
|
|
183
|
+
{ ( ?Cap ?Items ?L ) :bestMutant ( ?Best ?BestScore ?BestW ?BestV ) } <= {
|
|
184
|
+
?L list:length 1 .
|
|
185
|
+
?L list:first ?Best .
|
|
186
|
+
( ?Best ?Cap ?Items ) :candidateScore ( ?BestScore ?BestW ?BestV )
|
|
187
|
+
}.
|
|
188
|
+
|
|
189
|
+
{ ( ?Cap ?Items ?L ) :bestMutant ( ?Best ?BestScore ?BestW ?BestV ) } <= {
|
|
190
|
+
?L list:length ?N .
|
|
191
|
+
?N math:greaterThan 1 .
|
|
192
|
+
|
|
193
|
+
?L list:first ?H .
|
|
194
|
+
?L list:rest ?T .
|
|
195
|
+
|
|
196
|
+
( ?Cap ?Items ?T ) :bestMutant ( ?B2 ?S2 ?W2 ?V2 ) .
|
|
197
|
+
( ?H ?Cap ?Items ) :candidateScore ( ?S1 ?W1 ?V1 ) .
|
|
198
|
+
|
|
199
|
+
( ?H ?S1 ?W1 ?V1 ?B2 ?S2 ?W2 ?V2 ) :pickBest ( ?Best ?BestScore ?BestW ?BestV )
|
|
200
|
+
}.
|
|
201
|
+
|
|
202
|
+
# --------------
|
|
203
|
+
# evolution loop
|
|
204
|
+
# --------------
|
|
205
|
+
|
|
206
|
+
# generation cap
|
|
207
|
+
{ ( ?Bits ?Cap ?Items ?Gen ?MaxGen ) :evolve ( ?Bits ?Gen ) } <= {
|
|
208
|
+
?Gen math:equalTo ?MaxGen
|
|
209
|
+
}.
|
|
210
|
+
|
|
211
|
+
# stop if best doesn't improve
|
|
212
|
+
{ ( ?Bits ?Cap ?Items ?Gen ?MaxGen ) :evolve ( ?Bits ?Gen ) } <= {
|
|
213
|
+
?Gen math:lessThan ?MaxGen .
|
|
214
|
+
( ?Bits ?Cap ?Items ) :candidateScore ( ?Score ?W ?V ) .
|
|
215
|
+
|
|
216
|
+
?Bits string:length ?Len .
|
|
217
|
+
( ?Bits ?Len ) :mutants ?Ms .
|
|
218
|
+
( ( ?Bits ) ?Ms ) list:append ?Candidates .
|
|
219
|
+
|
|
220
|
+
( ?Cap ?Items ?Candidates ) :bestMutant ( ?Best ?BestScore ?BW ?BV ) .
|
|
221
|
+
?BestScore math:equalTo ?Score
|
|
222
|
+
}.
|
|
223
|
+
|
|
224
|
+
# keep evolving while improvement exists
|
|
225
|
+
{ ( ?Bits ?Cap ?Items ?Gen ?MaxGen ) :evolve ( ?Final ?FinalGen ) } <= {
|
|
226
|
+
?Gen math:lessThan ?MaxGen .
|
|
227
|
+
( ?Bits ?Cap ?Items ) :candidateScore ( ?Score ?W ?V ) .
|
|
228
|
+
|
|
229
|
+
?Bits string:length ?Len .
|
|
230
|
+
( ?Bits ?Len ) :mutants ?Ms .
|
|
231
|
+
( ( ?Bits ) ?Ms ) list:append ?Candidates .
|
|
232
|
+
|
|
233
|
+
( ?Cap ?Items ?Candidates ) :bestMutant ( ?Best ?BestScore ?BW ?BV ) .
|
|
234
|
+
?BestScore math:notEqualTo ?Score .
|
|
235
|
+
|
|
236
|
+
( ?Gen 1 ) :inc ?Gen1 .
|
|
237
|
+
( ?Best ?Cap ?Items ?Gen1 ?MaxGen ) :evolve ( ?Final ?FinalGen )
|
|
238
|
+
}.
|
|
239
|
+
|
|
240
|
+
# --------------
|
|
241
|
+
# query / output
|
|
242
|
+
# --------------
|
|
243
|
+
|
|
244
|
+
{
|
|
245
|
+
:cfg :capacity ?Cap;
|
|
246
|
+
:maxGenerations ?Max;
|
|
247
|
+
:items ?Items.
|
|
248
|
+
|
|
249
|
+
?Items list:length ?Len .
|
|
250
|
+
( ?Len ) :zeros ?Start .
|
|
251
|
+
|
|
252
|
+
( ?Start ?Cap ?Items 0 ?Max ) :evolve ( ?Best ?Gen ) .
|
|
253
|
+
( ?Best ?Cap ?Items ) :candidateScore ( ?Fit ?W ?V ) .
|
|
254
|
+
( ?W ?Cap ) :feasible ?Ok .
|
|
255
|
+
|
|
256
|
+
( "Knapsack GA best genome %s (feasible=%s): weight=%s value=%s after %s generations.\n"
|
|
257
|
+
?Best ?Ok ?W ?V ?Gen ) string:format ?Line
|
|
258
|
+
}
|
|
259
|
+
log:query
|
|
260
|
+
{ 1 log:outputString ?Line }.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# ====================================================================
|
|
2
|
+
# N3 LINKS POLICY, PROVENANCE, AND INFERENCE
|
|
3
|
+
#
|
|
4
|
+
# Another “speaks for itself” case:
|
|
5
|
+
# Delegation-based trust + distributed authorization.
|
|
6
|
+
#
|
|
7
|
+
# What it shows (in one syntax):
|
|
8
|
+
# - Quoted claims from multiple web documents
|
|
9
|
+
# - A tiny trust policy that can *delegate* trust to other documents
|
|
10
|
+
# - Importing only trusted statements into the fact set
|
|
11
|
+
# - Reasoning across imported facts to derive permissions
|
|
12
|
+
# - Provenance output using singleton graph terms (formulas),
|
|
13
|
+
# and *not stored* as derived facts.
|
|
14
|
+
#
|
|
15
|
+
# Run:
|
|
16
|
+
# eyeling examples/n3-delegation-access.n3
|
|
17
|
+
#
|
|
18
|
+
# Output:
|
|
19
|
+
# - :report :trusts <doc>
|
|
20
|
+
# - :report :entails { <user> :canRead <resource>. }
|
|
21
|
+
# - { ... } :assertedBy <doc> (singleton graph provenance)
|
|
22
|
+
# ====================================================================
|
|
23
|
+
|
|
24
|
+
@prefix : <https://example.org/n3-delegation#>.
|
|
25
|
+
@prefix id: <https://example.org/id/>.
|
|
26
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
|
|
27
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
28
|
+
|
|
29
|
+
# ----------
|
|
30
|
+
# Trust root
|
|
31
|
+
# ----------
|
|
32
|
+
|
|
33
|
+
:policy :trusts <https://root.example/policy.n3>.
|
|
34
|
+
|
|
35
|
+
# ------------------------------
|
|
36
|
+
# The Web "says" (quoted graphs)
|
|
37
|
+
# ------------------------------
|
|
38
|
+
|
|
39
|
+
# Root policy delegates trust outward.
|
|
40
|
+
<https://root.example/policy.n3> :says {
|
|
41
|
+
:policy :delegatesTo <https://hr.example/policy.n3>.
|
|
42
|
+
:policy :delegatesTo <https://team.example/members.n3>.
|
|
43
|
+
}.
|
|
44
|
+
|
|
45
|
+
# HR publishes what groups may read what.
|
|
46
|
+
<https://hr.example/policy.n3> :says {
|
|
47
|
+
:eng :mayRead :buildReport.
|
|
48
|
+
:eng :mayRead :roadmap.
|
|
49
|
+
}.
|
|
50
|
+
|
|
51
|
+
# Team publishes membership, and delegates further.
|
|
52
|
+
<https://team.example/members.n3> :says {
|
|
53
|
+
id:alice foaf:name "Alice".
|
|
54
|
+
id:alice :memberOf :eng.
|
|
55
|
+
|
|
56
|
+
:policy :delegatesTo <https://interns.example/members.n3>.
|
|
57
|
+
}.
|
|
58
|
+
|
|
59
|
+
# Intern list becomes trusted only because Team delegated to it.
|
|
60
|
+
<https://interns.example/members.n3> :says {
|
|
61
|
+
id:eve foaf:name "Eve".
|
|
62
|
+
id:eve :memberOf :eng.
|
|
63
|
+
}.
|
|
64
|
+
|
|
65
|
+
# Untrusted rumor: present as quoted data, but will not be imported.
|
|
66
|
+
<http://shady.example/rumor.n3> :says {
|
|
67
|
+
id:mallory foaf:name "Mallory".
|
|
68
|
+
id:mallory :memberOf :eng.
|
|
69
|
+
:eng :mayRead :secrets.
|
|
70
|
+
}.
|
|
71
|
+
|
|
72
|
+
# --------------------------------
|
|
73
|
+
# Trust can be delegated (forward)
|
|
74
|
+
# --------------------------------
|
|
75
|
+
|
|
76
|
+
{
|
|
77
|
+
:policy :trusts ?Doc.
|
|
78
|
+
?Doc :says ?F.
|
|
79
|
+
?F log:includes { :policy :delegatesTo ?Other. }.
|
|
80
|
+
}
|
|
81
|
+
=>
|
|
82
|
+
{
|
|
83
|
+
:policy :trusts ?Other.
|
|
84
|
+
}.
|
|
85
|
+
|
|
86
|
+
# ----------------------------------
|
|
87
|
+
# Import only trusted quoted triples
|
|
88
|
+
# ----------------------------------
|
|
89
|
+
{
|
|
90
|
+
:policy :trusts ?Doc.
|
|
91
|
+
?Doc :says ?F.
|
|
92
|
+
?F log:includes { ?S ?P ?O. }.
|
|
93
|
+
}
|
|
94
|
+
=>
|
|
95
|
+
{
|
|
96
|
+
?S ?P ?O.
|
|
97
|
+
}.
|
|
98
|
+
|
|
99
|
+
# ------------------------------------------------
|
|
100
|
+
# Local meaning: membership + policy => permission
|
|
101
|
+
# ------------------------------------------------
|
|
102
|
+
{
|
|
103
|
+
?U :memberOf ?G.
|
|
104
|
+
?G :mayRead ?R.
|
|
105
|
+
}
|
|
106
|
+
=>
|
|
107
|
+
{
|
|
108
|
+
?U :canRead ?R.
|
|
109
|
+
}.
|
|
110
|
+
|
|
111
|
+
# ------
|
|
112
|
+
# REPORT
|
|
113
|
+
# ------
|
|
114
|
+
|
|
115
|
+
# Which documents ended up trusted (root + delegated)
|
|
116
|
+
{
|
|
117
|
+
:policy :trusts ?Doc.
|
|
118
|
+
}
|
|
119
|
+
log:query
|
|
120
|
+
{
|
|
121
|
+
:report :trusts ?Doc.
|
|
122
|
+
}.
|
|
123
|
+
|
|
124
|
+
# What the system entails
|
|
125
|
+
{
|
|
126
|
+
?U :canRead ?R.
|
|
127
|
+
}
|
|
128
|
+
log:query
|
|
129
|
+
{
|
|
130
|
+
:report :entails { ?U :canRead ?R. }.
|
|
131
|
+
}.
|
|
132
|
+
|
|
133
|
+
# Why (provenance), using singleton graph terms:
|
|
134
|
+
# show the two supporting asserted statements and where they came from.
|
|
135
|
+
{
|
|
136
|
+
?U :canRead ?R.
|
|
137
|
+
|
|
138
|
+
?U :memberOf ?G.
|
|
139
|
+
?G :mayRead ?R.
|
|
140
|
+
|
|
141
|
+
:policy :trusts ?DocM.
|
|
142
|
+
?DocM :says ?FM.
|
|
143
|
+
?FM log:includes { ?U :memberOf ?G. }.
|
|
144
|
+
|
|
145
|
+
:policy :trusts ?DocP.
|
|
146
|
+
?DocP :says ?FP.
|
|
147
|
+
?FP log:includes { ?G :mayRead ?R. }.
|
|
148
|
+
}
|
|
149
|
+
log:query
|
|
150
|
+
{
|
|
151
|
+
{ ?U :memberOf ?G. } :assertedBy ?DocM.
|
|
152
|
+
{ ?G :mayRead ?R. } :assertedBy ?DocP.
|
|
153
|
+
}.
|