eyeling 1.24.30 → 1.24.33

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.
@@ -1,50 +1,36 @@
1
- # ==============================
2
- # RDF Message Flow input sidecar
3
- # ==============================
1
+ # =============================
2
+ # RDF Message Flow message log
3
+ # =============================
4
4
  #
5
5
  # This file is the data half of the runnable example:
6
6
  #
7
7
  # eyeling -r examples/rdf-message-flow.n3 examples/input/rdf-message-flow.trig
8
8
  #
9
- # It is intentionally plain TriG rather than a parser-level RDF Message Log with
10
- # VERSION "1.2-messages" and MESSAGE delimiters. The RDF Messages draft says an
11
- # RDF Message is an RDF dataset interpreted atomically, that a stream is an
12
- # ordered sequence of such messages, and that messages in a stream should not be
13
- # combined by default. To demonstrate those ideas in Eyeling today, the default
14
- # graph below contains example-local envelope records (:m001 ... :m005) and each
15
- # non-empty message payload is placed in its own named graph (in:payload001 ...
16
- # in:payload005).
9
+ # It is a parser-level RDF Message Log using the RDF 1.2 Messages draft syntax:
10
+ # VERSION "1.2-messages" selects message-log parsing and MESSAGE delimiters
11
+ # separate the ordered RDF Messages. Eyeling replays this log internally by
12
+ # materializing message envelopes and one payload graph per non-empty message.
13
+ # The sidecar itself does not contain application-level envelope facts.
17
14
  #
18
- # The envelope IRIs are not identifiers for RDF Messages defined by the spec;
19
- # they are application-level records used by the flow-control rules. The named
20
- # payload graphs are the datasets/messages being interpreted atomically. The
21
- # third envelope is an empty heartbeat, which is valid because RDF Messages may
22
- # be empty. Blank node labels are kept unique because this sidecar is ordinary
23
- # TriG; a true RDF Message Log parser would reset blank-node scope per MESSAGE.
15
+ # The third message is deliberately empty. The same blank node label _:obs is
16
+ # also reused in several messages; an RDF Message Log parser scopes blank node
17
+ # identifiers to each message, so those labels do not collide.
24
18
 
25
- @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-message-flow#> .
26
- @prefix flow: <https://eyereasoner.github.io/eyeling/examples/rdf-message-flow/vocab#> .
27
- @prefix prov: <http://www.w3.org/ns/prov#> .
28
- @prefix sosa: <http://www.w3.org/ns/sosa/> .
29
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
30
- @prefix math: <http://www.w3.org/2000/10/swap/math#> .
31
- @prefix list: <http://www.w3.org/2000/10/swap/list#> .
32
- @prefix log: <http://www.w3.org/2000/10/swap/log#> .
33
- @prefix string: <http://www.w3.org/2000/10/swap/string#> .
34
- @prefix see: <https://example.org/see#> .
35
- @prefix in: <https://example.org/see/input#> .
19
+ VERSION "1.2-messages"
20
+ PREFIX : <https://eyereasoner.github.io/eyeling/examples/rdf-message-flow#>
21
+ PREFIX flow: <https://eyereasoner.github.io/eyeling/examples/rdf-message-flow/vocab#>
22
+ PREFIX prov: <http://www.w3.org/ns/prov#>
23
+ PREFIX sosa: <http://www.w3.org/ns/sosa/>
24
+ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
25
+ PREFIX see: <https://example.org/see#>
26
+ PREFIX in: <https://example.org/see/input#>
36
27
 
