eyeling 1.26.7 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/HANDBOOK.md +32 -1
  2. package/dist/browser/eyeling.browser.js +396 -3
  3. package/examples/deck/act-barley-seed-lineage.md +1 -1
  4. package/examples/deck/faltings-genus2-finiteness.md +1 -1
  5. package/examples/deck/high-trust-rdf-bloom-envelope.md +1 -1
  6. package/examples/deck/odrl-dpv-risk-ranked.md +1 -1
  7. package/examples/deck/rdf-message-cold-chain-recall.md +71 -0
  8. package/examples/deck/rdf-message-flow.md +1 -1
  9. package/examples/deck/rdf-message-ldes-incremental.md +94 -0
  10. package/examples/deck/rdf-message-window-repair.md +1 -1
  11. package/examples/deck/schema-foaf-mapping.md +2 -0
  12. package/examples/input/rdf-message-cold-chain-recall.trig +668 -0
  13. package/examples/input/rdf-message-flow.trig +3 -0
  14. package/examples/input/rdf-message-ldes-incremental.trig +564 -0
  15. package/examples/input/rdf-message-microgrid.trig +3 -0
  16. package/examples/input/rdf-message-window-repair.trig +3 -0
  17. package/examples/input/rdf-messages.trig +3 -0
  18. package/examples/output/rdf-message-cold-chain-recall.md +13 -0
  19. package/examples/output/rdf-message-ldes-incremental.md +13 -0
  20. package/examples/rdf-message-cold-chain-recall.n3 +229 -0
  21. package/examples/rdf-message-flow.n3 +3 -0
  22. package/examples/rdf-message-ldes-incremental.n3 +231 -0
  23. package/examples/rdf-message-microgrid.n3 +3 -0
  24. package/examples/rdf-message-window-repair.n3 +3 -0
  25. package/examples/rdf-messages.n3 +3 -0
  26. package/eyeling.js +396 -3
  27. package/lib/cli.js +396 -3
  28. package/package.json +5 -3
  29. package/test/examples.test.js +25 -14
  30. package/test/fixtures/marc-rules-stream-messages.n3 +192 -0
  31. package/test/stream_messages.test.js +243 -0
