eyeprolog 0.5.7 → 0.5.9

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 (178) hide show
  1. package/README.md +8 -0
  2. package/examples/age.pl +3 -3
  3. package/examples/aliases-and-namespaces.pl +1 -1
  4. package/examples/book/README.md +1 -1
  5. package/examples/book/chapter-09/02-normalized.pl +1 -1
  6. package/examples/book/chapter-33/02-source_role.pl +2 -2
  7. package/examples/delfour.pl +2 -2
  8. package/examples/dpv-odrl-purpose-mapping.pl +28 -28
  9. package/examples/flandor.pl +2 -2
  10. package/examples/goldbach.pl +3 -2
  11. package/examples/input/dpv-odrl-purpose-mapping-rules.pl +3 -3
  12. package/examples/input/odrl-dpv-fpv-trust-flow-rules.pl +2 -2
  13. package/examples/input/odrl-dpv-healthcare-risk-ranked-rules.pl +2 -2
  14. package/examples/input/odrl-dpv-risk-ranked-rules.pl +2 -2
  15. package/examples/input/odrl-policy-advanced-rules.pl +26 -26
  16. package/examples/input/odrl-policy-rules.pl +13 -13
  17. package/examples/input/rdf12-annotated-claims-rules.pl +6 -6
  18. package/examples/input/rdf12-annotation-rules.pl +3 -3
  19. package/examples/input/rdf12-directional-language-rules.pl +4 -2
  20. package/examples/input/rdf12-nested-triple-term-rules.pl +5 -4
  21. package/examples/input/rdf12-trig-graph-join-rules.pl +6 -5
  22. package/examples/input/rdf12-trig-named-graph-rules.pl +6 -5
  23. package/examples/input/rdf12-trig-triple-term-rules.pl +4 -3
  24. package/examples/input/rdf12-triple-term-rules.pl +4 -3
  25. package/examples/observability-log-correlation.pl +7 -7
  26. package/examples/odrl-dpv-fpv-trust-flow.pl +31 -31
  27. package/examples/odrl-dpv-healthcare-risk-ranked.pl +37 -37
  28. package/examples/odrl-dpv-risk-ranked.pl +49 -49
  29. package/examples/odrl-policy-advanced-from-turtle.pl +44 -44
  30. package/examples/odrl-policy-from-turtle.pl +20 -20
  31. package/examples/output/age.pl +1 -1
  32. package/examples/output/complex.pl +0 -5
  33. package/examples/output/enigma1225.pl +1 -1
  34. package/examples/output/goldbach.pl +0 -10
  35. package/examples/output/observability-log-correlation.pl +28 -28
  36. package/examples/output/odrl-dpv-fpv-trust-flow.pl +1 -1
  37. package/examples/output/path-discovery.pl +3 -3
  38. package/examples/output/rdf12-annotated-claims.pl +1 -1
  39. package/examples/output/rdf12-annotation.pl +1 -1
  40. package/examples/output/rdf12-directional-language.pl +2 -2
  41. package/examples/output/rdf12-nested-triple-term.pl +1 -1
  42. package/examples/output/rdf12-trig-graph-join.pl +1 -1
  43. package/examples/output/rdf12-trig-named-graph.pl +3 -3
  44. package/examples/output/rdf12-trig-triple-term.pl +1 -1
  45. package/examples/output/rdf12-triple-term.pl +1 -1
  46. package/examples/output/reusable-builtins.pl +3 -3
  47. package/examples/output/socket-age.pl +1 -1
  48. package/examples/output/term-tools.pl +1 -1
  49. package/examples/path-discovery.pl +7700 -7700
  50. package/examples/proof/age.pl +18 -18
  51. package/examples/proof/aliases-and-namespaces.pl +2 -2
  52. package/examples/proof/chart-parser.pl +4 -4
  53. package/examples/proof/d3-group.pl +3 -3
  54. package/examples/proof/data-negotiation.pl +3 -3
  55. package/examples/proof/dog.pl +1 -1
  56. package/examples/proof/hanoi.pl +7 -7
  57. package/examples/proof/iso-dynamic-database.pl +1 -1
  58. package/examples/proof/linear-logic-resources.pl +8 -8
  59. package/examples/proof/list-collection.pl +5 -49
  60. package/examples/proof/odrl-policy-from-turtle.pl +8 -8
  61. package/examples/proof/prime-range.pl +2 -2
  62. package/examples/proof/rdf12-annotation.pl +8 -8
  63. package/examples/proof/rdf12-directional-language.pl +10 -10
  64. package/examples/proof/rdf12-nested-triple-term.pl +5 -5
  65. package/examples/proof/rdf12-trig-graph-join.pl +6 -6
  66. package/examples/proof/rdf12-trig-named-graph.pl +16 -16
  67. package/examples/proof/rdf12-trig-triple-term.pl +5 -5
  68. package/examples/proof/rdf12-triple-term.pl +5 -5
  69. package/examples/proof/reusable-builtins.pl +32 -32
  70. package/examples/proof/socket-age.pl +10 -10
  71. package/examples/proof/term-tools.pl +6 -6
  72. package/examples/proof/weighted-interval-scheduling.pl +1 -1
  73. package/examples/rdf12-annotated-claims.pl +16 -16
  74. package/examples/rdf12-annotation.pl +7 -7
  75. package/examples/rdf12-directional-language.pl +7 -6
  76. package/examples/rdf12-nested-triple-term.pl +7 -7
  77. package/examples/rdf12-trig-graph-join.pl +9 -9
  78. package/examples/rdf12-trig-named-graph.pl +9 -9
  79. package/examples/rdf12-trig-triple-term.pl +6 -6
  80. package/examples/rdf12-triple-term.pl +6 -6
  81. package/examples/reusable-builtins.pl +5 -5
  82. package/examples/sieve.pl +2 -2
  83. package/examples/socket-age.pl +3 -3
  84. package/index.d.ts +8 -0
  85. package/package.json +1 -1
  86. package/src/explain.js +32 -0
  87. package/src/eyeprolog-library.pl +731 -0
  88. package/src/index.js +4 -0
  89. package/src/library-source.js +18 -0
  90. package/src/library.js +127 -981
  91. package/src/program.js +8 -1
  92. package/src/solver.js +2 -2
  93. package/test/conformance/cases/arithmetic/061_date_difference.pl +2 -2
  94. package/test/conformance/cases/arithmetic/extra_difference_leap_day.pl +1 -1
  95. package/test/conformance/cases/arithmetic/extra_difference_same_day.pl +1 -1
  96. package/test/conformance/cases/builtins/037_matching_and_comparison.pl +2 -2
  97. package/test/conformance/cases/builtins/076_composed_reusable_builtins.pl +5 -5
  98. package/test/conformance/cases/builtins/100_reusable_builtin_workflow.pl +4 -4
  99. package/test/conformance/cases/builtins/extra_difference_end_before_start_fails.pl +1 -1
  100. package/test/conformance/cases/builtins/extra_difference_invalid_date_fails.pl +1 -1
  101. package/test/conformance/cases/strings/030_strings_and_atoms.pl +2 -2
  102. package/test/conformance/cases/strings/055_string_matching_filters.pl +4 -4
  103. package/test/conformance/cases/strings/056_string_concat_modes.pl +5 -5
  104. package/test/conformance/cases/strings/064_reusable_string_builtins.pl +8 -8
  105. package/test/conformance/cases/strings/070_matches_named_captures.pl +2 -2
  106. package/test/conformance/cases/strings/071_string_edges.pl +8 -8
  107. package/test/conformance/cases/strings/072_string_conversions.pl +5 -5
  108. package/test/conformance/cases/strings/089_string_split_join_pipeline.pl +5 -5
  109. package/test/conformance/cases/strings/090_string_substring_replace_edges.pl +7 -7
  110. package/test/conformance/cases/strings/091_string_case_and_trim.pl +5 -5
  111. package/test/conformance/cases/strings/092_scalar_string_conversions.pl +3 -3
  112. package/test/conformance/cases/strings/093_regex_named_captures_context.pl +6 -6
  113. package/test/conformance/cases/strings/atom_string_from_string.pl +1 -1
  114. package/test/conformance/cases/strings/casefold_atoms.pl +1 -1
  115. package/test/conformance/cases/strings/contains_empty_needle.pl +1 -1
  116. package/test/conformance/cases/strings/extra_join_empty_list.pl +1 -1
  117. package/test/conformance/cases/strings/extra_join_iri_and_atom.pl +1 -1
  118. package/test/conformance/cases/strings/extra_matches_invalid_pattern_fails.pl +1 -1
  119. package/test/conformance/cases/strings/extra_named_regex_optional_missing.pl +1 -1
  120. package/test/conformance/cases/strings/extra_replace_multiple.pl +1 -1
  121. package/test/conformance/cases/strings/extra_split_empty_separator.pl +1 -1
  122. package/test/conformance/cases/strings/extra_substring_last_char.pl +1 -1
  123. package/test/conformance/cases/strings/extra_term_string_iri_list.pl +1 -1
  124. package/test/conformance/cases/strings/extra_uppercase_mixed_string.pl +1 -1
  125. package/test/conformance/cases/strings/join_mixed_scalars.pl +1 -1
  126. package/test/conformance/cases/strings/matches_simple_alternation.pl +1 -1
  127. package/test/conformance/cases/strings/named_regex_two_groups.pl +1 -1
  128. package/test/conformance/cases/strings/not_matches_simple_pattern.pl +1 -1
  129. package/test/conformance/cases/strings/number_string_from_string.pl +1 -1
  130. package/test/conformance/cases/strings/number_string_rejects_non_numeric.pl +1 -1
  131. package/test/conformance/cases/strings/replace_empty_search_no_change.pl +1 -1
  132. package/test/conformance/cases/strings/split_without_separator_match.pl +1 -1
  133. package/test/conformance/cases/strings/substring_out_of_range_fails.pl +1 -1
  134. package/test/conformance/cases/strings/substring_zero_count.pl +1 -1
  135. package/test/conformance/cases/strings/trim_tabs_and_spaces.pl +2 -2
  136. package/test/conformance/expected/arithmetic/061_date_difference.pl +2 -2
  137. package/test/conformance/expected/arithmetic/extra_difference_leap_day.pl +1 -1
  138. package/test/conformance/expected/arithmetic/extra_difference_same_day.pl +1 -1
  139. package/test/conformance/expected/builtins/076_composed_reusable_builtins.pl +5 -5
  140. package/test/conformance/expected/builtins/100_reusable_builtin_workflow.pl +2 -2
  141. package/test/conformance/expected/builtins/atom_string_iri_atom.pl +1 -1
  142. package/test/conformance/expected/strings/030_strings_and_atoms.pl +1 -1
  143. package/test/conformance/expected/strings/056_string_concat_modes.pl +8 -8
  144. package/test/conformance/expected/strings/064_reusable_string_builtins.pl +9 -9
  145. package/test/conformance/expected/strings/070_matches_named_captures.pl +1 -1
  146. package/test/conformance/expected/strings/071_string_edges.pl +8 -8
  147. package/test/conformance/expected/strings/072_string_conversions.pl +3 -3
  148. package/test/conformance/expected/strings/089_string_split_join_pipeline.pl +4 -4
  149. package/test/conformance/expected/strings/090_string_substring_replace_edges.pl +6 -6
  150. package/test/conformance/expected/strings/091_string_case_and_trim.pl +5 -5
  151. package/test/conformance/expected/strings/092_scalar_string_conversions.pl +4 -4
  152. package/test/conformance/expected/strings/093_regex_named_captures_context.pl +3 -3
  153. package/test/conformance/expected/strings/casefold_atoms.pl +2 -2
  154. package/test/conformance/expected/strings/extra_join_empty_list.pl +1 -1
  155. package/test/conformance/expected/strings/extra_join_iri_and_atom.pl +1 -1
  156. package/test/conformance/expected/strings/extra_lowercase_iri_atom.pl +1 -1
  157. package/test/conformance/expected/strings/extra_named_regex_optional_missing.pl +1 -1
  158. package/test/conformance/expected/strings/extra_replace_multiple.pl +1 -1
  159. package/test/conformance/expected/strings/extra_split_empty_separator.pl +1 -1
  160. package/test/conformance/expected/strings/extra_substring_last_char.pl +1 -1
  161. package/test/conformance/expected/strings/extra_term_string_iri_list.pl +1 -1
  162. package/test/conformance/expected/strings/extra_uppercase_mixed_string.pl +1 -1
  163. package/test/conformance/expected/strings/join_mixed_scalars.pl +1 -1
  164. package/test/conformance/expected/strings/named_regex_two_groups.pl +1 -1
  165. package/test/conformance/expected/strings/replace_empty_search_no_change.pl +1 -1
  166. package/test/conformance/expected/strings/split_without_separator_match.pl +1 -1
  167. package/test/conformance/expected/strings/substring_zero_count.pl +1 -1
  168. package/test/conformance/expected/strings/term_string_nested_term.pl +1 -1
  169. package/test/conformance/expected/strings/trim_tabs_and_spaces.pl +1 -1
  170. package/test/conformance/expected/terms/065_reusable_term_control_builtins.pl +1 -1
  171. package/test/conformance/expected/terms/term_string_readback_iri_list.pl +1 -1
  172. package/test/conformance/expected-proofs/proofs/extra_aggregate_min.pl +2 -2
  173. package/test/conformance/expected-proofs/proofs/extra_once_member.pl +1 -1
  174. package/test/conformance/expected-proofs/proofs/list_builtin.pl +1 -1
  175. package/test/run-rdf-tools.mjs +1 -1
  176. package/test/run-regression.mjs +50 -21
  177. package/the-art-of-eyeprolog.md +85 -66
  178. package/tools/rdf-codec.mjs +1 -1