37
- :temperatureFlow a flow:RDFMessageStream .
38
- :temperatureFlow flow:orderedEnvelopes (:m001 :m002 :m003 :m004 :m005) .
39
- :temperatureFlow flow:envelope :m001 .
40
- :temperatureFlow flow:envelope :m002 .
41
- :temperatureFlow flow:envelope :m003 .
42
- :temperatureFlow flow:envelope :m004 .
43
- :temperatureFlow flow:envelope :m005 .
44
- :temperatureFlow :producer :thermometerA .
45
- :temperatureFlow :consumer :flowProcessor .
46
- :temperatureFlow :pipeline (:ingest :validate :interpret :route :sink) .
47
- :temperatureFlow :highThreshold 26 .
28
+ # Message 1: stream context plus first observation.
29
+ :temperatureFlow a flow:RDFMessageStream ;
30
+ :producer :thermometerA ;
31
+ :consumer :flowProcessor ;
32
+ :pipeline (:ingest :validate :interpret :route :sink) ;
33
+ :highThreshold 26 .
48
34
 
49
35
  :thermometerA a flow:StreamProducer .
50
36
  :flowProcessor a flow:StreamConsumer .
@@ -52,77 +38,42 @@
52
38
  :alertSink a flow:StreamConsumer .
53
39
  :heartbeatSink a flow:StreamConsumer .
54
40
 
55
- :m001 a flow:MessageEnvelope .
56
- :m001 :atStage :ingest .
57
- :m001 flow:offset 1 .
58
- :m001 flow:nextEnvelope :m002 .
59
- :m001 prov:generatedAtTime "2026-05-12T18:20:00Z"^^xsd:dateTime .
60
- :m001 flow:payloadKind :observation .
61
- :m001 flow:expectedResult 21 .
62
- :m001 flow:payloadGraph in:payload001 .
41
+ _:obs a sosa:Observation ;
42
+ sosa:madeBySensor :thermometerA ;
43
+ sosa:resultTime "2026-05-12T18:20:00Z"^^xsd:dateTime ;
44
+ sosa:hasSimpleResult 21 .
63
45
 
64
- :m002 a flow:MessageEnvelope .
65
- :m002 flow:offset 2 .
66
- :m002 flow:nextEnvelope :m003 .
67
- :m002 prov:generatedAtTime "2026-05-12T18:21:00Z"^^xsd:dateTime .
68
- :m002 flow:payloadKind :observation .
69
- :m002 flow:expectedResult 22 .
70
- :m002 flow:payloadGraph in:payload002 .
46
+ in:run a see:InputDataset ;
47
+ see:name "rdf_message_flow" ;
48
+ see:title "RDF Message Flow" ;
49
+ see:sourceFile "examples/rdf-message-flow.n3" ;
50
+ see:description "A true RDF 1.2 Message Log sidecar. Eyeling parses VERSION 1.2-messages and MESSAGE delimiters into replayable internal message envelopes." ;
51
+ see:compiler "Eyeling RDF Message Log input" .
71
52
 
72
- :m003 a flow:MessageEnvelope .
73
- :m003 flow:offset 3 .
74
- :m003 flow:nextEnvelope :m004 .
75
- :m003 prov:generatedAtTime "2026-05-12T18:22:00Z"^^xsd:dateTime .
76
- :m003 flow:payloadKind :heartbeat .
53
+ MESSAGE
77
54
 
78
- :m004 a flow:MessageEnvelope .
79
- :m004 flow:offset 4 .
80
- :m004 flow:nextEnvelope :m005 .
81
- :m004 prov:generatedAtTime "2026-05-12T18:23:00Z"^^xsd:dateTime .
82
- :m004 flow:payloadKind :observation .
83
- :m004 flow:expectedResult 28 .
84
- :m004 flow:payloadGraph in:payload004 .
55
+ # Message 2: normal observation.
56
+ _:obs a sosa:Observation ;
57
+ sosa:madeBySensor :thermometerA ;
58
+ sosa:resultTime "2026-05-12T18:21:00Z"^^xsd:dateTime ;
59
+ sosa:hasSimpleResult 22 .
85
60
 
86
- :m005 a flow:MessageEnvelope .
87
- :m005 flow:offset 5 .
88
- :m005 prov:generatedAtTime "2026-05-12T18:24:00Z"^^xsd:dateTime .
89
- :m005 flow:payloadKind :observation .
90
- :m005 flow:expectedResult 29 .
91
- :m005 flow:payloadGraph in:payload005 .
61
+ MESSAGE
92
62
 