@@ -0,0 +1,229 @@
1
+ # =================================
2
+ # RDF Message Cold Chain Recall
3
+ # =================================
4
+ #
5
+ # Run as:
6
+ #
7
+ # eyeling -r examples/rdf-message-cold-chain-recall.n3 examples/input/rdf-message-cold-chain-recall.trig
8
+ #
9
+ # See the handbook section on RDF Message Log replay under -r:
10
+ # https://eyereasoner.github.io/eyeling/HANDBOOK#rdf-message-log-replay-under--r
11
+ #
12
+ # This example is meant to be operationally obvious: a cold-chain shipment has
13
+ # many historical telemetry messages, a checkpoint says which prefix was already
14
+ # processed, and the new tail contains inconsistent evidence about whether a
15
+ # medicine batch stayed below its temperature limit. The repair keeps the
16
+ # calibrated logger reading before materializing a recall/quarantine decision.
17
+
18
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-message-cold-chain-recall#>.
19
+ @prefix eymsg: <https://eyereasoner.github.io/eyeling/vocab/message#>.
20
+ @prefix ldes: <https://w3id.org/ldes#>.
21
+ @prefix tree: <https://w3id.org/tree#>.
22
+ @prefix list: <http://www.w3.org/2000/10/swap/list#>.
23
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
24
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
25
+ @prefix string: <http://www.w3.org/2000/10/swap/string#>.
26
+
27
+ # Parser replay gives us an ordered RDF Message stream. Keep this visible in
28
+ # the derived data so the report can say how many messages were processed.
29
+ {
30
+ ?Stream a eymsg:RDFMessageStream;
31
+ eymsg:envelope ?Envelope.
32
+ ?Envelope a eymsg:MessageEnvelope;
33
+ eymsg:offset ?Offset.
34
+ } => {
35
+ ?Envelope :messageOffset ?Offset;
36
+ :messageBoundaryExplicit true.
37
+ }.
38
+
39
+ # Message 1 carries stream metadata and the consumer checkpoint. Everything up
40
+ # to sequence 42 was already materialized by a previous synchronization run.
41
+ {
42
+ ?Envelope eymsg:payloadGraph ?Payload.
43
+ ?Payload log:nameOf ?PayloadContext.
44
+ ?PayloadContext log:includes {
45
+ :telemetryStream a ldes:EventStream;
46
+ ldes:timestampPath :observedAt;
47
+ ldes:sequencePath :sequence;
48
+ tree:view :telemetryPage;
49
+ :lastCommittedSequence ?Bookmark;
50
+ :currentWindowFromSequence ?WindowStart;
51
+ :temperatureLimitTenthC ?Limit;
52
+ :temperatureLimitLabel ?LimitLabel;
53
+ :repairPolicy :preferCalibratedLogger.
54
+ :quarantineDecision :decisionText ?DecisionText.
55
+ }.
56
+ } => {
57
+ :telemetryStream a ldes:EventStream;
58
+ ldes:timestampPath :observedAt;
59
+ ldes:sequencePath :sequence;
60
+ tree:view :telemetryPage;
61
+ :lastCommittedSequence ?Bookmark;
62
+ :currentWindowFromSequence ?WindowStart;
63
+ :temperatureLimitTenthC ?Limit;
64
+ :temperatureLimitLabel ?LimitLabel;
65
+ :repairPolicy :preferCalibratedLogger.
66
+ :quarantineDecision :decisionText ?DecisionText.
67
+ }.
68
+
69
+ # Each RDF Message payload contributes one LDES telemetry member. The payloads
70
+ # stay scoped to their message graphs; the reasoner lifts only the fields needed
71
+ # for incremental classification, repair, and reporting.
72
+ {
73
+ ?Envelope eymsg:payloadGraph ?Payload.
74
+ ?Payload log:nameOf ?PayloadContext.
75
+ ?PayloadContext log:includes {
76
+ :telemetryStream tree:member ?Member.
77
+ ?Member a :ColdChainObservation;
78
+ :sequence ?Sequence;
79
+ :observedAt ?ObservedAt;
80
+ :batch ?Batch;
81
+ :temperatureTenthC ?Temperature;
82
+ :temperatureLabel ?TemperatureLabel;
83
+ :priority ?Priority;
84
+ :source ?Source.
85
+ }.
86
+ } => {
87
+ ?Member :ldesMember true;
88
+ :envelope ?Envelope;
89
+ :sequence ?Sequence;
90
+ :observedAt ?ObservedAt;
91
+ :batch ?Batch;
92
+ :temperatureTenthC ?Temperature;
93
+ :temperatureLabel ?TemperatureLabel;
94
+ :priority ?Priority;
95
+ :source ?Source.
96
+ ?Envelope :emitsLDESMember ?Member.
97
+ }.
98
+
99
+
100
+ # Carry optional calibration metadata when a telemetry member has it. Most
101
+ # sensors do not; the calibrated logger in the noisy tail does.
102
+ {
103
+ ?Envelope eymsg:payloadGraph ?Payload.
104
+ ?Payload log:nameOf ?PayloadContext.
105
+ ?PayloadContext log:includes {
106
+ ?Member :calibrationClass ?CalibrationClass.
107
+ }.
108
+ } => {
109
+ ?Member :calibrationClass ?CalibrationClass.
110
+ }.
111
+
112
+ # The checkpoint separates the large committed prefix from the new tail.
113
+ {
114
+ :telemetryStream :lastCommittedSequence ?Bookmark.
115
+ ?Member :ldesMember true;
116
+ :sequence ?Sequence.
117
+ ?Sequence math:notGreaterThan ?Bookmark.
118
+ } => {
119
+ ?Member :alreadyCommitted true.
120
+ }.
121
+
122
+ {
123
+ :telemetryStream :lastCommittedSequence ?Bookmark.
124
+ ?Member :ldesMember true;
125
+ :sequence ?Sequence.
126
+ ?Sequence math:greaterThan ?Bookmark.
127
+ } => {
128
+ ?Member :newlyEmitted true.
129
+ }.
130
+
131
+ {
132
+ :telemetryStream :currentWindowFromSequence ?WindowStart.
133
+ ?Member :newlyEmitted true;
134
+ :sequence ?Sequence.
135
+ ?Sequence math:notLessThan ?WindowStart.
136
+ } => {
137
+ :currentColdChainWindow :contains ?Member.
138
+ ?Member :inCurrentColdChainWindow true.
139
+ }.
140
+
141
+ # The raw tail is inconsistent for batchA: some new telemetry says the batch is
142
+ # still within range, while another message says it crossed the cold-chain limit.
143
+ {
144
+ :telemetryStream :temperatureLimitTenthC ?Limit.
145
+ :currentColdChainWindow :contains ?InRangeMember, ?ExcursionMember.
146
+ ?InRangeMember :batch ?Batch;
147
+ :temperatureTenthC ?InRangeTemperature.
148
+ ?ExcursionMember :batch ?Batch;
149
+ :temperatureTenthC ?ExcursionTemperature.
150
+ ?InRangeTemperature math:notGreaterThan ?Limit.
151
+ ?ExcursionTemperature math:greaterThan ?Limit.
152
+ ?InRangeMember log:notEqualTo ?ExcursionMember.
153
+ } => {
154
+ :currentColdChainWindow :rawConflict :batchBothInRangeAndInExcursion;
155
+ :inconsistentBatch ?Batch.
156
+ }.
157
+
158
+ # Preferred repair: calibrated cold-chain logger evidence wins for recall
159
+ # decisions. In this example it says batchA exceeded the temperature limit.
160
+ {
161
+ :telemetryStream :temperatureLimitTenthC ?Limit.
162
+ :currentColdChainWindow :rawConflict :batchBothInRangeAndInExcursion;
163
+ :contains ?PreferredMember.
164
+ ?PreferredMember :batch ?Batch;
165
+ :temperatureTenthC ?PreferredTemperature;
166
+ :temperatureLabel ?PreferredTemperatureLabel;
167
+ :priority ?PreferredPriority;
168
+ :source ?PreferredSource;
169
+ :sequence ?PreferredSequence;
170
+ :calibrationClass :calibratedLogger.
171
+ ?PreferredTemperature math:greaterThan ?Limit.
172
+ } => {
173
+ :currentColdChainWindow :preferredRepair :calibratedLoggerWins;
174
+ :repairedBatch ?Batch;
175
+ :preferredEvidence ?PreferredMember;
176
+ :preferredSource ?PreferredSource;
177
+ :preferredSequence ?PreferredSequence;
178
+ :preferredPriority ?PreferredPriority;
179
+ :repairedTemperatureTenthC ?PreferredTemperature;
180
+ :repairedTemperatureLabel ?PreferredTemperatureLabel;
181
+ :materializedDecision :quarantineDecision.
182
+ }.
183
+
184
+ # Count the whole stream and the incremental tail. The interesting point is
185
+ # that the input is large enough to make streaming useful, while the repair is
186
+ # local to the new messages after the checkpoint.
187
+ {
188
+ ( ?Member { ?Member :ldesMember true. } ?AllMembers ) log:collectAllIn _:coldChainCounts.
189
+ ?AllMembers list:length ?AllCount.
190
+ ( ?Member { ?Member :alreadyCommitted true. } ?CommittedMembers ) log:collectAllIn _:coldChainCounts.
191
+ ?CommittedMembers list:length ?CommittedCount.
192
+ ( ?Member { ?Member :newlyEmitted true. } ?NewMembers ) log:collectAllIn _:coldChainCounts.
193
+ ?NewMembers list:length ?NewCount.
194
+ ( ?Member { ?Member :inCurrentColdChainWindow true. } ?WindowMembers ) log:collectAllIn _:coldChainCounts.
195
+ ?WindowMembers list:length ?WindowCount.
196
+ } => {
197
+ :incrementalColdChainRun :totalTelemetryMembers ?AllCount;
198
+ :alreadyCommittedMembers ?CommittedCount;
199
+ :newlyEmittedMembers ?NewCount;
200
+ :windowMemberCount ?WindowCount.
201
+ }.
202
+
203
+ # Emit one compact report when replay, checkpointing, conflict detection, repair,
204
+ # and final materialization are all present.
205
+ {
206
+ ?Stream a eymsg:RDFMessageStream;
207
+ eymsg:orderedEnvelopes ?Envelopes.
208
+ ?Envelopes list:length ?EnvelopeCount.
209
+ :telemetryStream :lastCommittedSequence ?Bookmark;
210
+ :temperatureLimitTenthC ?Limit;
211
+ :temperatureLimitLabel ?LimitLabel.
212
+ :incrementalColdChainRun :totalTelemetryMembers ?AllCount;
213
+ :alreadyCommittedMembers ?CommittedCount;
214
+ :newlyEmittedMembers ?NewCount;
215
+ :windowMemberCount ?WindowCount.
216
+ :currentColdChainWindow :rawConflict :batchBothInRangeAndInExcursion;
217
+ :inconsistentBatch :batchA;
218
+ :preferredRepair :calibratedLoggerWins;
219
+ :preferredSource ?PreferredSource;
220
+ :preferredSequence ?PreferredSequence;
221
+ :preferredPriority ?PreferredPriority;
222
+ :repairedTemperatureLabel ?PreferredTemperatureLabel;
223
+ :materializedDecision :quarantineDecision.
224
+ :quarantineDecision :decisionText ?DecisionText.
225
+ ("# rdf-message-cold-chain-recall\n\n## Source files\n\n- [N3 rules](../rdf-message-cold-chain-recall.n3)\n- [Input RDF Message Log](../input/rdf-message-cold-chain-recall.trig)\n- [Story deck](../deck/rdf-message-cold-chain-recall.md)\n\n## Answer\nCold-chain recall reasoning accepted: %d RDF Message envelopes contained %d append-only telemetry members. The consumer checkpoint was sequence %d, so %d committed history members were skipped and only %d newly emitted members entered the repair window. The tail window has %d members and says batchA is both within range and over the %s limit. The repair keeps the calibrated logger evidence at sequence %d from %s with priority %d, resolves the repaired temperature to %s, and materializes the decision: %s.\n\n## Explanation\nThis is the streaming shape that matters operationally. A cold-chain consumer can replay a long RDF Message Log, use LDES sequence metadata to resume after its checkpoint, and inspect only the new tail. The raw tail is contradictory, so the rules do not materialize from the flattened data. They first choose the calibrated logger reading, then derive the quarantine decision from that repaired state." ?EnvelopeCount ?AllCount ?Bookmark ?CommittedCount ?NewCount ?WindowCount ?LimitLabel ?PreferredSequence ?PreferredSource ?PreferredPriority ?PreferredTemperatureLabel ?DecisionText) string:format ?Block.
226
+ } => {
227
+ :rdfMessageColdChainRecallExample log:outputString ?Block.
228
+ :rdfMessageColdChainRecallExample :demonstrates :RDFMessageLogReplay, :LDESMemberStream, :CheckpointedSynchronization, :IncrementalColdChainReasoning, :TelemetryConflictRepair, :QuarantineMaterialization.
229
+ }.
@@ -6,6 +6,9 @@
6
6
  #
