eyeling 1.14.5 → 1.14.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/deck/schema-foaf-mapping.md +219 -0
- package/examples/n3-delegation-access.n3 +153 -0
- package/examples/n3-speaks-for-itself.n3 +118 -0
- package/examples/odrl-dpv-ehds-risk-ranked.n3 +38 -58
- package/examples/odrl-dpv-risk-ranked.n3 +37 -55
- package/examples/output/kaprekar.n3 +8010 -8010
- package/examples/output/n3-delegation-access.n3 +31 -0
- package/examples/output/n3-speaks-for-itself.n3 +52 -0
- package/examples/output/odrl-dpv-ehds-risk-ranked.n3 +8 -140
- package/examples/output/odrl-dpv-risk-ranked.n3 +9 -155
- package/examples/output/schema-foaf-mapping.n3 +7 -0
- package/examples/output/transcendental-families.n3 +236 -0
- package/examples/output/transcendental-lab.n3 +113 -0
- package/examples/output/transcendental-names-and-families.n3 +167 -0
- package/examples/output/transcendental-numbers-stretched.n3 +260 -0
- package/examples/output/transcendental-numbers.n3 +44 -0
- package/examples/output/wind-turbine.n3 +2 -2
- 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.js +207 -24
- package/lib/cli.js +8 -0
- package/lib/engine.js +9 -2
- package/lib/printing.js +190 -1
- package/package.json +1 -1
|
@@ -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,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
|
+
}.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# ==========================================================
|
|
2
|
+
# N3 SPEAKS FOR ITSELF
|
|
3
|
+
#
|
|
4
|
+
# One syntax does it all:
|
|
5
|
+
# - Names (URIs)
|
|
6
|
+
# - Claims (triples)
|
|
7
|
+
# - Quoted claims (formulas as data)
|
|
8
|
+
# - Policy (trust)
|
|
9
|
+
# - Reasoning (closure over links)
|
|
10
|
+
# - Provenance without reification (singleton graph terms)
|
|
11
|
+
#
|
|
12
|
+
# Run:
|
|
13
|
+
# eyeling examples/n3-speaks-for-itself.n3
|
|
14
|
+
#
|
|
15
|
+
# Output is just a few :report triples (no log:outputString).
|
|
16
|
+
# ==========================================================
|
|
17
|
+
|
|
18
|
+
@prefix : <https://example.org/n3-speaks#>.
|
|
19
|
+
@prefix id: <https://example.org/id/>.
|
|
20
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
|
|
21
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
22
|
+
|
|
23
|
+
# --------------------------------
|
|
24
|
+
# Policy: which documents we trust
|
|
25
|
+
# --------------------------------
|
|
26
|
+
|
|
27
|
+
:policy :trusts <https://alice.example/profile.n3>.
|
|
28
|
+
:policy :trusts <https://bob.example/profile.n3>.
|
|
29
|
+
:policy :trusts <https://carol.example/profile.n3>.
|
|
30
|
+
|
|
31
|
+
# -------------------------------------
|
|
32
|
+
# The Web "says" things (quoted graphs)
|
|
33
|
+
# -------------------------------------
|
|
34
|
+
|
|
35
|
+
<https://alice.example/profile.n3> :says {
|
|
36
|
+
id:alice foaf:name "Alice".
|
|
37
|
+
id:alice foaf:knows id:bob.
|
|
38
|
+
}.
|
|
39
|
+
|
|
40
|
+
<https://bob.example/profile.n3> :says {
|
|
41
|
+
id:bob foaf:name "Bob".
|
|
42
|
+
id:bob foaf:knows id:carol.
|
|
43
|
+
}.
|
|
44
|
+
|
|
45
|
+
<https://carol.example/profile.n3> :says {
|
|
46
|
+
id:carol foaf:name "Carol".
|
|
47
|
+
id:carol foaf:knows id:dave.
|
|
48
|
+
id:dave foaf:name "Dave".
|
|
49
|
+
}.
|
|
50
|
+
|
|
51
|
+
# Untrusted rumor: present as quoted data, but policy won’t import it.
|
|
52
|
+
<http://shady.example/rumor.n3> :says {
|
|
53
|
+
id:alice foaf:knows id:mallory.
|
|
54
|
+
id:mallory foaf:name "Mallory".
|
|
55
|
+
}.
|
|
56
|
+
|
|
57
|
+
# ----------------------------------------------------------------------------------
|
|
58
|
+
# Import rule: trusted quotes become facts
|
|
59
|
+
#
|
|
60
|
+
# IMPORTANT:
|
|
61
|
+
# Do NOT derive provenance facts that *store* formula terms (like {..} :from ?Doc)
|
|
62
|
+
# in the forward-chaining store, because formula terms in rule heads may be
|
|
63
|
+
# generated as fresh nodes each time and can prevent fixpoint termination.
|
|
64
|
+
#
|
|
65
|
+
# We still *output* provenance later via log:query, computed directly from quotes.
|
|
66
|
+
# ----------------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
{
|
|
69
|
+
:policy :trusts ?Doc.
|
|
70
|
+
?Doc :says ?F.
|
|
71
|
+
?F log:includes { ?S ?P ?O. }.
|
|
72
|
+
}
|
|
73
|
+
=>
|
|
74
|
+
{
|
|
75
|
+
?S ?P ?O.
|
|
76
|
+
}.
|
|
77
|
+
|
|
78
|
+
# ----------------------------------------------------------
|
|
79
|
+
# Meaning: knowsPlus is the transitive closure of foaf:knows
|
|
80
|
+
# ----------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
{ ?A foaf:knows ?B. } => { ?A :knowsPlus ?B. }.
|
|
83
|
+
{ ?A :knowsPlus ?B. ?B foaf:knows ?C. } => { ?A :knowsPlus ?C. }.
|
|
84
|
+
|
|
85
|
+
# ---------------------------------------
|
|
86
|
+
# REPORT: select only the “story” triples
|
|
87
|
+
# ---------------------------------------
|
|
88
|
+
|
|
89
|
+
# What we trust
|
|
90
|
+
{
|
|
91
|
+
:policy :trusts ?Doc.
|
|
92
|
+
}
|
|
93
|
+
log:query
|
|
94
|
+
{
|
|
95
|
+
:report :trusts ?Doc.
|
|
96
|
+
}.
|
|
97
|
+
|
|
98
|
+
# What we believed, and where it came from
|
|
99
|
+
# (provenance emitted as singleton graph term, but not stored as derived facts)
|
|
100
|
+
{
|
|
101
|
+
:policy :trusts ?Doc.
|
|
102
|
+
?Doc :says ?F.
|
|
103
|
+
?F log:includes { ?S ?P ?O. }.
|
|
104
|
+
}
|
|
105
|
+
log:query
|
|
106
|
+
{
|
|
107
|
+
:report :believes { ?S ?P ?O. }.
|
|
108
|
+
{ ?S ?P ?O. } :believedFromDoc ?Doc.
|
|
109
|
+
}.
|
|
110
|
+
|
|
111
|
+
# What logic adds: who Alice can reach by following links
|
|
112
|
+
{
|
|
113
|
+
id:alice :knowsPlus ?Who.
|
|
114
|
+
}
|
|
115
|
+
log:query
|
|
116
|
+
{
|
|
117
|
+
:report :aliceReaches ?Who.
|
|
118
|
+
}.
|