93
- in:payload001 {
94
- _:m001b0 a sosa:Observation .
95
- _:m001b0 sosa:madeBySensor :thermometerA .
96
- _:m001b0 sosa:resultTime "2026-05-12T18:20:00Z"^^xsd:dateTime .
97
- _:m001b0 sosa:hasSimpleResult 21 .
98
- }
63
+ # Message 3: empty heartbeat. The next MESSAGE delimiter finalizes this empty
64
+ # message and opens message 4.
65
+ MESSAGE
99
66
 
100
- in:payload002 {
101
- _:m002b0 a sosa:Observation .
102
- _:m002b0 sosa:madeBySensor :thermometerA .
103
- _:m002b0 sosa:resultTime "2026-05-12T18:21:00Z"^^xsd:dateTime .
104
- _:m002b0 sosa:hasSimpleResult 22 .
105
- }
67
+ # Message 4: hot observation.
68
+ _:obs a sosa:Observation ;
69
+ sosa:madeBySensor :thermometerA ;
70
+ sosa:resultTime "2026-05-12T18:23:00Z"^^xsd:dateTime ;
71
+ sosa:hasSimpleResult 28 .
106
72
 
107
- in:payload004 {
108
- _:m004b0 a sosa:Observation .
109
- _:m004b0 sosa:madeBySensor :thermometerA .
110
- _:m004b0 sosa:resultTime "2026-05-12T18:23:00Z"^^xsd:dateTime .
111
- _:m004b0 sosa:hasSimpleResult 28 .
112
- }
73
+ MESSAGE
113
74
 
114
- in:payload005 {
115
- _:m005b0 a sosa:Observation .
116
- _:m005b0 sosa:madeBySensor :thermometerA .
117
- _:m005b0 sosa:resultTime "2026-05-12T18:24:00Z"^^xsd:dateTime .
118
- _:m005b0 sosa:hasSimpleResult 29 .
119
- }
120
-
121
- in:metadata {
122
- in:run a see:InputDataset .
123
- in:run see:name "rdf_message_flow" .
124
- in:run see:title "RDF Message Flow" .
125
- in:run see:sourceFile "examples/rdf-message-flow.n3" .
126
- in:run see:description "A single Eyeling example split across an N3 rule file and a TriG input sidecar. It models an ordered RDF Message Stream using application-level envelopes and named payload graphs so that each payload can be interpreted atomically without merging all message contents into one graph." .
127
- in:run see:compiler "Eyeling RDF/TriG input sidecar" .
128
- }
75
+ # Message 5: hot observation. EOF finalizes the message.
76
+ _:obs a sosa:Observation ;
77
+ sosa:madeBySensor :thermometerA ;
78
+ sosa:resultTime "2026-05-12T18:24:00Z"^^xsd:dateTime ;
79
+ sosa:hasSimpleResult 29 .
@@ -1,89 +1,56 @@
1
- # ===================================
2
- # RDF Message Microgrid input sidecar
3
- # ===================================
1
+ # ==================================
2
+ # RDF Message Microgrid message log
3
+ # ==================================
4
4
  #
5
5
  # This file is the data half of the runnable example:
6
6
  #
7
7
  # eyeling -r examples/rdf-message-microgrid.n3 examples/input/rdf-message-microgrid.trig
8
8
  #
9
9
  # The scene is a clinic operating as an islanded microgrid after a storm. The