package/README.md CHANGED
@@ -30,6 +30,14 @@ eyeprolog --goal 'type(socrates, mortal)' examples/socrates.pl
30
30
 
31
31
  Programs may declare their default queries with `%% goal:` comments.
32
32
 
33
+ ## Portable library
34
+
35
+ EyeProlog adds 50 public library predicates to its 115-predicate ISO profile.
36
+ **48 of the 50 are ordinary Prolog clauses** in `src/eyeprolog-library.pl` and
37
+ are autoloaded in Node and the browser. Only `uuid/1` and `local_time/1` require
38
+ host support. Portable text predicates use ISO atoms or character lists; the
39
+ RDF tools emit lexical values as ISO atoms as well.
40
+
33
41
  ## RDF 1.2
34
42
 
35
43
  ```sh
package/examples/age.pl CHANGED
@@ -13,8 +13,8 @@
13
13
  %% goal: holds_result(X0, X1)
14
14
 
15
15
 
16
- birthDay(patH, "1944-08-21").
17
- duration(check, "P80Y").
16
+ birthDay(patH, '1944-08-21').
17
+ duration(check, 'P80Y').
18
18
 
19
19
  % A person is above a duration if the local date minus the birthday is greater
20
20
  % than that duration.
@@ -27,4 +27,4 @@ ageAbove(S, A) :-
27
27
 
28
28
  % Test mirroring the Eyeling example.
29
29
  holds_result(test, true) :-
30
- ageAbove(S, "P80Y").
30
+ ageAbove(S, 'P80Y').
@@ -16,7 +16,7 @@
16
16
  % application vocabulary is modeled with ordinary facts and rules.
17
17
  value(nativeMath, X) :- (X is 0.125 + 0.875).
18
18
  ok(nativeCompare, true) :- (2 < 3).
19
- ok(nativeString, true) :- matches("scoped retail insight", "retail|medical").
19
+ ok(nativeString, true) :- matches('scoped retail insight', 'retail|medical').
20
20
  tail(nativeList, Tail) :- [_head|Tail] = [a, b, c].
21
21
 
22
22
  % These names are just user data; eyeprolog does not give them special meaning.
@@ -62,7 +62,7 @@ npm run generate
62
62
  - [02-outgoing_costs.pl](chapter-08/02-outgoing_costs.pl)
63
63
  - [03-best_route.pl](chapter-08/03-best_route.pl)
64
64
 
65
- ## Chapter 9: Structured data, strings, and contexts
65
+ ## Chapter 9: Structured data, text, and contexts
66
66
 
67
67
  - [01-functor.pl](chapter-09/01-functor.pl)
68
68
  - [02-normalized.pl](chapter-09/02-normalized.pl)
@@ -2,4 +2,4 @@
2
2
  normalized(Input, Words) :-
3
3
  trim(Input, Trimmed),
4
4
  lowercase(Trimmed, Lower),
5
- split(Lower, " ", Words).
5
+ split(Lower, ' ', Words).
@@ -1,6 +1,6 @@
1
1
  % From The Art of EyeProlog, Chapter 33 — Pattern 2: Normalize at the boundary.
2
- source_role(person_7, "Doctor").
2
+ source_role(person_7, 'Doctor').
3
3
 
4
4
  canonical_role(Person, clinician) :-
5
5
  source_role(Person, Text),
6
- lowercase(Text, "doctor").
6
+ lowercase(Text, doctor).
@@ -105,7 +105,7 @@ insight_graph(delfourInsightGraph, (
105
105
  retailer(insight, "Delfour"),
106
106
  createdAt(insight, "2025-10-05T20:33:48.907163+00:00"),
107
107
  expiresAt(insight, "2025-10-05T22:33:48.907185+00:00"),
108
- serializedLowercase(insight, "createdat expiresat insight metric sugar_g_per_serving retailer delfour scopedevice self-scanner scopeevent pick_up_scanner")
108
+ serializedLowercase(insight, 'createdat expiresat insight metric sugar_g_per_serving retailer delfour scopedevice self-scanner scopeevent pick_up_scanner')
109
109
  )).
110
110
 
111
111
  policy_graph(delfourPolicyGraph, (
@@ -204,7 +204,7 @@ signature_verifies(check) :-
204
204
 
205
205
  minimization_strips_sensitive_terms(check) :-
206
206
  serialized_lowercase(insight, Text),
207
- \+ matches(Text, "diabetes|medical").
207
+ \+ matches(Text, 'diabetes|medical').
208
208
 
209
209
  scope_complete(check) :-
210
210
  scope_device(insight, _device),
@@ -2,31 +2,31 @@
2
2
 
3
3
  % Run with: eyeprolog --goal 'rdf(S, P, O, G)' program.pl.
4
4
 
5
- rdf(iri("https://example.org/alpha_care_process"), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), iri("https://w3id.org/dpv#Process"), default_graph).
6
- rdf(iri("https://example.org/alpha_care_process"), iri("https://w3id.org/dpv#hasDataController"), iri("https://example.org/hospital_a"), default_graph).
7
- rdf(iri("https://example.org/alpha_care_process"), iri("https://w3id.org/dpv#hasRecipient"), iri("https://example.org/research_partner"), default_graph).
8
- rdf(iri("https://example.org/alpha_care_process"), iri("https://w3id.org/dpv#hasPersonalData"), iri("https://example.org/lab_result"), default_graph).
9
- rdf(iri("https://example.org/alpha_care_process"), iri("https://w3id.org/dpv#hasProcessing"), iri("https://w3id.org/dpv#Use"), default_graph).
10
- rdf(iri("https://example.org/alpha_care_process"), iri("https://w3id.org/dpv#hasPurpose"), iri("https://w3id.org/dpv#Healthcare"), default_graph).
11
- rdf(iri("https://example.org/alpha_care_process"), iri("https://w3id.org/dpv#hasLegalBasis"), iri("https://w3id.org/dpv#Consent"), default_graph).
12
- rdf(iri("https://example.org/alpha_policy"), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), iri("http://www.w3.org/ns/odrl/2/Policy"), default_graph).
13
- rdf(iri("https://example.org/alpha_policy"), iri("https://example.org/representsProcess"), iri("https://example.org/alpha_care_process"), default_graph).
14
- rdf(iri("https://example.org/alpha_policy"), iri("http://www.w3.org/ns/odrl/2/permission"), iri("https://example.org/alpha_permission"), default_graph).
15
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), iri("http://www.w3.org/ns/odrl/2/Permission"), default_graph).
16
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/ns/odrl/2/assigner"), iri("https://example.org/hospital_a"), default_graph).
17
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/ns/odrl/2/assignee"), iri("https://example.org/research_partner"), default_graph).
18
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/ns/odrl/2/target"), iri("https://example.org/lab_result"), default_graph).
19
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/ns/odrl/2/action"), iri("http://www.w3.org/ns/odrl/2/use"), default_graph).
20
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/ns/odrl/2/constraint"), iri("https://example.org/alpha_purpose_constraint"), default_graph).
21
- rdf(iri("https://example.org/alpha_permission"), iri("http://www.w3.org/ns/odrl/2/constraint"), iri("https://example.org/alpha_basis_constraint"), default_graph).
22
- rdf(iri("https://example.org/alpha_purpose_constraint"), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), iri("http://www.w3.org/ns/odrl/2/Constraint"), default_graph).
23
- rdf(iri("https://example.org/alpha_purpose_constraint"), iri("http://www.w3.org/ns/odrl/2/leftOperand"), iri("http://www.w3.org/ns/odrl/2/purpose"), default_graph).
24
- rdf(iri("https://example.org/alpha_purpose_constraint"), iri("http://www.w3.org/ns/odrl/2/operator"), iri("http://www.w3.org/ns/odrl/2/isA"), default_graph).
25
- rdf(iri("https://example.org/alpha_purpose_constraint"), iri("http://www.w3.org/ns/odrl/2/rightOperand"), iri("https://w3id.org/dpv#Healthcare"), default_graph).
26
- rdf(iri("https://example.org/alpha_basis_constraint"), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), iri("http://www.w3.org/ns/odrl/2/Constraint"), default_graph).
27
- rdf(iri("https://example.org/alpha_basis_constraint"), iri("http://www.w3.org/ns/odrl/2/leftOperand"), iri("https://example.org/legalBasis"), default_graph).
28
- rdf(iri("https://example.org/alpha_basis_constraint"), iri("http://www.w3.org/ns/odrl/2/operator"), iri("http://www.w3.org/ns/odrl/2/isA"), default_graph).
29
- rdf(iri("https://example.org/alpha_basis_constraint"), iri("http://www.w3.org/ns/odrl/2/rightOperand"), iri("https://w3id.org/dpv#Consent"), default_graph).
5
+ rdf(iri('https://example.org/alpha_care_process'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('https://w3id.org/dpv#Process'), default_graph).
6
+ rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasDataController'), iri('https://example.org/hospital_a'), default_graph).
7
+ rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasRecipient'), iri('https://example.org/research_partner'), default_graph).
8
+ rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasPersonalData'), iri('https://example.org/lab_result'), default_graph).
9
+ rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasProcessing'), iri('https://w3id.org/dpv#Use'), default_graph).
10
+ rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasPurpose'), iri('https://w3id.org/dpv#Healthcare'), default_graph).
11
+ rdf(iri('https://example.org/alpha_care_process'), iri('https://w3id.org/dpv#hasLegalBasis'), iri('https://w3id.org/dpv#Consent'), default_graph).
12
+ rdf(iri('https://example.org/alpha_policy'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Policy'), default_graph).
13
+ rdf(iri('https://example.org/alpha_policy'), iri('https://example.org/representsProcess'), iri('https://example.org/alpha_care_process'), default_graph).
14
+ rdf(iri('https://example.org/alpha_policy'), iri('http://www.w3.org/ns/odrl/2/permission'), iri('https://example.org/alpha_permission'), default_graph).
15
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Permission'), default_graph).
16
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/assigner'), iri('https://example.org/hospital_a'), default_graph).
17
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/assignee'), iri('https://example.org/research_partner'), default_graph).
18
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/target'), iri('https://example.org/lab_result'), default_graph).
19
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/action'), iri('http://www.w3.org/ns/odrl/2/use'), default_graph).
20
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/constraint'), iri('https://example.org/alpha_purpose_constraint'), default_graph).
21
+ rdf(iri('https://example.org/alpha_permission'), iri('http://www.w3.org/ns/odrl/2/constraint'), iri('https://example.org/alpha_basis_constraint'), default_graph).
22
+ rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Constraint'), default_graph).
23
+ rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/ns/odrl/2/leftOperand'), iri('http://www.w3.org/ns/odrl/2/purpose'), default_graph).
24
+ rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/ns/odrl/2/operator'), iri('http://www.w3.org/ns/odrl/2/isA'), default_graph).
25
+ rdf(iri('https://example.org/alpha_purpose_constraint'), iri('http://www.w3.org/ns/odrl/2/rightOperand'), iri('https://w3id.org/dpv#Healthcare'), default_graph).
26
+ rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), iri('http://www.w3.org/ns/odrl/2/Constraint'), default_graph).
27
+ rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/ns/odrl/2/leftOperand'), iri('https://example.org/legalBasis'), default_graph).
28
+ rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/ns/odrl/2/operator'), iri('http://www.w3.org/ns/odrl/2/isA'), default_graph).
29
+ rdf(iri('https://example.org/alpha_basis_constraint'), iri('http://www.w3.org/ns/odrl/2/rightOperand'), iri('https://w3id.org/dpv#Consent'), default_graph).
30
30
 
31
31
  % Rules
32
32
  % Source data: examples/input/dpv-odrl-purpose-mapping.ttl
@@ -80,9 +80,9 @@ rdf_link(Subject, Predicate, Object) :-
80
80
  rdf(iri(SubjectIri), iri(PredicateIri), iri(ObjectIri), default_graph),
81
81
  iri_term(Object, ObjectIri).
82
82
 
83
- iri_term(ex(Name), Iri) :- namespace_iri("https://example.org/", Name, Iri).
84
- iri_term(dpv(Name), Iri) :- namespace_iri("https://w3id.org/dpv#", Name, Iri).
85
- iri_term(odrl(Name), Iri) :- namespace_iri("http://www.w3.org/ns/odrl/2/", Name, Iri).
83
+ iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
84
+ iri_term(dpv(Name), Iri) :- namespace_iri('https://w3id.org/dpv#', Name, Iri).
85
+ iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
86
86
 
87
87
  namespace_iri(Prefix, Name, Iri) :-
88
88
  atom(Name),
@@ -166,7 +166,7 @@ scopeEvent(macroInsight, "budget-prep-window").
166
166
  region(macroInsight, "Flanders").
167
167
  createdAt(macroInsight, "2026-04-08T07:00:00+00:00").
168
168
  expiresAt(macroInsight, "2026-04-08T19:00:00+00:00").
169
- serializedLowercase(macroInsight, "createdat expiresat insight metric regional_retooling_priority region flanders scopedevice economic-resilience-board scopeevent budget-prep-window suggestionpolicy lowest_cost_package_covering_all_active_needs threshold 3").
169
+ serializedLowercase(macroInsight, 'createdat expiresat insight metric regional_retooling_priority region flanders scopedevice economic-resilience-board scopeevent budget-prep-window suggestionpolicy lowest_cost_package_covering_all_active_needs threshold 3').
170
170
 
171
171
  envelopeInsight(envelope, macroInsight).
172
172
  envelopePolicy(envelope, policy).
@@ -224,7 +224,7 @@ hmac_matches(check) :-
224
224
 
225
225
  minimization_strips_sensitive_terms(check) :-
226
226
  serializedLowercase(macroInsight, Text),
227
- \+ matches(Text, "salary|payroll|invoice|medical|firmname").
227
+ \+ matches(Text, 'salary|payroll|invoice|medical|firmname').
228
228
 
229
229
  scope_complete(check) :-
230
230
  scopeDevice(macroInsight, _device),
@@ -42,8 +42,9 @@ has_factor(N, L) :-
42
42
 
43
43
  % query
44
44
  case(N, G) :-
45
- between(2, 35, I),
45
+ % Keep the portable benchmark below the range where repeated interpreted
46
+ % Miller-Rabin searches dominate the example suite.
47
+ between(2, 25, I),
46
48
  N is 2^I,
47
49
  goldbach(N, G).
48
50
  %% goal: case(_, _)
49
-
@@ -49,9 +49,9 @@ rdf_link(Subject, Predicate, Object) :-
49
49
  rdf(iri(SubjectIri), iri(PredicateIri), iri(ObjectIri), default_graph),
50
50
  iri_term(Object, ObjectIri).
51
51
 
52
- iri_term(ex(Name), Iri) :- namespace_iri("https://example.org/", Name, Iri).
53
- iri_term(dpv(Name), Iri) :- namespace_iri("https://w3id.org/dpv#", Name, Iri).
54
- iri_term(odrl(Name), Iri) :- namespace_iri("http://www.w3.org/ns/odrl/2/", Name, Iri).
52
+ iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
53
+ iri_term(dpv(Name), Iri) :- namespace_iri('https://w3id.org/dpv#', Name, Iri).
54
+ iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
55
55
 
56
56
  namespace_iri(Prefix, Name, Iri) :-
57
57
  atom(Name),
@@ -67,8 +67,8 @@ rdf_number(Subject, Predicate, Number) :-
67
67
  rdf(iri(SubjectIri), iri(PredicateIri), literal(Text, datatype(_Datatype)), default_graph),
68
68
  number_string(Number, Text).
69
69
 
70
- iri_term(ex(Name), Iri) :- namespace_iri("https://example.org/", Name, Iri).
71
- iri_term(odrl(Name), Iri) :- namespace_iri("http://www.w3.org/ns/odrl/2/", Name, Iri).
70
+ iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
71
+ iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
72
72
 
73
73
  namespace_iri(Prefix, Name, Iri) :-
74
74
  atom(Name),
@@ -96,8 +96,8 @@ rdf_number(Subject, Predicate, Number) :-
96
96
  rdf_text(Subject, Predicate, Text),
97
97
  number_string(Number, Text).
98
98
 
99
- iri_term(ex(Name), Iri) :- namespace_iri("https://example.org/", Name, Iri).
100
- iri_term(odrl(Name), Iri) :- namespace_iri("http://www.w3.org/ns/odrl/2/", Name, Iri).
99
+ iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
100
+ iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
101
101
 
102
102
  namespace_iri(Prefix, Name, Iri) :-
103
103
  atom(Name),
@@ -108,8 +108,8 @@ rdf_number(Subject, Predicate, Number) :-
108
108
  rdf_text(Subject, Predicate, Text),
109
109
  number_string(Number, Text).
110
110
 
111
- iri_term(ex(Name), Iri) :- namespace_iri("https://example.org/", Name, Iri).
112
- iri_term(odrl(Name), Iri) :- namespace_iri("http://www.w3.org/ns/odrl/2/", Name, Iri).
111
+ iri_term(ex(Name), Iri) :- namespace_iri('https://example.org/', Name, Iri).
112
+ iri_term(odrl(Name), Iri) :- namespace_iri('http://www.w3.org/ns/odrl/2/', Name, Iri).
113
113
 
114
114
  namespace_iri(Prefix, Name, Iri) :-
115
115
  atom(Name),
@@ -62,29 +62,29 @@ rdf_link(Subject, Predicate, Object) :-
62
62
  iri_value(Object, ObjectIri),
63
63
  rdf(iri(SubjectIri), iri(PredicateIri), iri(ObjectIri), default_graph).
64
64
 
65
- iri_value(advanced_policy, "https://example.org/advanced-policy").
66
- iri_value(research_permission, "https://example.org/research-permission").
67
- iri_value(transfer_prohibition, "https://example.org/transfer-prohibition").
68
- iri_value(health_dataset, "https://example.org/health-dataset").
69
- iri_value(research_hospital, "https://example.org/research-hospital").
70
- iri_value(medical_research, "https://example.org/medical-research").
71
- iri_value(eu, "https://example.org/eu").
72
- iri_value(deidentify_duty, "https://example.org/deidentify-duty").
73
- iri_value(deidentify, "https://example.org/deidentify").
74
- iri_value(purpose_constraint, "https://example.org/purpose-constraint").
75
- iri_value(region_constraint, "https://example.org/region-constraint").
76
- iri_value(permission, "http://www.w3.org/ns/odrl/2/permission").
77
- iri_value(prohibition, "http://www.w3.org/ns/odrl/2/prohibition").
78
- iri_value(target, "http://www.w3.org/ns/odrl/2/target").
79
- iri_value(action, "http://www.w3.org/ns/odrl/2/action").
80
- iri_value(assignee, "http://www.w3.org/ns/odrl/2/assignee").
81
- iri_value(constraint, "http://www.w3.org/ns/odrl/2/constraint").
82
- iri_value(duty, "http://www.w3.org/ns/odrl/2/duty").
83
- iri_value(left_operand, "http://www.w3.org/ns/odrl/2/leftOperand").
84
- iri_value(operator, "http://www.w3.org/ns/odrl/2/operator").
85
- iri_value(right_operand, "http://www.w3.org/ns/odrl/2/rightOperand").
86
- iri_value(purpose, "http://www.w3.org/ns/odrl/2/purpose").
87
- iri_value(spatial, "http://www.w3.org/ns/odrl/2/spatial").
88
- iri_value(eq, "http://www.w3.org/ns/odrl/2/eq").
89
- iri_value(use, "http://www.w3.org/ns/odrl/2/use").
90
- iri_value(transfer, "http://www.w3.org/ns/odrl/2/transfer").
65
+ iri_value(advanced_policy, 'https://example.org/advanced-policy').
66
+ iri_value(research_permission, 'https://example.org/research-permission').
67
+ iri_value(transfer_prohibition, 'https://example.org/transfer-prohibition').
68
+ iri_value(health_dataset, 'https://example.org/health-dataset').
69
+ iri_value(research_hospital, 'https://example.org/research-hospital').
70
+ iri_value(medical_research, 'https://example.org/medical-research').
71
+ iri_value(eu, 'https://example.org/eu').
72
+ iri_value(deidentify_duty, 'https://example.org/deidentify-duty').
73
+ iri_value(deidentify, 'https://example.org/deidentify').
74
+ iri_value(purpose_constraint, 'https://example.org/purpose-constraint').
75
+ iri_value(region_constraint, 'https://example.org/region-constraint').
76
+ iri_value(permission, 'http://www.w3.org/ns/odrl/2/permission').
77
+ iri_value(prohibition, 'http://www.w3.org/ns/odrl/2/prohibition').
78
+ iri_value(target, 'http://www.w3.org/ns/odrl/2/target').
79
+ iri_value(action, 'http://www.w3.org/ns/odrl/2/action').
80
+ iri_value(assignee, 'http://www.w3.org/ns/odrl/2/assignee').
81
+ iri_value(constraint, 'http://www.w3.org/ns/odrl/2/constraint').
82
+ iri_value(duty, 'http://www.w3.org/ns/odrl/2/duty').
83
+ iri_value(left_operand, 'http://www.w3.org/ns/odrl/2/leftOperand').
84
+ iri_value(operator, 'http://www.w3.org/ns/odrl/2/operator').
85
+ iri_value(right_operand, 'http://www.w3.org/ns/odrl/2/rightOperand').
86
+ iri_value(purpose, 'http://www.w3.org/ns/odrl/2/purpose').
87
+ iri_value(spatial, 'http://www.w3.org/ns/odrl/2/spatial').
88
+ iri_value(eq, 'http://www.w3.org/ns/odrl/2/eq').
89
+ iri_value(use, 'http://www.w3.org/ns/odrl/2/use').
90
+ iri_value(transfer, 'http://www.w3.org/ns/odrl/2/transfer').
@@ -7,44 +7,44 @@
7
7
 
8
8
  odrl_policy_decision(permit(use, research, dataset)) :-
9
9
  rdf(
10
- iri("https://example.org/policy"),
11
- iri("http://www.w3.org/ns/odrl/2/permission"),
10
+ iri('https://example.org/policy'),
11
+ iri('http://www.w3.org/ns/odrl/2/permission'),
12
12
  Permission,
13
13
  default_graph
14
14
  ),
15
15
  rdf(
16
16
  Permission,
17
- iri("http://www.w3.org/ns/odrl/2/target"),
18
- iri("https://example.org/dataset"),
17
+ iri('http://www.w3.org/ns/odrl/2/target'),
18
+ iri('https://example.org/dataset'),
19
19
  default_graph
20
20
  ),
21
21
  rdf(
22
22
  Permission,
23
- iri("http://www.w3.org/ns/odrl/2/action"),
24
- iri("http://www.w3.org/ns/odrl/2/use"),
23
+ iri('http://www.w3.org/ns/odrl/2/action'),
24
+ iri('http://www.w3.org/ns/odrl/2/use'),
25
25
  default_graph
26
26
  ),
27
27
  rdf(
28
28
  Permission,
29
- iri("http://www.w3.org/ns/odrl/2/constraint"),
29
+ iri('http://www.w3.org/ns/odrl/2/constraint'),
30
30
  Constraint,
31
31
  default_graph
32
32
  ),
33
33
  rdf(
34
34
  Constraint,
35
- iri("http://www.w3.org/ns/odrl/2/leftOperand"),
36
- iri("http://www.w3.org/ns/odrl/2/purpose"),
35
+ iri('http://www.w3.org/ns/odrl/2/leftOperand'),
36
+ iri('http://www.w3.org/ns/odrl/2/purpose'),
37
37
  default_graph
38
38
  ),
39
39
  rdf(
40
40
  Constraint,
41
- iri("http://www.w3.org/ns/odrl/2/operator"),
42
- iri("http://www.w3.org/ns/odrl/2/eq"),
41
+ iri('http://www.w3.org/ns/odrl/2/operator'),
42
+ iri('http://www.w3.org/ns/odrl/2/eq'),
43
43
  default_graph
44
44
  ),
45
45
  rdf(
46
46
  Constraint,
47
- iri("http://www.w3.org/ns/odrl/2/rightOperand"),
48
- iri("https://example.org/research"),
47
+ iri('http://www.w3.org/ns/odrl/2/rightOperand'),
48
+ iri('https://example.org/research'),
49
49
  default_graph
50
50
  ).
@@ -32,24 +32,24 @@ annotated_status_claim(Status, Source, Score) :-
32
32
  status_resource(Status, StatusIri),
33
33
  source_resource(Source, SourceIri),
34
34
  rdf(
35
- iri("https://example.org/bridge"),
36
- iri("https://example.org/status"),
35
+ iri('https://example.org/bridge'),
36
+ iri('https://example.org/status'),
37
37
  iri(StatusIri),
38
38
  default_graph
39
39
  ),
40
40
  rdf(
41
41
  Reifier,
42
- iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies"),
42
+ iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies'),
43
43
  triple(
44
- iri("https://example.org/bridge"),
45
- iri("https://example.org/status"),
44
+ iri('https://example.org/bridge'),
45
+ iri('https://example.org/status'),
46
46
  iri(StatusIri)
47
47
  ),
48
48
  default_graph
49
49
  ),
50
50
  rdf(
51
51
  Reifier,
52
- iri("https://example.org/assertedBy"),
52
+ iri('https://example.org/assertedBy'),
53
53
  iri(SourceIri),
54
54
  default_graph
55
55
  ),
@@ -5,19 +5,19 @@ annotated_claim(S, P, O, Reifier, Source, Date) :-
5
5
  rdf(S, P, O, default_graph),
6
6
  rdf(
7
7
  Reifier,
8
- iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies"),
8
+ iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies'),
9
9
  triple(S, P, O),
10
10
  default_graph
11
11
  ),
12
12
  rdf(
13
13
  Reifier,
14
- iri("https://example.org/statedBy"),
14
+ iri('https://example.org/statedBy'),
15
15
  Source,
16
16
  default_graph
17
17
  ),
18
18
  rdf(
19
19
  Reifier,
20
- iri("https://example.org/recorded"),
20
+ iri('https://example.org/recorded'),
21
21
  Date,
22
22
  default_graph
23
23
  ).
@@ -1,3 +1,5 @@
1
1
  % Preserve RDF 1.2 base-direction metadata while deriving display labels.
2
- rdf(S, iri("https://example.org/displayLabel"), Label, G) :-
3
- rdf(S, iri("https://example.org/label"), Label, G).
2
+ %% goal: rdf(X0, X1, X2, X3)
3
+
4
+ rdf(S, iri('https://example.org/displayLabel'), Label, G) :-
5
+ rdf(S, iri('https://example.org/label'), Label, G).
@@ -1,12 +1,13 @@
1
1
  % Match nested RDF 1.2 triple terms and derive the innermost relationship.
2
- rdf(S, iri("https://example.org/knows"), O, G) :-
2
+ rdf(S, iri('https://example.org/knows'), O, G) :-
3
3
  rdf(
4
4
  _,
5
- iri("https://example.org/reviews"),
5
+ iri('https://example.org/reviews'),
6
6
  triple(
7
7
  _,
8
- iri("https://example.org/claims"),
9
- triple(S, iri("https://example.org/knows"), O)
8
+ iri('https://example.org/claims'),
9
+ triple(S, iri('https://example.org/knows'), O)
10
10
  ),
11
11
  G
12
12
  ).
13
+ %% goal: rdf(X0, X1, X2, X3)
@@ -1,14 +1,15 @@
1
1
  % Join graph metadata in the default graph with data from the named graph.
2
- rdf(S, iri("https://example.org/reportedBy"), Station, default_graph) :-
2
+ rdf(S, iri('https://example.org/reportedBy'), Station, default_graph) :-
3
3
  rdf(
4
- iri("https://example.org/sensorGraph"),
5
- iri("https://example.org/reportedBy"),
4
+ iri('https://example.org/sensorGraph'),
5
+ iri('https://example.org/reportedBy'),
6
6
  Station,
7
7
  default_graph
8
8
  ),
9
9
  rdf(
10
10
  S,
11
- iri("https://example.org/temperature"),
11
+ iri('https://example.org/temperature'),
12
12
  _,
13
- iri("https://example.org/sensorGraph")
13
+ iri('https://example.org/sensorGraph')
14
14
  ).
15
+ %% goal: rdf(X0, X1, X2, X3)
@@ -1,7 +1,8 @@
1
1
  % Derive relationships inside the named graph that supplied the source data.
2
- rdf(S, iri("https://example.org/ancestor"), O, G) :-
3
- rdf(S, iri("https://example.org/parent"), O, G).
2
+ rdf(S, iri('https://example.org/ancestor'), O, G) :-
3
+ rdf(S, iri('https://example.org/parent'), O, G).
4
4
 
5
- rdf(S, iri("https://example.org/ancestor"), O, G) :-
6
- rdf(S, iri("https://example.org/parent"), M, G),
7
- rdf(M, iri("https://example.org/parent"), O, G).
5
+ rdf(S, iri('https://example.org/ancestor'), O, G) :-
6
+ rdf(S, iri('https://example.org/parent'), M, G),
7
+ rdf(M, iri('https://example.org/parent'), O, G).
8
+ %% goal: rdf(X0, X1, X2, X3)
@@ -1,8 +1,9 @@
1
1
  % Project a triple term while preserving its named-graph context.
2
- rdf(S, iri("https://example.org/knows"), O, G) :-
2
+ rdf(S, iri('https://example.org/knows'), O, G) :-
3
3
  rdf(
4
4
  _,
5
- iri("https://example.org/claims"),
6
- triple(S, iri("https://example.org/knows"), O),
5
+ iri('https://example.org/claims'),
6
+ triple(S, iri('https://example.org/knows'), O),
7
7
  G
8
8
  ).
9
+ %% goal: rdf(X0, X1, X2, X3)
@@ -1,8 +1,9 @@
1
1
  % Project an RDF 1.2 triple term into an ordinary asserted relationship.
2
- rdf(S, iri("https://example.org/knows"), O, G) :-
2
+ rdf(S, iri('https://example.org/knows'), O, G) :-
3
3
  rdf(
4
4
  _,
5
- iri("https://example.org/claims"),
6
- triple(S, iri("https://example.org/knows"), O),
5
+ iri('https://example.org/claims'),
6
+ triple(S, iri('https://example.org/knows'), O),
7
7
  G
8
8
  ).
9
+ %% goal: rdf(X0, X1, X2, X3)
@@ -11,12 +11,12 @@
11
11
  %% goal: trace_alert(X0, X1, X2)
12
12
 
13
13
 
14
- log_pattern("^ts=(?<ts>\\S+) level=(?<level>\\w+) event=(?<event>\\w+) user=(?<user>\\w+) ip=(?<ip>\\S+) traceparent=00-(?<trace_id>[0-9a-f]{32})-(?<span_id>[0-9a-f]{16})-(?<flags>[0-9a-f]{2})$").
14
+ log_pattern('^ts=(?<ts>\\S+) level=(?<level>\\w+) event=(?<event>\\w+) user=(?<user>\\w+) ip=(?<ip>\\S+) traceparent=00-(?<trace_id>[0-9a-f]{32})-(?<span_id>[0-9a-f]{16})-(?<flags>[0-9a-f]{2})$').
15
15
 
16
- raw_log(l1, "ts=2026-06-18T10:00:00Z level=warn event=login_failed user=alice ip=203.0.113.9 traceparent=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01").
17
- raw_log(l2, "ts=2026-06-18T10:00:03Z level=error event=payment_denied user=alice ip=203.0.113.9 traceparent=00-4bf92f3577b34da6a3ce929d0e0e4736-aaf067aa0ba90000-01").
18
- raw_log(l3, "ts=2026-06-18T10:01:12Z level=info event=login_success user=bob ip=198.51.100.4 traceparent=00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01").
19
- raw_log(noise, "healthcheck ok").
16
+ raw_log(l1, 'ts=2026-06-18T10:00:00Z level=warn event=login_failed user=alice ip=203.0.113.9 traceparent=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01').
17
+ raw_log(l2, 'ts=2026-06-18T10:00:03Z level=error event=payment_denied user=alice ip=203.0.113.9 traceparent=00-4bf92f3577b34da6a3ce929d0e0e4736-aaf067aa0ba90000-01').
18
+ raw_log(l3, 'ts=2026-06-18T10:01:12Z level=info event=login_success user=bob ip=198.51.100.4 traceparent=00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01').
19
+ raw_log(noise, 'healthcheck ok').
20
20
 
21
21
  parsed(Log, Context) :-
22
22
  raw_log(Log, Text),
@@ -42,6 +42,6 @@ parsed_event(Log, Event, User, Ip, Traceid) :-
42
42
  context_member(Context, trace_id(Traceid)).
43
43
 
44
44
  trace_alert(User, Traceid, Ip) :-
45
- parsed_event(Loginlog, "login_failed", User, Ip, Traceid),
46
- parsed_event(Paymentlog, "payment_denied", User, Ip, Traceid),
45
+ parsed_event(Loginlog, 'login_failed', User, Ip, Traceid),
46
+ parsed_event(Paymentlog, 'payment_denied', User, Ip, Traceid),
47
47
  (Loginlog \= Paymentlog).