7
7
  # eyeling -r examples/rdf-message-flow.n3 examples/input/rdf-message-flow.trig
8
8
  #
9
+ # See the handbook section on RDF Message Log replay under -r:
10
+ # https://eyereasoner.github.io/eyeling/HANDBOOK#rdf-message-log-replay-under--r
11
+ #
9
12
  # Motivation
10
13
  # ----------
11
14
  # The RDF Messages draft describes an RDF Message as an RDF dataset interpreted
@@ -0,0 +1,231 @@
1
+ # =====================================
2
+ # RDF Message LDES Incremental Repair
3
+ # =====================================
4
+ #
5
+ # Run as:
6
+ #
7
+ # eyeling -r examples/rdf-message-ldes-incremental.n3 examples/input/rdf-message-ldes-incremental.trig
8
+ #
9
+ # See the handbook section on RDF Message Log replay under -r:
10
+ # https://eyereasoner.github.io/eyeling/HANDBOOK#rdf-message-log-replay-under--r
11
+ #
12
+ # This example combines two streaming ideas:
13
+ #
14
+ # - RDF Messages give parser-level message boundaries for a potentially long
15
+ # stream. Eyeling replays those boundaries as eymsg: envelopes and keeps each
16
+ # payload graph separate.
17
+ # - LDES describes an append-only stream of members with a timestamp/sequence
18
+ # order. The rules below model an incremental consumer that has already
19
+ # committed sequence 34, so it only reasons over the new tail of the log.
20
+ #
21
+ # The input intentionally contains forty LDES members. Only the six members
22
+ # after the checkpoint are part of the current incremental repair window. That
23
+ # tail contains a concrete inconsistency: the same door is both open and closed.
24
+ # The repair keeps the highest-priority assertion before materializing the
25
+ # operational action.
26
+
27
+ @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-message-ldes-incremental#>.
28
+ @prefix eymsg: <https://eyereasoner.github.io/eyeling/vocab/message#>.
29
+ @prefix ldes: <https://w3id.org/ldes#>.
30
+ @prefix tree: <https://w3id.org/tree#>.
31
+ @prefix list: <http://www.w3.org/2000/10/swap/list#>.
32
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
33
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
34
+ @prefix string: <http://www.w3.org/2000/10/swap/string#>.
35
+
36
+ # Eyeling's RDF-message replay gives us a static, ordered view of a message log.
37
+ {
38
+ ?Stream a eymsg:RDFMessageStream;
39
+ eymsg:envelope ?Envelope.
40
+ ?Envelope a eymsg:MessageEnvelope;
41
+ eymsg:offset ?Offset.
42
+ } => {
43
+ ?Envelope :messageOffset ?Offset;
44
+ :messageBoundaryExplicit true.
45
+ }.
46
+
47
+ # Message 1 carries LDES context and the incremental consumer state. The LDES
48
+ # bookmark is the key point: everything up to sequence 34 was already committed
49
+ # by the previous synchronization run.
50
+ {
51
+ ?Envelope eymsg:payloadGraph ?Payload.
52
+ ?Payload log:nameOf ?PayloadContext.
53
+ ?PayloadContext log:includes {
54
+ :doorStream a ldes:EventStream;
55
+ ldes:timestampPath :observedAt;
56
+ ldes:sequencePath :sequence;
57
+ tree:view :doorStreamPage;
58
+ :lastCommittedSequence ?Bookmark;
59
+ :currentWindowFromSequence ?WindowStart;
60
+ :windowSize ?WindowSize;
61
+ :repairPolicy :preferHigherPriority.
62
+ :open :stateText ?OpenStateText;
63
+ :actionText ?OpenAction.
64
+ :closed :stateText ?ClosedStateText;
65
+ :actionText ?ClosedAction.
66
+ }.
67
+ } => {
68
+ :doorStream a ldes:EventStream;
69
+ ldes:timestampPath :observedAt;
70
+ ldes:sequencePath :sequence;
71
+ tree:view :doorStreamPage;
72
+ :lastCommittedSequence ?Bookmark;
73
+ :currentWindowFromSequence ?WindowStart;
74
+ :windowSize ?WindowSize;
75
+ :repairPolicy :preferHigherPriority.
76
+ :open :stateText ?OpenStateText;
77
+ :actionText ?OpenAction.
78
+ :closed :stateText ?ClosedStateText;
79
+ :actionText ?ClosedAction.
80
+ }.
81
+
82
+ # Each non-configuration RDF Message payload contributes one LDES member. The
83
+ # rules lift just the metadata needed by the incremental reasoner; the payloads
84
+ # themselves stay scoped to their message graphs.
85
+ {
86
+ ?Envelope eymsg:payloadGraph ?Payload.
87
+ ?Payload log:nameOf ?PayloadContext.
88
+ ?PayloadContext log:includes {
89
+ :doorStream tree:member ?Member.
90
+ ?Member a :DoorObservation;
91
+ :sequence ?Sequence;
92
+ :observedAt ?ObservedAt;
93
+ :door ?Door;
94
+ :doorState ?State;
95
+ :priority ?Priority;
96
+ :source ?Source.
97
+ }.
98
+ } => {
99
+ ?Member :ldesMember true;
100
+ :envelope ?Envelope;
101
+ :sequence ?Sequence;
102
+ :observedAt ?ObservedAt;
103
+ :door ?Door;
104
+ :doorState ?State;
105
+ :priority ?Priority;
106
+ :source ?Source.
107
+ ?Envelope :emitsLDESMember ?Member.
108
+ }.
109
+
110
+ # The LDES checkpoint lets an incremental consumer skip the large, already
111
+ # committed history.
112
+ {
113
+ :doorStream :lastCommittedSequence ?Bookmark.
114
+ ?Member :ldesMember true;
115
+ :sequence ?Sequence.
116
+ ?Sequence math:notGreaterThan ?Bookmark.
117
+ } => {
118
+ ?Member :alreadyCommitted true.
119
+ }.
120
+
121
+ {
122
+ :doorStream :lastCommittedSequence ?Bookmark.
123
+ ?Member :ldesMember true;
124
+ :sequence ?Sequence.
125
+ ?Sequence math:greaterThan ?Bookmark.
126
+ } => {
127
+ ?Member :newlyEmitted true.
128
+ }.
129
+
130
+ # The current incremental repair window is the new tail after the checkpoint.
131
+ {
132
+ :doorStream :currentWindowFromSequence ?WindowStart.
133
+ ?Member :newlyEmitted true;
134
+ :sequence ?Sequence.
135
+ ?Sequence math:notLessThan ?WindowStart.
136
+ } => {
137
+ :currentLDESWindow :contains ?Member.
138
+ ?Member :inCurrentLDESWindow true.
139
+ }.
140
+
141
+ # Raw tail materialization is inconsistent: the same door is open and closed in
142
+ # the new LDES members.
143
+ {
144
+ :currentLDESWindow :contains ?OpenMember, ?ClosedMember.
145
+ ?OpenMember :door ?Door;
146
+ :doorState :open.
147
+ ?ClosedMember :door ?Door;
148
+ :doorState :closed.
149
+ ?OpenMember log:notEqualTo ?ClosedMember.
150
+ } => {
151
+ :currentLDESWindow :rawConflict :doorOpenAndClosed;
152
+ :inconsistentDoor ?Door.
153
+ }.
154
+
155
+ # Preferred repair: keep the higher-priority assertion when the current tail
156
+ # contains conflicting LDES members for the same door.
157
+ {
158
+ :currentLDESWindow :contains ?PreferredMember, ?RejectedMember;
159
+ :rawConflict :doorOpenAndClosed.
160
+ ?PreferredMember :doorState ?PreferredState;
161
+ :priority ?PreferredPriority;
162
+ :source ?PreferredSource;
163
+ :sequence ?PreferredSequence.
164
+ ?RejectedMember :doorState ?RejectedState;
165
+ :priority ?RejectedPriority.
166
+ ?PreferredState log:notEqualTo ?RejectedState.
167
+ ?PreferredPriority math:greaterThan ?RejectedPriority.
168
+ } => {
169
+ :currentLDESWindow :preferredRepairState ?PreferredState;
170
+ :preferredEvidence ?PreferredMember;
171
+ :preferredSource ?PreferredSource;
172
+ :preferredSequence ?PreferredSequence;
173
+ :preferredPriority ?PreferredPriority;
174
+ :rejectsLowerPriority ?RejectedMember;
175
+ :repairsInconsistency :doorOpenAndClosed;
176
+ :resolvedDoorState ?PreferredState.
177
+ }.
178
+
179
+ # Materialize from the repaired state, not from the inconsistent raw window.
180
+ {
181
+ :currentLDESWindow :preferredRepairState ?State.
182
+ ?State :actionText ?ActionText.
183
+ } => {
184
+ :currentLDESWindow :materializedActionText ?ActionText.
185
+ }.
186
+
187
+ # Count the stream and the incremental tail. These counts are useful in the
188
+ # report because they show that the example input has lots of historical data,
189
+ # but the reasoning focus is the tail after the LDES bookmark.
190
+ {
191
+ ( ?Member { ?Member :ldesMember true. } ?AllMembers ) log:collectAllIn _:ldesCounts.
192
+ ?AllMembers list:length ?AllCount.
193
+ ( ?Member { ?Member :alreadyCommitted true. } ?CommittedMembers ) log:collectAllIn _:ldesCounts.
194
+ ?CommittedMembers list:length ?CommittedCount.
195
+ ( ?Member { ?Member :newlyEmitted true. } ?NewMembers ) log:collectAllIn _:ldesCounts.
196
+ ?NewMembers list:length ?NewCount.
197
+ ( ?Member { ?Member :inCurrentLDESWindow true. } ?WindowMembers ) log:collectAllIn _:ldesCounts.
198
+ ?WindowMembers list:length ?WindowCount.
199
+ } => {
200
+ :incrementalRun :totalLDESMembers ?AllCount;
201
+ :alreadyCommittedMembers ?CommittedCount;
202
+ :newlyEmittedMembers ?NewCount;
203
+ :windowMemberCount ?WindowCount.
204
+ }.
205
+
206
+ # Emit a compact human-readable result only once the parser replay, LDES
207
+ # checkpoint, count aggregation, inconsistency repair, and final materialization
208
+ # are all present.
209
+ {
210
+ ?Stream a eymsg:RDFMessageStream;
211
+ eymsg:orderedEnvelopes ?Envelopes.
212
+ ?Envelopes list:length ?EnvelopeCount.
213
+ :doorStream :lastCommittedSequence ?Bookmark;
214
+ :windowSize ?WindowSize.
215
+ :incrementalRun :totalLDESMembers ?AllCount;
216
+ :alreadyCommittedMembers ?CommittedCount;
217
+ :newlyEmittedMembers ?NewCount;
218
+ :windowMemberCount ?WindowCount.
219
+ :currentLDESWindow :rawConflict :doorOpenAndClosed;
220
+ :inconsistentDoor :doorA;
221
+ :preferredSource ?PreferredSource;
222
+ :preferredSequence ?PreferredSequence;
223
+ :preferredPriority ?PreferredPriority;
224
+ :resolvedDoorState ?State;
225
+ :materializedActionText ?ActionText.
226
+ ?State :stateText ?StateText.
227
+ ("# rdf-message-ldes-incremental\n\n## Source files\n\n- [N3 rules](../rdf-message-ldes-incremental.n3)\n- [Input RDF Message Log](../input/rdf-message-ldes-incremental.trig)\n- [Story deck](../deck/rdf-message-ldes-incremental.md)\n\n## Answer\nIncremental LDES reasoning accepted: %d RDF Message envelopes contained %d append-only LDES members. The consumer checkpoint was sequence %d, so %d committed history members were skipped and only %d newly emitted members entered the repair window. The tail window has %d members, contains a raw open/closed inconsistency for doorA, repairs it by keeping the priority-%d member at sequence %d from %s, resolves the door state to %s, and materializes the action: %s.\n\n## Explanation\nThe input is deliberately larger than the reasoning task: it serializes many LDES members as RDF Messages, but the LDES sequence bookmark tells the consumer which prefix was already materialized. Eyeling's -r mode replays the RDF Message Log into ordered eymsg: envelopes; the rules inspect each payload with log:includes, classify old versus new members from the LDES sequence path, and run the inconsistency repair only over the new tail. This mirrors an incremental streaming pipeline: append-only publication, resumable synchronization, small repair window, and monotonic output after the noisy tail is fixed." ?EnvelopeCount ?AllCount ?Bookmark ?CommittedCount ?NewCount ?WindowCount ?PreferredPriority ?PreferredSequence ?PreferredSource ?StateText ?ActionText) string:format ?Block.
228
+ } => {
229
+ :rdfMessageLDESIncrementalExample log:outputString ?Block.
230
+ :rdfMessageLDESIncrementalExample :demonstrates :RDFMessageLogReplay, :LDESMemberStream, :CheckpointedSynchronization, :IncrementalReasoning, :TailWindowRepair, :RawDoorInconsistency, :PreferredRepair.
231
+ }.
@@ -6,6 +6,9 @@
6
6
  #