10
- # data arrives as a replayable stream of atomic messages: life-safety loads,
11
- # power status, flexible demand, and an empty heartbeat. The default graph holds
12
- # application-local envelope facts, while each non-empty message payload is kept
13
- # in a named graph.
14
- #
15
- # The envelope IRIs are not RDF Message identifiers defined by the specification;
16
- # they are local replay records for this example. The named graphs are the
17
- # datasets/messages interpreted atomically by the N3 rules.
18
-
19
- @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-message-microgrid#> .
20
- @prefix rmsg: <https://eyereasoner.github.io/eyeling/examples/rdf-message-microgrid/vocab#> .
21
- @prefix prov: <http://www.w3.org/ns/prov#> .
22
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
23
- @prefix see: <https://example.org/see#> .
24
- @prefix in: <https://example.org/see/input#> .
10
+ # data arrives as a true RDF Message Log: life-safety loads, power status,
11
+ # flexible demand, and an empty heartbeat. Eyeling parses the MESSAGE boundaries
12
+ # internally and exposes the replay to the N3 rules as eymsg: envelopes.
25
13
 
26
- :stormClinicLog a rmsg:MessageLog .
27
- :stormClinicLog rmsg:orderedMessages (:m001 :m002 :m003 :m004) .
28
- :stormClinicLog rmsg:message :m001 .
29
- :stormClinicLog rmsg:message :m002 .
30
- :stormClinicLog rmsg:message :m003 .
31
- :stormClinicLog rmsg:message :m004 .
32
- :stormClinicLog rmsg:retentionPolicy "storm replay archive" .
14
+ VERSION "1.2-messages"
15
+ PREFIX : <https://eyereasoner.github.io/eyeling/examples/rdf-message-microgrid#>
16
+ PREFIX see: <https://example.org/see#>
17
+ PREFIX in: <https://example.org/see/input#>
33
18
 
34
- :m001 a rmsg:MessageEnvelope .
35
- :m001 rmsg:offset 1 .
36
- :m001 prov:generatedAtTime "2026-05-15T19:00:00Z"^^xsd:dateTime .
37
- :m001 rmsg:payloadKind :lifeSafetyLoads .
38
- :m001 rmsg:payloadGraph in:lifeSafetyPayload .
19
+ # Message 1: life-safety loads plus example metadata.
20
+ :oxygenConcentrator a :LifeSafetyLoad ;
21
+ :requiresWatts 500 ;
22
+ :serves :respiratoryCareRoom .
39
23
 
40
- :m002 a rmsg:MessageEnvelope .
41
- :m002 rmsg:offset 2 .
42
- :m002 prov:generatedAtTime "2026-05-15T19:01:00Z"^^xsd:dateTime .
43
- :m002 rmsg:payloadKind :powerStatus .
44
- :m002 rmsg:payloadGraph in:powerPayload .
24
+ :vaccineFridge a :ColdChainLoad ;
25
+ :requiresWatts 120 ;
26
+ :serves :vaccineColdChain .
45
27
 
46
- :m003 a rmsg:MessageEnvelope .
47
- :m003 rmsg:offset 3 .
48
- :m003 prov:generatedAtTime "2026-05-15T19:02:00Z"^^xsd:dateTime .
49
- :m003 rmsg:payloadKind :flexibleDemand .
50
- :m003 rmsg:payloadGraph in:flexPayload .
28
+ in:run a see:InputDataset ;
29
+ see:name "rdf_message_microgrid" ;
30
+ see:title "RDF Message Microgrid" ;
31
+ see:sourceFile "examples/rdf-message-microgrid.n3" ;
32
+ see:description "A true RDF 1.2 Message Log for a storm clinic microgrid. Eyeling parses MESSAGE delimiters into replayable internal message envelopes for bounded, explainable load-shedding." ;
33
+ see:compiler "Eyeling RDF Message Log input" .
51
34
 
52
- :m004 a rmsg:MessageEnvelope .
53
- :m004 rmsg:offset 4 .
54
- :m004 prov:generatedAtTime "2026-05-15T19:03:00Z"^^xsd:dateTime .
55
- :m004 rmsg:payloadKind :heartbeat .
35
+ MESSAGE
56
36
 
