eyeling 1.22.15 → 1.23.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.
- package/HANDBOOK.md +113 -16
- package/dist/browser/eyeling.browser.js +248 -34
- package/examples/barley-seed-becoming.n3 +497 -0
- package/examples/constructor-theory-becoming.n3 +177 -0
- package/examples/output/barley-seed-becoming.txt +25 -0
- package/examples/output/constructor-theory-becoming.n3 +18 -0
- package/examples/output/tunnel-junction-wake-switch-becoming.txt +21 -0
- package/examples/tunnel-junction-wake-switch-becoming.n3 +216 -0
- package/eyeling.js +255 -34
- package/index.d.ts +17 -5
- package/index.js +29 -8
- package/lib/cli.js +44 -32
- package/lib/engine.js +4 -2
- package/lib/multisource.js +198 -0
- package/package.json +1 -1
- package/test/api.test.js +101 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
tunnel-junction wake switch — becoming
|
|
2
|
+
|
|
3
|
+
Answer
|
|
4
|
+
YES for the tunnel junction.
|
|
5
|
+
NO for the conventional low-bias PN junction in the same wake-switch regime.
|
|
6
|
+
|
|
7
|
+
Reason Why
|
|
8
|
+
The tunnel junction can be read as a becoming under low forward bias. Because it is modeled as a heavily doped narrow PN junction with overlapping states, it can become a quantum-transfer state. In that regime it can become a sub-threshold current state, and under peak-to-valley scanning it can also become a negative differential response state. As a wake-switch device, that lets it become an ultra-low-bias switching state and finally a leak-alarm wake-serving state. By contrast, the conventional junction lacks the structural conditions needed for the same transition into quantum transfer, so the later wake-serving becoming is blocked as well.
|
|
9
|
+
|
|
10
|
+
Check
|
|
11
|
+
B1 OK - the tunnel junction can become a quantum-transfer state
|
|
12
|
+
B2 OK - the tunnel junction is classified as tunneling-dominant
|
|
13
|
+
B3 OK - the tunnel junction can become a sub-threshold current state
|
|
14
|
+
B4 OK - the tunnel junction can become a negative differential response state
|
|
15
|
+
B5 OK - the tunnel junction can become an ultra-low-bias switching state
|
|
16
|
+
B6 OK - the tunnel junction can become a leak-alarm wake-serving state
|
|
17
|
+
B7 OK - the conventional junction cannot become a quantum-transfer state
|
|
18
|
+
B8 OK - the conventional junction cannot become a sub-threshold current state
|
|
19
|
+
B9 OK - the conventional junction cannot become the tunnel-style negative differential state
|
|
20
|
+
B10 OK - the conventional junction cannot become an ultra-low-bias switching state here
|
|
21
|
+
B11 OK - the conventional junction cannot become a leak-alarm wake-serving state in this case
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# =================================================================================
|
|
2
|
+
# tunnel-junction wake switch — becoming
|
|
3
|
+
#
|
|
4
|
+
# This example reframes the wake-switch case as a becoming example.
|
|
5
|
+
# The device is not treated as a static component with capabilities, but as a
|
|
6
|
+
# system that can or cannot pass into a low-bias wake-triggering state.
|
|
7
|
+
#
|
|
8
|
+
# We compare two devices:
|
|
9
|
+
# - tunnelJunction : a heavily doped narrow PN junction with overlapping states
|
|
10
|
+
# - ordinaryJunction : a conventional PN junction without that overlap
|
|
11
|
+
#
|
|
12
|
+
# The point is to show:
|
|
13
|
+
# - what the tunnel junction can become under the low-bias requirement
|
|
14
|
+
# - what the conventional junction cannot become under the same requirement
|
|
15
|
+
# =================================================================================
|
|
16
|
+
|
|
17
|
+
@prefix : <http://example.org/tunnel-junction-wake-switch-becoming/> .
|
|
18
|
+
@prefix arc: <https://example.org/arc#> .
|
|
19
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
|
|
20
|
+
|
|
21
|
+
:case a arc:Case ;
|
|
22
|
+
arc:question "Can a tunnel-junction wake switch become a low-bias wake-triggering state in a regime where a conventional PN junction cannot?" .
|
|
23
|
+
|
|
24
|
+
# -------------------
|
|
25
|
+
# Application context
|
|
26
|
+
# -------------------
|
|
27
|
+
|
|
28
|
+
:leakAlarmNode a :EdgeSensor ;
|
|
29
|
+
:needs :MicrowattWakeSwitching ;
|
|
30
|
+
:application :PipeLeakAlarm .
|
|
31
|
+
|
|
32
|
+
# ----------------------------------
|
|
33
|
+
# Device A: tunnel-style PN junction
|
|
34
|
+
# ----------------------------------
|
|
35
|
+
|
|
36
|
+
:tunnelJunction a :PNJunction ;
|
|
37
|
+
:junctionKind :TunnelDiode ;
|
|
38
|
+
:doping :Heavy ;
|
|
39
|
+
:depletionWidth :Narrow ;
|
|
40
|
+
:stateAlignment :Overlap ;
|
|
41
|
+
:biasRegime :LowForwardBias ;
|
|
42
|
+
:scanProfile :PeakToValley ;
|
|
43
|
+
:deviceRole :WakeSwitch .
|
|
44
|
+
|
|
45
|
+
# ----------------------------------
|
|
46
|
+
# Device B: conventional PN junction
|
|
47
|
+
# ----------------------------------
|
|
48
|
+
|
|
49
|
+
:ordinaryJunction a :PNJunction ;
|
|
50
|
+
:junctionKind :ConventionalDiode ;
|
|
51
|
+
:doping :Standard ;
|
|
52
|
+
:depletionWidth :Wide ;
|
|
53
|
+
:stateAlignment :NoOverlap ;
|
|
54
|
+
:biasRegime :LowForwardBias ;
|
|
55
|
+
:scanProfile :MonotoneForward ;
|
|
56
|
+
:deviceRole :WakeSwitch .
|
|
57
|
+
|
|
58
|
+
# -------------------------------------------
|
|
59
|
+
# CAN-BECOME rules — viable state transitions
|
|
60
|
+
# -------------------------------------------
|
|
61
|
+
|
|
62
|
+
# A heavily doped, narrow junction with overlapping states can become a
|
|
63
|
+
# quantum-transfer-supporting junction.
|
|
64
|
+
{ ?J a :PNJunction ;
|
|
65
|
+
:doping :Heavy ;
|
|
66
|
+
:depletionWidth :Narrow ;
|
|
67
|
+
:stateAlignment :Overlap . }
|
|
68
|
+
=>
|
|
69
|
+
{ ?J :canBecome :QuantumTransferState ;
|
|
70
|
+
:transportMode :TunnelingDominant . } .
|
|
71
|
+
|
|
72
|
+
# In the low-forward-bias regime, a junction in the quantum-transfer state can
|
|
73
|
+
# become a sub-threshold current state.
|
|
74
|
+
{ ?J :canBecome :QuantumTransferState ;
|
|
75
|
+
:biasRegime :LowForwardBias . }
|
|
76
|
+
=>
|
|
77
|
+
{ ?J :canBecome :SubThresholdCurrentState . } .
|
|
78
|
+
|
|
79
|
+
# If the junction is scanned across the peak-to-valley window, it can become a
|
|
80
|
+
# negative differential response state.
|
|
81
|
+
{ ?J :canBecome :QuantumTransferState ;
|
|
82
|
+
:scanProfile :PeakToValley . }
|
|
83
|
+
=>
|
|
84
|
+
{ ?J :canBecome :NegativeDifferentialResponseState . } .
|
|
85
|
+
|
|
86
|
+
# A wake-switch device that can become a sub-threshold current state can become
|
|
87
|
+
# an ultra-low-bias switching state.
|
|
88
|
+
{ ?J :canBecome :SubThresholdCurrentState ;
|
|
89
|
+
:deviceRole :WakeSwitch . }
|
|
90
|
+
=>
|
|
91
|
+
{ ?J :canBecome :UltraLowBiasSwitchingState . } .
|
|
92
|
+
|
|
93
|
+
# If the device can become an ultra-low-bias switching state and the node needs
|
|
94
|
+
# microwatt wake switching, it can become a wake-serving device.
|
|
95
|
+
{ ?J :canBecome :UltraLowBiasSwitchingState .
|
|
96
|
+
:leakAlarmNode :needs :MicrowattWakeSwitching . }
|
|
97
|
+
=>
|
|
98
|
+
{ ?J :canBecome :LeakAlarmWakeServingState . } .
|
|
99
|
+
|
|
100
|
+
# -----------------------------------------------
|
|
101
|
+
# CANNOT-BECOME rules — blocked state transitions
|
|
102
|
+
# -----------------------------------------------
|
|
103
|
+
|
|
104
|
+
# A conventional wide-depletion low-bias junction without state overlap cannot
|
|
105
|
+
# become a quantum-transfer-supporting junction.
|
|
106
|
+
{ ?J a :PNJunction ;
|
|
107
|
+
:doping :Standard ;
|
|
108
|
+
:depletionWidth :Wide ;
|
|
109
|
+
:stateAlignment :NoOverlap . }
|
|
110
|
+
=>
|
|
111
|
+
{ ?J :cannotBecome :QuantumTransferState . } .
|
|
112
|
+
|
|
113
|
+
# Without that quantum-transfer state, the junction cannot become a
|
|
114
|
+
# sub-threshold current state in the same low-bias regime.
|
|
115
|
+
{ ?J :cannotBecome :QuantumTransferState ;
|
|
116
|
+
:biasRegime :LowForwardBias . }
|
|
117
|
+
=>
|
|
118
|
+
{ ?J :cannotBecome :SubThresholdCurrentState . } .
|
|
119
|
+
|
|
120
|
+
# Without quantum transfer, the tunnel-style negative differential state is
|
|
121
|
+
# blocked as well.
|
|
122
|
+
{ ?J :cannotBecome :QuantumTransferState . }
|
|
123
|
+
=>
|
|
124
|
+
{ ?J :cannotBecome :NegativeDifferentialResponseState . } .
|
|
125
|
+
|
|
126
|
+
# Without sub-threshold current, the device cannot become an ultra-low-bias
|
|
127
|
+
# switching state.
|
|
128
|
+
{ ?J :cannotBecome :SubThresholdCurrentState ;
|
|
129
|
+
:deviceRole :WakeSwitch . }
|
|
130
|
+
=>
|
|
131
|
+
{ ?J :cannotBecome :UltraLowBiasSwitchingState . } .
|
|
132
|
+
|
|
133
|
+
# Without ultra-low-bias switching, the device cannot become a wake-serving
|
|
134
|
+
# device for the leak-alarm node.
|
|
135
|
+
{ ?J :cannotBecome :UltraLowBiasSwitchingState .
|
|
136
|
+
:leakAlarmNode :needs :MicrowattWakeSwitching . }
|
|
137
|
+
=>
|
|
138
|
+
{ ?J :cannotBecome :LeakAlarmWakeServingState . } .
|
|
139
|
+
|
|
140
|
+
# ------
|
|
141
|
+
# Checks
|
|
142
|
+
# ------
|
|
143
|
+
|
|
144
|
+
{ :tunnelJunction :canBecome :QuantumTransferState . }
|
|
145
|
+
=> { :case :checkB1 :Passed . } .
|
|
146
|
+
|
|
147
|
+
{ :tunnelJunction :transportMode :TunnelingDominant . }
|
|
148
|
+
=> { :case :checkB2 :Passed . } .
|
|
149
|
+
|
|
150
|
+
{ :tunnelJunction :canBecome :SubThresholdCurrentState . }
|
|
151
|
+
=> { :case :checkB3 :Passed . } .
|
|
152
|
+
|
|
153
|
+
{ :tunnelJunction :canBecome :NegativeDifferentialResponseState . }
|
|
154
|
+
=> { :case :checkB4 :Passed . } .
|
|
155
|
+
|
|
156
|
+
{ :tunnelJunction :canBecome :UltraLowBiasSwitchingState . }
|
|
157
|
+
=> { :case :checkB5 :Passed . } .
|
|
158
|
+
|
|
159
|
+
{ :tunnelJunction :canBecome :LeakAlarmWakeServingState . }
|
|
160
|
+
=> { :case :checkB6 :Passed . } .
|
|
161
|
+
|
|
162
|
+
{ :ordinaryJunction :cannotBecome :QuantumTransferState . }
|
|
163
|
+
=> { :case :checkB7 :Passed . } .
|
|
164
|
+
|
|
165
|
+
{ :ordinaryJunction :cannotBecome :SubThresholdCurrentState . }
|
|
166
|
+
=> { :case :checkB8 :Passed . } .
|
|
167
|
+
|
|
168
|
+
{ :ordinaryJunction :cannotBecome :NegativeDifferentialResponseState . }
|
|
169
|
+
=> { :case :checkB9 :Passed . } .
|
|
170
|
+
|
|
171
|
+
{ :ordinaryJunction :cannotBecome :UltraLowBiasSwitchingState . }
|
|
172
|
+
=> { :case :checkB10 :Passed . } .
|
|
173
|
+
|
|
174
|
+
{ :ordinaryJunction :cannotBecome :LeakAlarmWakeServingState . }
|
|
175
|
+
=> { :case :checkB11 :Passed . } .
|
|
176
|
+
|
|
177
|
+
# ----------------
|
|
178
|
+
# ARC-style output
|
|
179
|
+
# ----------------
|
|
180
|
+
|
|
181
|
+
{ :case :checkB1 :Passed .
|
|
182
|
+
:case :checkB2 :Passed .
|
|
183
|
+
:case :checkB3 :Passed .
|
|
184
|
+
:case :checkB4 :Passed .
|
|
185
|
+
:case :checkB5 :Passed .
|
|
186
|
+
:case :checkB6 :Passed .
|
|
187
|
+
:case :checkB7 :Passed .
|
|
188
|
+
:case :checkB8 :Passed .
|
|
189
|
+
:case :checkB9 :Passed .
|
|
190
|
+
:case :checkB10 :Passed .
|
|
191
|
+
:case :checkB11 :Passed . }
|
|
192
|
+
=>
|
|
193
|
+
{
|
|
194
|
+
:out log:outputString """tunnel-junction wake switch — becoming
|
|
195
|
+
|
|
196
|
+
Answer
|
|
197
|
+
YES for the tunnel junction.
|
|
198
|
+
NO for the conventional low-bias PN junction in the same wake-switch regime.
|
|
199
|
+
|
|
200
|
+
Reason Why
|
|
201
|
+
The tunnel junction can be read as a becoming under low forward bias. Because it is modeled as a heavily doped narrow PN junction with overlapping states, it can become a quantum-transfer state. In that regime it can become a sub-threshold current state, and under peak-to-valley scanning it can also become a negative differential response state. As a wake-switch device, that lets it become an ultra-low-bias switching state and finally a leak-alarm wake-serving state. By contrast, the conventional junction lacks the structural conditions needed for the same transition into quantum transfer, so the later wake-serving becoming is blocked as well.
|
|
202
|
+
|
|
203
|
+
Check
|
|
204
|
+
B1 OK - the tunnel junction can become a quantum-transfer state
|
|
205
|
+
B2 OK - the tunnel junction is classified as tunneling-dominant
|
|
206
|
+
B3 OK - the tunnel junction can become a sub-threshold current state
|
|
207
|
+
B4 OK - the tunnel junction can become a negative differential response state
|
|
208
|
+
B5 OK - the tunnel junction can become an ultra-low-bias switching state
|
|
209
|
+
B6 OK - the tunnel junction can become a leak-alarm wake-serving state
|
|
210
|
+
B7 OK - the conventional junction cannot become a quantum-transfer state
|
|
211
|
+
B8 OK - the conventional junction cannot become a sub-threshold current state
|
|
212
|
+
B9 OK - the conventional junction cannot become the tunnel-style negative differential state
|
|
213
|
+
B10 OK - the conventional junction cannot become an ultra-low-bias switching state here
|
|
214
|
+
B11 OK - the conventional junction cannot become a leak-alarm wake-serving state in this case
|
|
215
|
+
""" .
|
|
216
|
+
} .
|
package/eyeling.js
CHANGED
|
@@ -4921,6 +4921,7 @@ const { pathToFileURL } = require('node:url');
|
|
|
4921
4921
|
const engine = require('./engine');
|
|
4922
4922
|
const deref = require('./deref');
|
|
4923
4923
|
const { PrefixEnv } = require('./prelude');
|
|
4924
|
+
const { parseN3Text, mergeParsedDocuments } = require('./multisource');
|
|
4924
4925
|
|
|
4925
4926
|
function offsetToLineCol(text, offset) {
|
|
4926
4927
|
const chars = Array.from(text);
|
|
@@ -5004,8 +5005,9 @@ function main() {
|
|
|
5004
5005
|
|
|
5005
5006
|
function printHelp(toStderr = false) {
|
|
5006
5007
|
const msg =
|
|
5007
|
-
`Usage: ${prog} [options] [file.n3|-]\n\n` +
|
|
5008
|
-
`When no file is given and stdin is piped, read N3 from stdin.\n
|
|
5008
|
+
`Usage: ${prog} [options] [file-or-url.n3|- ...]\n\n` +
|
|
5009
|
+
`When no file is given and stdin is piped, read N3 from stdin.\n` +
|
|
5010
|
+
`When multiple inputs are given, parse each source separately, merge ASTs, then reason once.\n\n` +
|
|
5009
5011
|
`Options:\n` +
|
|
5010
5012
|
` -a, --ast Print parsed AST as JSON and exit.\n` +
|
|
5011
5013
|
` --builtin <module.js> Load a custom builtin module (repeatable).\n` +
|
|
@@ -5049,7 +5051,7 @@ function main() {
|
|
|
5049
5051
|
builtinModules.push(a.slice('--builtin='.length));
|
|
5050
5052
|
continue;
|
|
5051
5053
|
}
|
|
5052
|
-
if (!a.startsWith('-')) positional.push(a);
|
|
5054
|
+
if (a === '-' || !a.startsWith('-')) positional.push(a);
|
|
5053
5055
|
}
|
|
5054
5056
|
|
|
5055
5057
|
const showAst = argv.includes('--ast') || argv.includes('-a');
|
|
@@ -5075,17 +5077,12 @@ function main() {
|
|
|
5075
5077
|
if (typeof engine.setSuperRestrictedMode === 'function') engine.setSuperRestrictedMode(true);
|
|
5076
5078
|
}
|
|
5077
5079
|
|
|
5078
|
-
// Positional args (
|
|
5080
|
+
// Positional args (one or more N3 sources).
|
|
5079
5081
|
const useImplicitStdin = positional.length === 0 && !process.stdin.isTTY;
|
|
5080
5082
|
if (positional.length === 0 && !useImplicitStdin) {
|
|
5081
5083
|
printHelp(false);
|
|
5082
5084
|
process.exit(0);
|
|
5083
5085
|
}
|
|
5084
|
-
if (positional.length > 1) {
|
|
5085
|
-
console.error('Error: expected at most one input [file.n3|-].');
|
|
5086
|
-
printHelp(true);
|
|
5087
|
-
process.exit(1);
|
|
5088
|
-
}
|
|
5089
5086
|
|
|
5090
5087
|
for (const spec of builtinModules) {
|
|
5091
5088
|
try {
|
|
@@ -5097,35 +5094,47 @@ function main() {
|
|
|
5097
5094
|
}
|
|
5098
5095
|
}
|
|
5099
5096
|
|
|
5100
|
-
const
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
let text;
|
|
5104
|
-
try {
|
|
5105
|
-
text = __readInputSourceSync(sourceLabel);
|
|
5106
|
-
} catch (e) {
|
|
5107
|
-
if (sourceLabel === '<stdin>') console.error(`Error reading stdin: ${e.message}`);
|
|
5108
|
-
else console.error(`Error reading file ${JSON.stringify(sourceLabel)}: ${e.message}`);
|
|
5097
|
+
const sourceLabels = useImplicitStdin ? ['<stdin>'] : positional.map((item) => (item === '-' ? '<stdin>' : item));
|
|
5098
|
+
if (sourceLabels.filter((item) => item === '<stdin>').length > 1) {
|
|
5099
|
+
console.error('Error: stdin can only be used once.');
|
|
5109
5100
|
process.exit(1);
|
|
5110
5101
|
}
|
|
5111
5102
|
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
engine.setTracePrefixes(prefixes);
|
|
5121
|
-
} catch (e) {
|
|
5122
|
-
if (e && e.name === 'N3SyntaxError') {
|
|
5123
|
-
console.error(formatN3SyntaxError(e, text, sourceLabel));
|
|
5103
|
+
const parsedSources = [];
|
|
5104
|
+
for (const sourceLabel of sourceLabels) {
|
|
5105
|
+
let text;
|
|
5106
|
+
try {
|
|
5107
|
+
text = __readInputSourceSync(sourceLabel);
|
|
5108
|
+
} catch (e) {
|
|
5109
|
+
if (sourceLabel === '<stdin>') console.error(`Error reading stdin: ${e.message}`);
|
|
5110
|
+
else console.error(`Error reading source ${JSON.stringify(sourceLabel)}: ${e.message}`);
|
|
5124
5111
|
process.exit(1);
|
|
5125
5112
|
}
|
|
5126
|
-
|
|
5113
|
+
|
|
5114
|
+
try {
|
|
5115
|
+
parsedSources.push(
|
|
5116
|
+
parseN3Text(text, {
|
|
5117
|
+
baseIri: __sourceLabelToBaseIri(sourceLabel),
|
|
5118
|
+
label: sourceLabel,
|
|
5119
|
+
}),
|
|
5120
|
+
);
|
|
5121
|
+
} catch (e) {
|
|
5122
|
+
if (e && e.name === 'N3SyntaxError') {
|
|
5123
|
+
console.error(formatN3SyntaxError(e, text, sourceLabel));
|
|
5124
|
+
process.exit(1);
|
|
5125
|
+
}
|
|
5126
|
+
throw e;
|
|
5127
|
+
}
|
|
5127
5128
|
}
|
|
5128
5129
|
|
|
5130
|
+
const mergedDocument = mergeParsedDocuments(parsedSources);
|
|
5131
|
+
const prefixes = mergedDocument.prefixes;
|
|
5132
|
+
const triples = mergedDocument.triples;
|
|
5133
|
+
const frules = mergedDocument.frules;
|
|
5134
|
+
const brules = mergedDocument.brules;
|
|
5135
|
+
const qrules = mergedDocument.logQueryRules;
|
|
5136
|
+
const tokenSets = parsedSources.map((source) => ({ tokens: source.tokens, prefixes: source.prefixes }));
|
|
5137
|
+
|
|
5129
5138
|
if (showAst) {
|
|
5130
5139
|
function astReplacer(unusedJsonKey, value) {
|
|
5131
5140
|
if (value instanceof Set) return Array.from(value);
|
|
@@ -5267,7 +5276,10 @@ function main() {
|
|
|
5267
5276
|
const mayAutoRenderOutputStrings = programMayProduceOutputStrings(triples, frules, qrules);
|
|
5268
5277
|
|
|
5269
5278
|
if (streamMode && !hasQueries && !mayAutoRenderOutputStrings) {
|
|
5270
|
-
const usedInInput =
|
|
5279
|
+
const usedInInput = new Set();
|
|
5280
|
+
for (const source of tokenSets) {
|
|
5281
|
+
for (const pfx of prefixesUsedInInputTokens(source.tokens, source.prefixes)) usedInInput.add(pfx);
|
|
5282
|
+
}
|
|
5271
5283
|
const outPrefixes = restrictPrefixEnv(prefixes, usedInInput);
|
|
5272
5284
|
|
|
5273
5285
|
// Ensure log:trace uses the same compact prefix set as the output.
|
|
@@ -5861,6 +5873,7 @@ const EMPTY_LIST_TERM = new ListTerm([]);
|
|
|
5861
5873
|
const { lex, N3SyntaxError } = require('./lexer');
|
|
5862
5874
|
const { Parser } = require('./parser');
|
|
5863
5875
|
const { liftBlankRuleVars } = require('./rules');
|
|
5876
|
+
const { parseN3SourceList } = require('./multisource');
|
|
5864
5877
|
|
|
5865
5878
|
const {
|
|
5866
5879
|
makeBuiltins,
|
|
@@ -9202,7 +9215,8 @@ function reasonStream(input, opts = {}) {
|
|
|
9202
9215
|
builtinModules = null,
|
|
9203
9216
|
} = opts;
|
|
9204
9217
|
|
|
9205
|
-
const
|
|
9218
|
+
const parsedSourceList = parseN3SourceList(input, { baseIri });
|
|
9219
|
+
const parsedInput = parsedSourceList || normalizeParsedReasonerInputSync(input);
|
|
9206
9220
|
const rdfFactory = rdfjs ? getDataFactory(dataFactory) : null;
|
|
9207
9221
|
|
|
9208
9222
|
const __oldEnforceHttps = deref.getEnforceHttpsEnabled();
|
|
@@ -9345,7 +9359,7 @@ function reasonRdfJs(input, opts = {}) {
|
|
|
9345
9359
|
|
|
9346
9360
|
Promise.resolve().then(async () => {
|
|
9347
9361
|
try {
|
|
9348
|
-
const normalizedInput = await normalizeReasonerInputAsync(input);
|
|
9362
|
+
const normalizedInput = parseN3SourceList(input, restOpts) || (await normalizeReasonerInputAsync(input));
|
|
9349
9363
|
reasonStream(normalizedInput, {
|
|
9350
9364
|
...restOpts,
|
|
9351
9365
|
rdfjs: false,
|
|
@@ -10532,6 +10546,213 @@ function lex(inputText) {
|
|
|
10532
10546
|
|
|
10533
10547
|
module.exports = { Token, N3SyntaxError, lex, decodeN3StringEscapes };
|
|
10534
10548
|
|
|
10549
|
+
};
|
|
10550
|
+
__modules["lib/multisource.js"] = function(require, module, exports){
|
|
10551
|
+
/**
|
|
10552
|
+
* Eyeling Reasoner — multi-source parsing helpers
|
|
10553
|
+
*
|
|
10554
|
+
* These helpers let the CLI/API parse several N3 documents independently and
|
|
10555
|
+
* merge their parsed ASTs before reasoning. This avoids building one giant N3
|
|
10556
|
+
* string while preserving the existing lexer/parser/engine pipeline.
|
|
10557
|
+
*/
|
|
10558
|
+
|
|
10559
|
+
'use strict';
|
|
10560
|
+
|
|
10561
|
+
const { lex } = require('./lexer');
|
|
10562
|
+
const { Parser } = require('./parser');
|
|
10563
|
+
const {
|
|
10564
|
+
Blank,
|
|
10565
|
+
ListTerm,
|
|
10566
|
+
OpenListTerm,
|
|
10567
|
+
GraphTerm,
|
|
10568
|
+
Triple,
|
|
10569
|
+
Rule,
|
|
10570
|
+
PrefixEnv,
|
|
10571
|
+
annotateQuotedGraphTerm,
|
|
10572
|
+
} = require('./prelude');
|
|
10573
|
+
|
|
10574
|
+
function emptyParsedDocument() {
|
|
10575
|
+
return {
|
|
10576
|
+
prefixes: PrefixEnv.newDefault(),
|
|
10577
|
+
triples: [],
|
|
10578
|
+
frules: [],
|
|
10579
|
+
brules: [],
|
|
10580
|
+
logQueryRules: [],
|
|
10581
|
+
};
|
|
10582
|
+
}
|
|
10583
|
+
|
|
10584
|
+
function parseN3Text(text, opts = {}) {
|
|
10585
|
+
const { baseIri = '', label = '<input>' } = opts || {};
|
|
10586
|
+
const tokens = lex(text);
|
|
10587
|
+
const parser = new Parser(tokens);
|
|
10588
|
+
if (baseIri) parser.prefixes.setBase(baseIri);
|
|
10589
|
+
const [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
|
|
10590
|
+
return { prefixes, triples, frules, brules, logQueryRules, tokens, text, label };
|
|
10591
|
+
}
|
|
10592
|
+
|
|
10593
|
+
function sourceBlankPrefix(sourceIndex) {
|
|
10594
|
+
return `_:src${sourceIndex}_`;
|
|
10595
|
+
}
|
|
10596
|
+
|
|
10597
|
+
function scopedBlankLabel(label, sourceIndex, mapping) {
|
|
10598
|
+
const key = String(label || '');
|
|
10599
|
+
let out = mapping.get(key);
|
|
10600
|
+
if (out) return out;
|
|
10601
|
+
|
|
10602
|
+
const bare = key.startsWith('_:') ? key.slice(2) : key;
|
|
10603
|
+
out = sourceBlankPrefix(sourceIndex) + bare;
|
|
10604
|
+
mapping.set(key, out);
|
|
10605
|
+
return out;
|
|
10606
|
+
}
|
|
10607
|
+
|
|
10608
|
+
function scopeBlankNodesInDocument(doc, sourceIndex) {
|
|
10609
|
+
const mapping = new Map();
|
|
10610
|
+
|
|
10611
|
+
function cloneTerm(term) {
|
|
10612
|
+
if (term instanceof Blank) return new Blank(scopedBlankLabel(term.label, sourceIndex, mapping));
|
|
10613
|
+
if (term instanceof ListTerm) return new ListTerm(term.elems.map(cloneTerm));
|
|
10614
|
+
if (term instanceof OpenListTerm) return new OpenListTerm(term.prefix.map(cloneTerm), term.tailVar);
|
|
10615
|
+
if (term instanceof GraphTerm) return annotateQuotedGraphTerm(new GraphTerm(term.triples.map(cloneTriple)));
|
|
10616
|
+
return term;
|
|
10617
|
+
}
|
|
10618
|
+
|
|
10619
|
+
function cloneTriple(triple) {
|
|
10620
|
+
return new Triple(cloneTerm(triple.s), cloneTerm(triple.p), cloneTerm(triple.o));
|
|
10621
|
+
}
|
|
10622
|
+
|
|
10623
|
+
function cloneRule(rule) {
|
|
10624
|
+
const headBlankLabels = new Set();
|
|
10625
|
+
if (rule && rule.headBlankLabels instanceof Set) {
|
|
10626
|
+
for (const label of rule.headBlankLabels) headBlankLabels.add(scopedBlankLabel(label, sourceIndex, mapping));
|
|
10627
|
+
}
|
|
10628
|
+
|
|
10629
|
+
const out = new Rule(
|
|
10630
|
+
(rule.premise || []).map(cloneTriple),
|
|
10631
|
+
(rule.conclusion || []).map(cloneTriple),
|
|
10632
|
+
rule.isForward,
|
|
10633
|
+
rule.isFuse,
|
|
10634
|
+
headBlankLabels,
|
|
10635
|
+
);
|
|
10636
|
+
|
|
10637
|
+
if (rule && Object.prototype.hasOwnProperty.call(rule, '__dynamicConclusionTerm')) {
|
|
10638
|
+
Object.defineProperty(out, '__dynamicConclusionTerm', {
|
|
10639
|
+
value: cloneTerm(rule.__dynamicConclusionTerm),
|
|
10640
|
+
enumerable: false,
|
|
10641
|
+
writable: false,
|
|
10642
|
+
configurable: true,
|
|
10643
|
+
});
|
|
10644
|
+
}
|
|
10645
|
+
|
|
10646
|
+
return out;
|
|
10647
|
+
}
|
|
10648
|
+
|
|
10649
|
+
return {
|
|
10650
|
+
prefixes: doc.prefixes,
|
|
10651
|
+
triples: (doc.triples || []).map(cloneTriple),
|
|
10652
|
+
frules: (doc.frules || []).map(cloneRule),
|
|
10653
|
+
brules: (doc.brules || []).map(cloneRule),
|
|
10654
|
+
logQueryRules: (doc.logQueryRules || []).map(cloneRule),
|
|
10655
|
+
tokens: doc.tokens,
|
|
10656
|
+
text: doc.text,
|
|
10657
|
+
label: doc.label,
|
|
10658
|
+
};
|
|
10659
|
+
}
|
|
10660
|
+
|
|
10661
|
+
function mergePrefixEnvs(target, source) {
|
|
10662
|
+
if (!source) return target;
|
|
10663
|
+
const map = source.map || {};
|
|
10664
|
+
for (const [prefix, iri] of Object.entries(map)) {
|
|
10665
|
+
// Every parser starts with an empty default namespace. Do not let a later
|
|
10666
|
+
// source that never declared ':' erase a useful default namespace from an
|
|
10667
|
+
// earlier source; prefix merging is for output readability only.
|
|
10668
|
+
if (iri || !Object.prototype.hasOwnProperty.call(target.map, prefix)) target.set(prefix, iri);
|
|
10669
|
+
}
|
|
10670
|
+
if (source.baseIri) target.setBase(source.baseIri);
|
|
10671
|
+
return target;
|
|
10672
|
+
}
|
|
10673
|
+
|
|
10674
|
+
function mergeParsedDocuments(docs, opts = {}) {
|
|
10675
|
+
const documents = Array.isArray(docs) ? docs : [];
|
|
10676
|
+
const scopeBlankNodes =
|
|
10677
|
+
typeof opts.scopeBlankNodes === 'boolean' ? opts.scopeBlankNodes : documents.length > 1;
|
|
10678
|
+
|
|
10679
|
+
const merged = emptyParsedDocument();
|
|
10680
|
+
const mergedSources = [];
|
|
10681
|
+
|
|
10682
|
+
for (let i = 0; i < documents.length; i++) {
|
|
10683
|
+
const originalDoc = documents[i] || emptyParsedDocument();
|
|
10684
|
+
const doc = scopeBlankNodes ? scopeBlankNodesInDocument(originalDoc, i + 1) : originalDoc;
|
|
10685
|
+
|
|
10686
|
+
mergePrefixEnvs(merged.prefixes, doc.prefixes);
|
|
10687
|
+
merged.triples.push(...(doc.triples || []));
|
|
10688
|
+
merged.frules.push(...(doc.frules || []));
|
|
10689
|
+
merged.brules.push(...(doc.brules || []));
|
|
10690
|
+
merged.logQueryRules.push(...(doc.logQueryRules || []));
|
|
10691
|
+
mergedSources.push(doc);
|
|
10692
|
+
}
|
|
10693
|
+
|
|
10694
|
+
Object.defineProperty(merged, 'sources', {
|
|
10695
|
+
value: mergedSources,
|
|
10696
|
+
enumerable: false,
|
|
10697
|
+
writable: false,
|
|
10698
|
+
configurable: true,
|
|
10699
|
+
});
|
|
10700
|
+
|
|
10701
|
+
return merged;
|
|
10702
|
+
}
|
|
10703
|
+
|
|
10704
|
+
function isN3SourceListInput(input) {
|
|
10705
|
+
return !!(
|
|
10706
|
+
input &&
|
|
10707
|
+
typeof input === 'object' &&
|
|
10708
|
+
!Array.isArray(input) &&
|
|
10709
|
+
Array.isArray(input.sources)
|
|
10710
|
+
);
|
|
10711
|
+
}
|
|
10712
|
+
|
|
10713
|
+
function normalizeN3SourceItem(source, index) {
|
|
10714
|
+
const sourceNumber = index + 1;
|
|
10715
|
+
if (typeof source === 'string') {
|
|
10716
|
+
return { text: source, label: `<source ${sourceNumber}>`, baseIri: '' };
|
|
10717
|
+
}
|
|
10718
|
+
if (!source || typeof source !== 'object' || Array.isArray(source)) {
|
|
10719
|
+
throw new TypeError('Each N3 source must be a string or an object with an n3/text field');
|
|
10720
|
+
}
|
|
10721
|
+
|
|
10722
|
+
const text = typeof source.n3 === 'string' ? source.n3 : typeof source.text === 'string' ? source.text : null;
|
|
10723
|
+
if (text === null) throw new TypeError('Each N3 source object must provide an n3 or text string');
|
|
10724
|
+
|
|
10725
|
+
return {
|
|
10726
|
+
text,
|
|
10727
|
+
label: typeof source.label === 'string' && source.label ? source.label : `<source ${sourceNumber}>`,
|
|
10728
|
+
baseIri: typeof source.baseIri === 'string' ? source.baseIri : '',
|
|
10729
|
+
};
|
|
10730
|
+
}
|
|
10731
|
+
|
|
10732
|
+
function parseN3SourceList(input, opts = {}) {
|
|
10733
|
+
if (!isN3SourceListInput(input)) return null;
|
|
10734
|
+
const sources = input.sources.map(normalizeN3SourceItem);
|
|
10735
|
+
const defaultBaseIri = typeof opts.baseIri === 'string' ? opts.baseIri : '';
|
|
10736
|
+
const parsed = sources.map((source, index) =>
|
|
10737
|
+
parseN3Text(source.text, {
|
|
10738
|
+
label: source.label,
|
|
10739
|
+
baseIri: source.baseIri || (sources.length === 1 ? defaultBaseIri : ''),
|
|
10740
|
+
}),
|
|
10741
|
+
);
|
|
10742
|
+
return mergeParsedDocuments(parsed, {
|
|
10743
|
+
scopeBlankNodes: typeof input.scopeBlankNodes === 'boolean' ? input.scopeBlankNodes : parsed.length > 1,
|
|
10744
|
+
});
|
|
10745
|
+
}
|
|
10746
|
+
|
|
10747
|
+
module.exports = {
|
|
10748
|
+
emptyParsedDocument,
|
|
10749
|
+
parseN3Text,
|
|
10750
|
+
mergeParsedDocuments,
|
|
10751
|
+
scopeBlankNodesInDocument,
|
|
10752
|
+
isN3SourceListInput,
|
|
10753
|
+
parseN3SourceList,
|
|
10754
|
+
};
|
|
10755
|
+
|
|
10535
10756
|
};
|
|
10536
10757
|
__modules["lib/parser.js"] = function(require, module, exports){
|
|
10537
10758
|
/**
|
package/index.d.ts
CHANGED
|
@@ -120,6 +120,13 @@ declare module 'eyeling' {
|
|
|
120
120
|
|
|
121
121
|
export type EyelingAstBundle = [EyelingPrefixEnv, EyelingTriple[], EyelingRule[], EyelingRule[], EyelingRule[]?];
|
|
122
122
|
|
|
123
|
+
export type N3Source = string | { n3?: string; text?: string; baseIri?: string; label?: string };
|
|
124
|
+
|
|
125
|
+
export interface N3SourceListInput {
|
|
126
|
+
sources: N3Source[];
|
|
127
|
+
scopeBlankNodes?: boolean;
|
|
128
|
+
}
|
|
129
|
+
|
|
123
130
|
export interface RdfJsReasonInput {
|
|
124
131
|
n3?: string;
|
|
125
132
|
quads?: Iterable<RdfJsQuad> | AsyncIterable<RdfJsQuad>;
|
|
@@ -189,13 +196,16 @@ declare module 'eyeling' {
|
|
|
189
196
|
queryQuads?: RdfJsQuad[];
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
export function reason(
|
|
199
|
+
export function reason(
|
|
200
|
+
opts: ReasonOptions,
|
|
201
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
202
|
+
): string;
|
|
193
203
|
export function reasonStream(
|
|
194
|
-
input: string | RdfJsReasonInput | EyelingAstBundle,
|
|
204
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
195
205
|
opts?: ReasonStreamOptions,
|
|
196
206
|
): ReasonStreamResult;
|
|
197
207
|
export function reasonRdfJs(
|
|
198
|
-
input: string | RdfJsReasonInput | EyelingAstBundle,
|
|
208
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
199
209
|
opts?: Omit<ReasonStreamOptions, 'rdfjs' | 'onDerived'>,
|
|
200
210
|
): AsyncIterable<RdfJsQuad>;
|
|
201
211
|
|
|
@@ -212,16 +222,18 @@ declare module 'eyeling/browser' {
|
|
|
212
222
|
export type RdfJsQuad = import('eyeling').RdfJsQuad;
|
|
213
223
|
export type RdfJsReasonInput = import('eyeling').RdfJsReasonInput;
|
|
214
224
|
export type EyelingAstBundle = import('eyeling').EyelingAstBundle;
|
|
225
|
+
export type N3Source = import('eyeling').N3Source;
|
|
226
|
+
export type N3SourceListInput = import('eyeling').N3SourceListInput;
|
|
215
227
|
export type ReasonStreamOptions = import('eyeling').ReasonStreamOptions;
|
|
216
228
|
export type ReasonStreamResult = import('eyeling').ReasonStreamResult;
|
|
217
229
|
export type BuiltinHandler = import('eyeling').BuiltinHandler;
|
|
218
230
|
|
|
219
231
|
export function reasonStream(
|
|
220
|
-
input: string | RdfJsReasonInput | EyelingAstBundle,
|
|
232
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
221
233
|
opts?: ReasonStreamOptions,
|
|
222
234
|
): ReasonStreamResult;
|
|
223
235
|
export function reasonRdfJs(
|
|
224
|
-
input: string | RdfJsReasonInput | EyelingAstBundle,
|
|
236
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
225
237
|
opts?: Omit<ReasonStreamOptions, 'rdfjs' | 'onDerived'>,
|
|
226
238
|
): AsyncIterable<RdfJsQuad>;
|
|
227
239
|
|