7
7
  # eyeling -r examples/rdf-message-microgrid.n3 examples/input/rdf-message-microgrid.trig
8
8
  #
9
+ # See the handbook section on RDF Message Log replay under -r:
10
+ # https://eyereasoner.github.io/eyeling/HANDBOOK#rdf-message-log-replay-under--r
11
+ #
9
12
  # A clinic is running as an islanded microgrid after a storm. Several small
10
13
  # systems send RDF data: one message describes life-safety loads, another
11
14
  # describes battery and solar status, another describes flexible demand that may
@@ -6,6 +6,9 @@
6
6
  #
7
7
  # eyeling -r examples/rdf-message-window-repair.n3 examples/input/rdf-message-window-repair.trig
8
8
  #
9
+ # See the handbook section on RDF Message Log replay under -r:
10
+ # https://eyereasoner.github.io/eyeling/HANDBOOK#rdf-message-log-replay-under--r
11
+ #
9
12
  # This example is inspired by incremental, inconsistency-resilient reasoning over
10
13
  # sliding ABox streams. The input is a true RDF Message Log: each MESSAGE
11
14
  # boundary is parsed by Eyeling into an eymsg: envelope with one payload graph per
@@ -6,6 +6,9 @@
6
6
  #
7
7
  # eyeling -r examples/rdf-messages.n3 examples/input/rdf-messages.trig
8
8
  #
9
+ # See the handbook section on RDF Message Log replay under -r:
10
+ # https://eyereasoner.github.io/eyeling/HANDBOOK#rdf-message-log-replay-under--r
11
+ #
9
12
  # Motivation
10
13
  # ----------
11
14
  # The RDF Messages draft defines an RDF Message as an RDF dataset interpreted