57
- in:lifeSafetyPayload {
58
- :oxygenConcentrator a :LifeSafetyLoad .
59
- :oxygenConcentrator :requiresWatts 500 .
60
- :oxygenConcentrator :serves :respiratoryCareRoom .
37
+ # Message 2: current power status.
38
+ :batteryBank a :PowerReserve ;
39
+ :availableWatts 650 ;
40
+ :state :islanded .
61
41
 
62
- :vaccineFridge a :ColdChainLoad .
63
- :vaccineFridge :requiresWatts 120 .
64
- :vaccineFridge :serves :vaccineColdChain .
65
- }
42
+ :solarForecast a :NearTermForecast ;
43
+ :expectedWatts 150 .
66
44
 
67
- in:powerPayload {
68
- :batteryBank a :PowerReserve .
69
- :batteryBank :availableWatts 650 .
70
- :batteryBank :state :islanded .
45
+ MESSAGE
71
46
 
72
- :solarForecast a :NearTermForecast .
73
- :solarForecast :expectedWatts 150 .
74
- }
47
+ # Message 3: flexible demand that can safely be shed.
48
+ :evChargers a :FlexibleLoad ;
49
+ :shedWatts 600 ;
50
+ :serves :staffVehicles .
75
51
 
76
- in:flexPayload {
77
- :evChargers a :FlexibleLoad .
78
- :evChargers :shedWatts 600 .
79
- :evChargers :serves :staffVehicles .
80
- }
52
+ MESSAGE
81
53
 
82
- in:metadata {
83
- in:run a see:InputDataset .
84
- in:run see:name "rdf_message_microgrid" .
85
- in:run see:title "RDF Message Microgrid" .
86
- in:run see:sourceFile "examples/rdf-message-microgrid.n3" .
87
- in:run see:description "A storm clinic microgrid example using application-local RDF Message envelopes and named payload graphs so a reasoner can make a bounded, explainable load-shedding decision." .
88
- in:run see:compiler "Eyeling RDF/TriG input sidecar" .
89
- }
54
+ # Message 4: empty heartbeat. The next MESSAGE delimiter finalizes this empty
55
+ # message and leaves no trailing payload.
56
+ MESSAGE
@@ -1,90 +1,47 @@
1
- # ==========================
2
- # RDF Messages input sidecar
3
- # ==========================
1
+ # ===============================
2
+ # RDF Messages parser-level input
3
+ # ===============================
4
4
  #
5
5
  # This file is the data half of the runnable example:
6
6
  #
7
7
  # eyeling -r examples/rdf-messages.n3 examples/input/rdf-messages.trig
8
8
  #
9
- # It is intentionally plain TriG rather than a parser-level RDF Message Log with
10
- # VERSION "1.2-messages" and MESSAGE delimiters. The RDF Messages draft says an
11
- # RDF Message is an RDF dataset interpreted atomically, that a message stream is
12
- # an ordered sequence of such messages, that messages are not combined by
13
- # default, and that blank-node labels are scoped to the message.
9
+ # It is a true RDF Message Log. VERSION "1.2-messages" tells Eyeling to parse
10
+ # MESSAGE delimiters as message boundaries before ordinary N3 reasoning starts.
11
+ # Eyeling then materializes an internal eymsg: replay view with ordered envelopes
12
+ # and one payload graph per non-empty message.
14
13
  #
15
- # To demonstrate those ideas in Eyeling today, the default graph contains
16
- # application-local envelope records (:m001 ... :m003) plus replay order and
17
- # offsets. Each non-empty message payload is placed in its own named graph
18
- # (in:payload001 and in:payload003). The second envelope is an empty heartbeat,
19
- # which is valid because RDF Messages may be empty.
20
- #
21
- # The envelope IRIs are not message identifiers defined by the spec; they are
22
- # application-level records used by the rules. The named payload graphs are the
23
- # datasets/messages being interpreted atomically. The rmsg:localBlankLabel values
24
- # show that the same source-local label "_:b0" can recur in different messages;
25
- # the concrete TriG blank nodes themselves are unique because this sidecar is
26
- # ordinary TriG rather than an RDF Message Log parser resetting blank-node scope.
27
-
28
- @prefix : <https://eyereasoner.github.io/eyeling/examples/rdf-messages#> .
29
- @prefix rmsg: <https://eyereasoner.github.io/eyeling/examples/rdf-messages/vocab#> .
30
- @prefix prov: <http://www.w3.org/ns/prov#> .
31
- @prefix sosa: <http://www.w3.org/ns/sosa/> .
32
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
33
- @prefix math: <http://www.w3.org/2000/10/swap/math#> .
34
- @prefix list: <http://www.w3.org/2000/10/swap/list#> .
35
- @prefix log: <http://www.w3.org/2000/10/swap/log#> .
36
- @prefix string: <http://www.w3.org/2000/10/swap/string#> .
37
- @prefix see: <https://example.org/see#> .
38
- @prefix in: <https://example.org/see/input#> .
39
-
40
- :temperatureLog a rmsg:MessageLog .
41
- :temperatureLog rmsg:orderedMessages (:m001 :m002 :m003) .
42
- :temperatureLog rmsg:message :m001 .
43
- :temperatureLog rmsg:message :m002 .
44
- :temperatureLog rmsg:message :m003 .
45
- :temperatureLog rmsg:profile :generatedAtTimeProfile .
46
- :temperatureLog rmsg:retentionPolicy "replayable archive" .
47
-
48
- :m001 a rmsg:MessageEnvelope .
49
- :m001 rmsg:offset 1 .
50
- :m001 prov:generatedAtTime "2026-05-12T18:20:00Z"^^xsd:dateTime .
51
- :m001 rmsg:payloadKind :observation .
52
- :m001 rmsg:localBlankLabel "_:b0" .
53
- :m001 rmsg:expectedResult 22 .
54
- :m001 rmsg:payloadGraph in:payload001 .
55
-
56
- :m002 a rmsg:MessageEnvelope .
57
- :m002 rmsg:offset 2 .
58
- :m002 prov:generatedAtTime "2026-05-12T18:22:00Z"^^xsd:dateTime .
59
- :m002 rmsg:payloadKind :heartbeat .
60
-
61
- :m003 a rmsg:MessageEnvelope .
62
- :m003 rmsg:offset 3 .
63
- :m003 prov:generatedAtTime "2026-05-12T18:25:00Z"^^xsd:dateTime .
64
- :m003 rmsg:payloadKind :observation .
65
- :m003 rmsg:localBlankLabel "_:b0" .
66
- :m003 rmsg:expectedResult 23 .
67
- :m003 rmsg:payloadGraph in:payload003 .
68
-
69
- in:payload001 {
70
- _:m001b0 a sosa:Observation .
71
- _:m001b0 sosa:madeBySensor :thermometerA .
72
- _:m001b0 sosa:resultTime "2026-05-12T18:20:00Z"^^xsd:dateTime .
73
- _:m001b0 sosa:hasSimpleResult 22 .
74
- }
75
-
76
- in:payload003 {
77
- _:m003b0 a sosa:Observation .
78
- _:m003b0 sosa:madeBySensor :thermometerA .
79
- _:m003b0 sosa:resultTime "2026-05-12T18:25:00Z"^^xsd:dateTime .
80
- _:m003b0 sosa:hasSimpleResult 23 .
81
- }
82
-
83
- in:metadata {
84
- in:run a see:InputDataset .
85
- in:run see:name "rdf_messages" .
86
- in:run see:title "RDF Messages" .
87
- in:run see:sourceFile "examples/rdf-messages.n3" .
88
- in:run see:description "A single Eyeling example split across an N3 rule file and a TriG input sidecar. It models a replayable RDF Message Log with application-level envelopes and named payload graphs so that each payload can be interpreted atomically without merging all message contents into one graph." .
89
- in:run see:compiler "Eyeling RDF/TriG input sidecar" .
90
- }
14
+ # The second message is deliberately empty. The first and third messages both use
15
+ # the source-local blank-node label _:b0. Because blank-node labels are scoped to
16
+ # each RDF Message, Eyeling rewrites them into distinct internal blank nodes.
17
+
18
+ VERSION "1.2-messages"
19
+ PREFIX : <https://eyereasoner.github.io/eyeling/examples/rdf-messages#>
20
+ PREFIX sosa: <http://www.w3.org/ns/sosa/>
21
+ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
22
+ PREFIX see: <https://example.org/see#>
23
+ PREFIX in: <https://example.org/see/input#>
24
+
25
+ # Message 1: first temperature observation plus example metadata.
26
+ _:b0 a sosa:Observation ;
27
+ sosa:madeBySensor :thermometerA ;
28
+ sosa:resultTime "2026-05-12T18:20:00Z"^^xsd:dateTime ;
29
+ sosa:hasSimpleResult 22 .
30
+
31
+ in:run a see:InputDataset ;
32
+ see:name "rdf_messages" ;
33
+ see:title "RDF Messages" ;
34
+ see:sourceFile "examples/rdf-messages.n3" ;
35
+ see:description "A true RDF 1.2 Message Log. Eyeling parses VERSION 1.2-messages and MESSAGE delimiters into replayable internal message envelopes." ;
36
+ see:compiler "Eyeling RDF Message Log input" .
37
+
38
+ MESSAGE
39
+
40
+ # Message 2: empty heartbeat.
41
+ MESSAGE
42
+
43
+ # Message 3: second observation. The _:b0 label is intentionally reused here.
44
+ _:b0 a sosa:Observation ;
45
+ sosa:madeBySensor :thermometerA ;
46
+ sosa:resultTime "2026-05-12T18:25:00Z"^^xsd:dateTime ;
47
+ sosa:hasSimpleResult 23 .
@@ -3,10 +3,10 @@
3
3
  ## Source files
4
4
 
5
5
  - [N3 rules](../rdf-message-flow.n3)
6
- - [Input TriG](../input/rdf-message-flow.trig)
6
+ - [Input RDF Message Log](../input/rdf-message-flow.trig)
7
7
 
8
8
  ## Answer
9
- Continuous RDF Message flow accepted: 5 ordered message envelopes moved through the ingest → validate → interpret → route → sink pipeline. The threshold was 26, so results 21 and 22 were archived, the heartbeat kept the stream alive, and results 28 and 29 were emitted as alerts.
9
+ Continuous RDF Message flow accepted: 5 ordered parser-replayed message envelopes moved through the ingest → validate → interpret → route → sink pipeline. The threshold was 26, so results 21 and 22 were archived, the empty heartbeat kept the stream alive, and results 28 and 29 were emitted as alerts.
10
10
 
11
11
  ## Explanation
12
- The input is a single runnable example split across an N3 rule file and a TriG sidecar. The TriG file uses example-local envelope facts for stream order and processing state, while each named payload graph is treated as an atomic RDF Message dataset. Only :m001 starts at ingress; each envelope must reach :sink before the continuous-flow rule releases its flow:nextEnvelope. Observation payloads are inspected with log:includes inside their own payload formula, and the empty heartbeat advances without a payload graph. This keeps message boundaries visible to the reasoner instead of merging all payload triples into one global graph.
12
+ The input sidecar is now a true RDF Message Log using VERSION \"1.2-messages\" and MESSAGE delimiters. Eyeling parses the log internally into an eymsg: replay view with ordered envelopes, offsets, next-envelope links, and one payload graph per non-empty message. Only the first replayed envelope starts at ingress; each envelope must reach :sink before the continuous-flow rule releases its eymsg:nextEnvelope. Observation payloads are inspected with log:includes inside their own message formula, and the delimiter-only third message is replayed as an empty heartbeat. This keeps message boundaries in the parser/runtime instead of modeling them by hand in the TriG sidecar.
@@ -3,12 +3,10 @@
3
3
  ## Source files
4
4
 
5
5
  - [N3 rules](../rdf-message-microgrid.n3)
6
- - [Input TriG](../input/rdf-message-microgrid.trig)
6
+ - [Input RDF Message Log](../input/rdf-message-microgrid.trig)
7
7
 
8
8
  ## Answer
9
- Storm clinic microgrid accepted: 4 RDF Message envelopes were replayed atomically. Critical care needs 620 W, current battery plus solar gives 800 W, and deferring the EV chargers frees 600 W, so the protected budget is 1400 W. The reasoned action is to keep the oxygen concentrator and vaccine fridge online, while deferring EV charging.
9
+ Storm clinic microgrid accepted: 4 parser-replayed RDF Messages were processed atomically. Critical care needs 620 W, current battery plus solar gives 800 W, and deferring the EV chargers frees 600 W, so the protected budget is 1400 W. The reasoned action is to keep the oxygen concentrator and vaccine fridge online, while deferring EV charging.
10
10
 
11
- ## Why this is an RDF Messages example
12
- The input is a single runnable example split across an N3 rule file and a TriG sidecar. The default graph records stream order, offsets, and envelope metadata. Each non-empty named graph is treated as an atomic message payload, and the fourth message is an empty heartbeat. The rules inspect each payload with log:includes inside its own formula, then combine only the derived conclusions needed for the microgrid decision. This keeps the explanation tied to message boundaries instead of silently flattening the stream into one global graph.
13
-
14
- This is intentionally not a parser-level VERSION \"1.2-messages\" / MESSAGE delimiter test. It is a reasoning example over an already-materialized sidecar representation of a message log.
11
+ ## Why this is an RDF Message Log example
12
+ The input now uses VERSION \"1.2-messages\" and MESSAGE delimiters. Eyeling parses those boundaries internally into an eymsg: replay view, so the rules do not need hand-written application envelopes. Each non-empty message is inspected with log:includes inside its own payload formula, and the final delimiter-only message is replayed as an empty heartbeat. The decision combines only the derived conclusions needed for load shedding while keeping the explanation tied to explicit message boundaries.
@@ -3,12 +3,10 @@
3
3
  ## Source files
4
4
 
5
5
  - [N3 rules](../rdf-messages.n3)
6
- - [Input TriG](../input/rdf-messages.trig)
6
+ - [Input RDF Message Log](../input/rdf-messages.trig)
7
7
 
8
8
  ## Answer
9
- RDF Message replay archive accepted: 3 explicit message boundaries are preserved. Message :m002 is an empty heartbeat, and the local blank-node label _:b0 is safely reused in separate message envelopes.
9
+ RDF Message Log accepted: 3 parser-replayed message boundaries are preserved. The middle message is an empty heartbeat, and the same source-local blank-node label is safely reused because Eyeling scopes blank nodes per message.
10
10
 
11
11
  ## Explanation
12
- The input is a single runnable example split across an N3 rule file and a TriG sidecar. The TriG file uses application-local envelope facts for stream order and replay metadata, while each non-empty named payload graph is treated as an atomic RDF Message dataset. Payloads are inspected with log:includes inside their own formulas, so the observation data stays inside the message boundary instead of being treated as one global graph. The two temperature results, 22 and 23, are different observations from the same stream but are contextualized by their message boundaries.
13
-
14
- This is intentionally not a parser-level VERSION \"1.2-messages\" / MESSAGE delimiter test. It is a reasoning example over an already-materialized sidecar representation of a message log.
12
+ The input now uses VERSION \"1.2-messages\" and MESSAGE delimiters instead of hand-written application envelope facts. Eyeling parses the log internally into an eymsg: replay view with ordered envelopes and one payload graph per non-empty message. The rules inspect each payload with log:includes inside its own message formula, so the observation data stays inside the message boundary instead of being treated as one global graph. The two temperature results, 22 and 23, are different observations from the same stream and remain contextualized by their message boundaries.