eyeling 1.34.6 → 2.35.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 (448) hide show
  1. package/README.md +33 -0
  2. package/dist/browser/eyeling.browser.js +284 -14
  3. package/examples/collatz-1000.n3 +4 -0
  4. package/examples/fibonacci.n3 +13 -8
  5. package/examples/fundamental-theorem-arithmetic.n3 +6 -0
  6. package/eyeling.js +284 -14
  7. package/lib/cli.js +2 -2
  8. package/lib/engine.js +269 -4
  9. package/lib/multisource.js +1 -1
  10. package/lib/parser.js +12 -7
  11. package/package.json +1 -1
  12. package/test/eyelang/conformance/README.md +0 -43
  13. package/test/eyelang/conformance/cases/001_fact_output.pl +0 -4
  14. package/test/eyelang/conformance/cases/002_rule_recursion.pl +0 -7
  15. package/test/eyelang/conformance/cases/002_rule_recursion.query +0 -1
  16. package/test/eyelang/conformance/cases/003_terms_and_readback.pl +0 -16
  17. package/test/eyelang/conformance/cases/003_terms_and_readback.query +0 -1
  18. package/test/eyelang/conformance/cases/004_conjunction_and_parentheses.pl +0 -5
  19. package/test/eyelang/conformance/cases/004_conjunction_and_parentheses.query +0 -1
  20. package/test/eyelang/conformance/cases/005_list_deconstruction.pl +0 -6
  21. package/test/eyelang/conformance/cases/005_list_deconstruction.query +0 -1
  22. package/test/eyelang/conformance/cases/006_comma_formula_data.pl +0 -4
  23. package/test/eyelang/conformance/cases/006_comma_formula_data.query +0 -1
  24. package/test/eyelang/conformance/cases/007_anonymous_variables.pl +0 -5
  25. package/test/eyelang/conformance/cases/007_anonymous_variables.query +0 -1
  26. package/test/eyelang/conformance/cases/008_graphic_atoms.pl +0 -6
  27. package/test/eyelang/conformance/cases/008_graphic_atoms.query +0 -1
  28. package/test/eyelang/conformance/cases/009_comments_and_whitespace.pl +0 -5
  29. package/test/eyelang/conformance/cases/009_comments_and_whitespace.query +0 -1
  30. package/test/eyelang/conformance/cases/010_variable_scope_and_reuse.pl +0 -8
  31. package/test/eyelang/conformance/cases/010_variable_scope_and_reuse.query +0 -1
  32. package/test/eyelang/conformance/cases/011_predicate_arity.pl +0 -6
  33. package/test/eyelang/conformance/cases/011_predicate_arity.query +0 -1
  34. package/test/eyelang/conformance/cases/012_nested_compound_unification.pl +0 -5
  35. package/test/eyelang/conformance/cases/012_nested_compound_unification.query +0 -1
  36. package/test/eyelang/conformance/cases/013_multiple_clauses_order.pl +0 -6
  37. package/test/eyelang/conformance/cases/013_multiple_clauses_order.query +0 -1
  38. package/test/eyelang/conformance/cases/014_failure_filters_answers.pl +0 -7
  39. package/test/eyelang/conformance/cases/014_failure_filters_answers.query +0 -1
  40. package/test/eyelang/conformance/cases/015_improper_list_unification.pl +0 -6
  41. package/test/eyelang/conformance/cases/015_improper_list_unification.query +0 -1
  42. package/test/eyelang/conformance/cases/016_zero_arity_compound.pl +0 -4
  43. package/test/eyelang/conformance/cases/016_zero_arity_compound.query +0 -1
  44. package/test/eyelang/conformance/cases/017_three_step_recursion.pl +0 -8
  45. package/test/eyelang/conformance/cases/017_three_step_recursion.query +0 -1
  46. package/test/eyelang/conformance/cases/018_quoted_atom_readback.pl +0 -6
  47. package/test/eyelang/conformance/cases/018_quoted_atom_readback.query +0 -1
  48. package/test/eyelang/conformance/cases/019_parenthesized_three_conjuncts.pl +0 -7
  49. package/test/eyelang/conformance/cases/019_parenthesized_three_conjuncts.query +0 -1
  50. package/test/eyelang/conformance/cases/020_nested_list_terms.pl +0 -5
  51. package/test/eyelang/conformance/cases/020_nested_list_terms.query +0 -1
  52. package/test/eyelang/conformance/cases/021_repeated_variable_head.pl +0 -7
  53. package/test/eyelang/conformance/cases/022_rule_head_structure.pl +0 -5
  54. package/test/eyelang/conformance/cases/023_quoted_escapes_readback.pl +0 -5
  55. package/test/eyelang/conformance/cases/024_numeric_literal_readback.pl +0 -6
  56. package/test/eyelang/conformance/cases/025_body_parentheses_with_formula_data.pl +0 -5
  57. package/test/eyelang/conformance/cases/026_underscore_named_variable_reuse.pl +0 -5
  58. package/test/eyelang/conformance/cases/027_default_derived_output.pl +0 -5
  59. package/test/eyelang/conformance/cases/028_materialize_focus.pl +0 -5
  60. package/test/eyelang/conformance/cases/029_arithmetic_and_comparison.pl +0 -11
  61. package/test/eyelang/conformance/cases/029_arithmetic_and_comparison.query +0 -1
  62. package/test/eyelang/conformance/cases/030_strings_and_atoms.pl +0 -4
  63. package/test/eyelang/conformance/cases/030_strings_and_atoms.query +0 -1
  64. package/test/eyelang/conformance/cases/031_lists_aggregation_ordering.pl +0 -10
  65. package/test/eyelang/conformance/cases/031_lists_aggregation_ordering.query +0 -1
  66. package/test/eyelang/conformance/cases/032_holds_parts.pl +0 -4
  67. package/test/eyelang/conformance/cases/033_negation_once_generators.pl +0 -7
  68. package/test/eyelang/conformance/cases/033_negation_once_generators.query +0 -1
  69. package/test/eyelang/conformance/cases/034_equality_and_inequality.pl +0 -6
  70. package/test/eyelang/conformance/cases/034_equality_and_inequality.query +0 -1
  71. package/test/eyelang/conformance/cases/035_list_relations.pl +0 -5
  72. package/test/eyelang/conformance/cases/035_list_relations.query +0 -1
  73. package/test/eyelang/conformance/cases/036_append_splits.pl +0 -3
  74. package/test/eyelang/conformance/cases/036_append_splits.query +0 -1
  75. package/test/eyelang/conformance/cases/037_matching_and_comparison.pl +0 -7
  76. package/test/eyelang/conformance/cases/037_matching_and_comparison.query +0 -1
  77. package/test/eyelang/conformance/cases/038_memoize_declaration.pl +0 -8
  78. package/test/eyelang/conformance/cases/038_memoize_declaration.query +0 -1
  79. package/test/eyelang/conformance/cases/039_numeric_functions.pl +0 -9
  80. package/test/eyelang/conformance/cases/039_numeric_functions.query +0 -1
  81. package/test/eyelang/conformance/cases/040_between_enumeration.pl +0 -3
  82. package/test/eyelang/conformance/cases/040_between_enumeration.query +0 -1
  83. package/test/eyelang/conformance/cases/041_smallest_divisor.pl +0 -3
  84. package/test/eyelang/conformance/cases/041_smallest_divisor.query +0 -1
  85. package/test/eyelang/conformance/cases/042_negation_filter.pl +0 -7
  86. package/test/eyelang/conformance/cases/042_negation_filter.query +0 -1
  87. package/test/eyelang/conformance/cases/043_once_user_predicate.pl +0 -5
  88. package/test/eyelang/conformance/cases/043_once_user_predicate.query +0 -1
  89. package/test/eyelang/conformance/cases/044_findall_user_goal.pl +0 -6
  90. package/test/eyelang/conformance/cases/044_findall_user_goal.query +0 -1
  91. package/test/eyelang/conformance/cases/045_sort_deduplicates_atoms.pl +0 -3
  92. package/test/eyelang/conformance/cases/045_sort_deduplicates_atoms.query +0 -1
  93. package/test/eyelang/conformance/cases/046_append_bound_prefix_suffix.pl +0 -4
  94. package/test/eyelang/conformance/cases/046_append_bound_prefix_suffix.query +0 -1
  95. package/test/eyelang/conformance/cases/047_nth0_index_generation.pl +0 -3
  96. package/test/eyelang/conformance/cases/047_nth0_index_generation.query +0 -1
  97. package/test/eyelang/conformance/cases/048_set_nth0_edges.pl +0 -4
  98. package/test/eyelang/conformance/cases/048_set_nth0_edges.query +0 -1
  99. package/test/eyelang/conformance/cases/049_select_duplicate_occurrences.pl +0 -3
  100. package/test/eyelang/conformance/cases/049_select_duplicate_occurrences.query +0 -1
  101. package/test/eyelang/conformance/cases/050_not_member_filter.pl +0 -6
  102. package/test/eyelang/conformance/cases/050_not_member_filter.query +0 -1
  103. package/test/eyelang/conformance/cases/051_nested_holds_parts.pl +0 -4
  104. package/test/eyelang/conformance/cases/052_holds_member.pl +0 -3
  105. package/test/eyelang/conformance/cases/053_materialize_excludes_source_fact.pl +0 -6
  106. package/test/eyelang/conformance/cases/054_numeric_and_lexical_comparison.pl +0 -5
  107. package/test/eyelang/conformance/cases/054_numeric_and_lexical_comparison.query +0 -1
  108. package/test/eyelang/conformance/cases/055_string_matching_filters.pl +0 -6
  109. package/test/eyelang/conformance/cases/055_string_matching_filters.query +0 -1
  110. package/test/eyelang/conformance/cases/056_string_and_atom_concat.pl +0 -3
  111. package/test/eyelang/conformance/cases/056_string_and_atom_concat.query +0 -1
  112. package/test/eyelang/conformance/cases/057_countall_empty_and_nonempty.pl +0 -4
  113. package/test/eyelang/conformance/cases/057_countall_empty_and_nonempty.query +0 -1
  114. package/test/eyelang/conformance/cases/058_sumall_numeric_template.pl +0 -5
  115. package/test/eyelang/conformance/cases/058_sumall_numeric_template.query +0 -1
  116. package/test/eyelang/conformance/cases/059_aggregate_min_template.pl +0 -5
  117. package/test/eyelang/conformance/cases/059_aggregate_min_template.query +0 -1
  118. package/test/eyelang/conformance/cases/060_aggregate_max_compound_key.pl +0 -5
  119. package/test/eyelang/conformance/cases/060_aggregate_max_compound_key.query +0 -1
  120. package/test/eyelang/conformance/cases/061_date_difference.pl +0 -4
  121. package/test/eyelang/conformance/cases/062_reusable_numeric_builtins.pl +0 -10
  122. package/test/eyelang/conformance/cases/063_reusable_list_builtins.pl +0 -11
  123. package/test/eyelang/conformance/cases/064_reusable_string_builtins.pl +0 -12
  124. package/test/eyelang/conformance/cases/065_reusable_term_control_builtins.pl +0 -11
  125. package/test/eyelang/conformance/cases/066_numeric_edges.pl +0 -14
  126. package/test/eyelang/conformance/cases/067_list_edges.pl +0 -10
  127. package/test/eyelang/conformance/cases/068_list_generation_order.pl +0 -7
  128. package/test/eyelang/conformance/cases/069_list_summaries_and_sets.pl +0 -9
  129. package/test/eyelang/conformance/cases/070_matches_named_captures.pl +0 -13
  130. package/test/eyelang/conformance/cases/071_string_edges.pl +0 -10
  131. package/test/eyelang/conformance/cases/072_string_conversions.pl +0 -10
  132. package/test/eyelang/conformance/cases/073_term_introspection_edges.pl +0 -10
  133. package/test/eyelang/conformance/cases/074_forall_edges.pl +0 -10
  134. package/test/eyelang/conformance/cases/075_aggregation_edges.pl +0 -12
  135. package/test/eyelang/conformance/cases/076_composed_reusable_builtins.pl +0 -8
  136. package/test/eyelang/conformance/cases/077_recursive_path_with_lists.pl +0 -10
  137. package/test/eyelang/conformance/cases/078_mutual_recursion_with_arithmetic.pl +0 -7
  138. package/test/eyelang/conformance/cases/079_big_integer_arithmetic.pl +0 -8
  139. package/test/eyelang/conformance/cases/080_rounding_modes.pl +0 -10
  140. package/test/eyelang/conformance/cases/081_zero_safe_numeric_functions.pl +0 -9
  141. package/test/eyelang/conformance/cases/082_comparison_semantics.pl +0 -10
  142. package/test/eyelang/conformance/cases/083_between_modes_and_empty_ranges.pl +0 -8
  143. package/test/eyelang/conformance/cases/084_append_and_select_composition.pl +0 -7
  144. package/test/eyelang/conformance/cases/085_nth_and_update_edges.pl +0 -8
  145. package/test/eyelang/conformance/cases/086_slicing_pipeline.pl +0 -10
  146. package/test/eyelang/conformance/cases/087_sort_reverse_length.pl +0 -8
  147. package/test/eyelang/conformance/cases/088_list_summaries_failures.pl +0 -8
  148. package/test/eyelang/conformance/cases/089_string_split_join_pipeline.pl +0 -7
  149. package/test/eyelang/conformance/cases/090_string_substring_replace_edges.pl +0 -9
  150. package/test/eyelang/conformance/cases/091_string_case_and_trim.pl +0 -7
  151. package/test/eyelang/conformance/cases/092_scalar_string_conversions.pl +0 -9
  152. package/test/eyelang/conformance/cases/093_regex_named_captures_context.pl +0 -8
  153. package/test/eyelang/conformance/cases/094_context_holds_enumeration.pl +0 -7
  154. package/test/eyelang/conformance/cases/095_term_introspection_roundtrip.pl +0 -8
  155. package/test/eyelang/conformance/cases/096_functor_scalar_edges.pl +0 -8
  156. package/test/eyelang/conformance/cases/097_control_negation_once_forall.pl +0 -13
  157. package/test/eyelang/conformance/cases/098_aggregation_nested_templates.pl +0 -11
  158. package/test/eyelang/conformance/cases/099_materialize_multiple_arities.pl +0 -8
  159. package/test/eyelang/conformance/cases/100_reusable_builtin_workflow.pl +0 -10
  160. package/test/eyelang/conformance/cases/core/001_fact_output.pl +0 -4
  161. package/test/eyelang/conformance/cases/core/001_fact_query.query +0 -1
  162. package/test/eyelang/conformance/cases/core/002_rule_recursion.pl +0 -7
  163. package/test/eyelang/conformance/cases/core/002_rule_recursion.query +0 -1
  164. package/test/eyelang/conformance/cases/core/003_terms_and_readback.pl +0 -16
  165. package/test/eyelang/conformance/cases/core/003_terms_and_readback.query +0 -1
  166. package/test/eyelang/conformance/cases/core/004_conjunction_and_parentheses.pl +0 -5
  167. package/test/eyelang/conformance/cases/core/004_conjunction_and_parentheses.query +0 -1
  168. package/test/eyelang/conformance/cases/core/005_list_deconstruction.pl +0 -6
  169. package/test/eyelang/conformance/cases/core/005_list_deconstruction.query +0 -1
  170. package/test/eyelang/conformance/cases/core/006_comma_formula_data.pl +0 -4
  171. package/test/eyelang/conformance/cases/core/006_comma_formula_data.query +0 -1
  172. package/test/eyelang/conformance/cases/core/007_anonymous_variables.pl +0 -5
  173. package/test/eyelang/conformance/cases/core/007_anonymous_variables.query +0 -1
  174. package/test/eyelang/conformance/cases/core/008_graphic_atoms.pl +0 -6
  175. package/test/eyelang/conformance/cases/core/008_graphic_atoms.query +0 -1
  176. package/test/eyelang/conformance/cases/core/009_comments_and_whitespace.pl +0 -5
  177. package/test/eyelang/conformance/cases/core/009_comments_and_whitespace.query +0 -1
  178. package/test/eyelang/conformance/cases/core/010_variable_scope_and_reuse.pl +0 -8
  179. package/test/eyelang/conformance/cases/core/010_variable_scope_and_reuse.query +0 -1
  180. package/test/eyelang/conformance/cases/core/011_predicate_arity.pl +0 -6
  181. package/test/eyelang/conformance/cases/core/011_predicate_arity.query +0 -1
  182. package/test/eyelang/conformance/cases/core/012_nested_compound_unification.pl +0 -5
  183. package/test/eyelang/conformance/cases/core/012_nested_compound_unification.query +0 -1
  184. package/test/eyelang/conformance/cases/core/013_multiple_clauses_order.pl +0 -6
  185. package/test/eyelang/conformance/cases/core/013_multiple_clauses_order.query +0 -1
  186. package/test/eyelang/conformance/cases/core/014_failure_filters_answers.pl +0 -7
  187. package/test/eyelang/conformance/cases/core/014_failure_filters_answers.query +0 -1
  188. package/test/eyelang/conformance/cases/core/015_improper_list_unification.pl +0 -6
  189. package/test/eyelang/conformance/cases/core/015_improper_list_unification.query +0 -1
  190. package/test/eyelang/conformance/cases/core/016_zero_arity_compound.pl +0 -4
  191. package/test/eyelang/conformance/cases/core/016_zero_arity_compound.query +0 -1
  192. package/test/eyelang/conformance/cases/core/017_three_step_recursion.pl +0 -8
  193. package/test/eyelang/conformance/cases/core/017_three_step_recursion.query +0 -1
  194. package/test/eyelang/conformance/cases/core/018_quoted_atom_readback.pl +0 -6
  195. package/test/eyelang/conformance/cases/core/018_quoted_atom_readback.query +0 -1
  196. package/test/eyelang/conformance/cases/core/019_parenthesized_three_conjuncts.pl +0 -7
  197. package/test/eyelang/conformance/cases/core/019_parenthesized_three_conjuncts.query +0 -1
  198. package/test/eyelang/conformance/cases/core/020_nested_list_terms.pl +0 -5
  199. package/test/eyelang/conformance/cases/core/020_nested_list_terms.query +0 -1
  200. package/test/eyelang/conformance/cases/core/021_repeated_variable_head.pl +0 -7
  201. package/test/eyelang/conformance/cases/core/022_rule_head_structure.pl +0 -5
  202. package/test/eyelang/conformance/cases/core/023_quoted_escapes_readback.pl +0 -5
  203. package/test/eyelang/conformance/cases/core/024_numeric_literal_readback.pl +0 -6
  204. package/test/eyelang/conformance/cases/core/025_body_parentheses_with_formula_data.pl +0 -5
  205. package/test/eyelang/conformance/cases/core/026_underscore_named_variable_reuse.pl +0 -5
  206. package/test/eyelang/conformance/cases/extension/001_default_derived_output.pl +0 -5
  207. package/test/eyelang/conformance/cases/extension/002_materialize_focus.pl +0 -5
  208. package/test/eyelang/conformance/cases/extension/003_arithmetic_and_comparison.pl +0 -11
  209. package/test/eyelang/conformance/cases/extension/003_arithmetic_and_comparison.query +0 -1
  210. package/test/eyelang/conformance/cases/extension/004_strings_and_atoms.pl +0 -4
  211. package/test/eyelang/conformance/cases/extension/004_strings_and_atoms.query +0 -1
  212. package/test/eyelang/conformance/cases/extension/005_lists_aggregation_ordering.pl +0 -10
  213. package/test/eyelang/conformance/cases/extension/005_lists_aggregation_ordering.query +0 -1
  214. package/test/eyelang/conformance/cases/extension/006_formula_terms.query +0 -1
  215. package/test/eyelang/conformance/cases/extension/006_holds_parts.pl +0 -4
  216. package/test/eyelang/conformance/cases/extension/007_negation_once_generators.pl +0 -7
  217. package/test/eyelang/conformance/cases/extension/007_negation_once_generators.query +0 -1
  218. package/test/eyelang/conformance/cases/extension/008_equality_and_inequality.pl +0 -6
  219. package/test/eyelang/conformance/cases/extension/008_equality_and_inequality.query +0 -1
  220. package/test/eyelang/conformance/cases/extension/009_list_relations.pl +0 -5
  221. package/test/eyelang/conformance/cases/extension/009_list_relations.query +0 -1
  222. package/test/eyelang/conformance/cases/extension/010_append_splits.pl +0 -3
  223. package/test/eyelang/conformance/cases/extension/010_append_splits.query +0 -1
  224. package/test/eyelang/conformance/cases/extension/011_matching_and_comparison.pl +0 -7
  225. package/test/eyelang/conformance/cases/extension/011_matching_and_comparison.query +0 -1
  226. package/test/eyelang/conformance/cases/extension/012_memoize_declaration.pl +0 -8
  227. package/test/eyelang/conformance/cases/extension/012_memoize_declaration.query +0 -1
  228. package/test/eyelang/conformance/cases/extension/013_numeric_functions.pl +0 -9
  229. package/test/eyelang/conformance/cases/extension/013_numeric_functions.query +0 -1
  230. package/test/eyelang/conformance/cases/extension/014_between_enumeration.pl +0 -3
  231. package/test/eyelang/conformance/cases/extension/014_between_enumeration.query +0 -1
  232. package/test/eyelang/conformance/cases/extension/015_smallest_divisor.pl +0 -3
  233. package/test/eyelang/conformance/cases/extension/015_smallest_divisor.query +0 -1
  234. package/test/eyelang/conformance/cases/extension/016_negation_filter.pl +0 -7
  235. package/test/eyelang/conformance/cases/extension/016_negation_filter.query +0 -1
  236. package/test/eyelang/conformance/cases/extension/017_once_user_predicate.pl +0 -5
  237. package/test/eyelang/conformance/cases/extension/017_once_user_predicate.query +0 -1
  238. package/test/eyelang/conformance/cases/extension/018_findall_user_goal.pl +0 -6
  239. package/test/eyelang/conformance/cases/extension/018_findall_user_goal.query +0 -1
  240. package/test/eyelang/conformance/cases/extension/019_sort_deduplicates_atoms.pl +0 -3
  241. package/test/eyelang/conformance/cases/extension/019_sort_deduplicates_atoms.query +0 -1
  242. package/test/eyelang/conformance/cases/extension/020_append_bound_prefix_suffix.pl +0 -4
  243. package/test/eyelang/conformance/cases/extension/020_append_bound_prefix_suffix.query +0 -1
  244. package/test/eyelang/conformance/cases/extension/021_nth0_index_generation.pl +0 -3
  245. package/test/eyelang/conformance/cases/extension/021_nth0_index_generation.query +0 -1
  246. package/test/eyelang/conformance/cases/extension/022_set_nth0_edges.pl +0 -4
  247. package/test/eyelang/conformance/cases/extension/022_set_nth0_edges.query +0 -1
  248. package/test/eyelang/conformance/cases/extension/023_select_duplicate_occurrences.pl +0 -3
  249. package/test/eyelang/conformance/cases/extension/023_select_duplicate_occurrences.query +0 -1
  250. package/test/eyelang/conformance/cases/extension/024_not_member_filter.pl +0 -6
  251. package/test/eyelang/conformance/cases/extension/024_not_member_filter.query +0 -1
  252. package/test/eyelang/conformance/cases/extension/026_nested_formula_terms.query +0 -1
  253. package/test/eyelang/conformance/cases/extension/026_nested_holds_parts.pl +0 -4
  254. package/test/eyelang/conformance/cases/extension/027_formula_member.query +0 -1
  255. package/test/eyelang/conformance/cases/extension/027_holds_member.pl +0 -3
  256. package/test/eyelang/conformance/cases/extension/027_materialize_excludes_source_fact.pl +0 -6
  257. package/test/eyelang/conformance/cases/extension/028_numeric_and_lexical_comparison.pl +0 -5
  258. package/test/eyelang/conformance/cases/extension/028_numeric_and_lexical_comparison.query +0 -1
  259. package/test/eyelang/conformance/cases/extension/029_string_matching_filters.pl +0 -6
  260. package/test/eyelang/conformance/cases/extension/029_string_matching_filters.query +0 -1
  261. package/test/eyelang/conformance/cases/extension/030_string_and_atom_concat.pl +0 -3
  262. package/test/eyelang/conformance/cases/extension/030_string_and_atom_concat.query +0 -1
  263. package/test/eyelang/conformance/cases/extension/031_countall_empty_and_nonempty.pl +0 -4
  264. package/test/eyelang/conformance/cases/extension/031_countall_empty_and_nonempty.query +0 -1
  265. package/test/eyelang/conformance/cases/extension/032_sumall_numeric_template.pl +0 -5
  266. package/test/eyelang/conformance/cases/extension/032_sumall_numeric_template.query +0 -1
  267. package/test/eyelang/conformance/cases/extension/033_aggregate_min_template.pl +0 -5
  268. package/test/eyelang/conformance/cases/extension/033_aggregate_min_template.query +0 -1
  269. package/test/eyelang/conformance/cases/extension/034_aggregate_max_compound_key.pl +0 -5
  270. package/test/eyelang/conformance/cases/extension/034_aggregate_max_compound_key.query +0 -1
  271. package/test/eyelang/conformance/cases/extension/035_date_difference.pl +0 -4
  272. package/test/eyelang/conformance/cases/extension/036_reusable_numeric_builtins.pl +0 -10
  273. package/test/eyelang/conformance/cases/extension/037_reusable_list_builtins.pl +0 -11
  274. package/test/eyelang/conformance/cases/extension/038_reusable_string_builtins.pl +0 -12
  275. package/test/eyelang/conformance/cases/extension/039_reusable_term_control_builtins.pl +0 -11
  276. package/test/eyelang/conformance/cases/extension/044_matches_named_captures.pl +0 -13
  277. package/test/eyelang/conformance/expected/001_fact_output.pl +0 -1
  278. package/test/eyelang/conformance/expected/002_rule_recursion.pl +0 -2
  279. package/test/eyelang/conformance/expected/003_terms_and_readback.pl +0 -13
  280. package/test/eyelang/conformance/expected/004_conjunction_and_parentheses.pl +0 -1
  281. package/test/eyelang/conformance/expected/005_list_deconstruction.pl +0 -2
  282. package/test/eyelang/conformance/expected/006_comma_formula_data.pl +0 -1
  283. package/test/eyelang/conformance/expected/007_anonymous_variables.pl +0 -1
  284. package/test/eyelang/conformance/expected/008_graphic_atoms.pl +0 -3
  285. package/test/eyelang/conformance/expected/009_comments_and_whitespace.pl +0 -2
  286. package/test/eyelang/conformance/expected/010_variable_scope_and_reuse.pl +0 -2
  287. package/test/eyelang/conformance/expected/011_predicate_arity.pl +0 -2
  288. package/test/eyelang/conformance/expected/012_nested_compound_unification.pl +0 -2
  289. package/test/eyelang/conformance/expected/013_multiple_clauses_order.pl +0 -2
  290. package/test/eyelang/conformance/expected/014_failure_filters_answers.pl +0 -1
  291. package/test/eyelang/conformance/expected/015_improper_list_unification.pl +0 -3
  292. package/test/eyelang/conformance/expected/016_zero_arity_compound.pl +0 -1
  293. package/test/eyelang/conformance/expected/017_three_step_recursion.pl +0 -3
  294. package/test/eyelang/conformance/expected/018_quoted_atom_readback.pl +0 -3
  295. package/test/eyelang/conformance/expected/019_parenthesized_three_conjuncts.pl +0 -1
  296. package/test/eyelang/conformance/expected/020_nested_list_terms.pl +0 -2
  297. package/test/eyelang/conformance/expected/021_repeated_variable_head.pl +0 -2
  298. package/test/eyelang/conformance/expected/022_rule_head_structure.pl +0 -2
  299. package/test/eyelang/conformance/expected/023_quoted_escapes_readback.pl +0 -2
  300. package/test/eyelang/conformance/expected/024_numeric_literal_readback.pl +0 -3
  301. package/test/eyelang/conformance/expected/025_body_parentheses_with_formula_data.pl +0 -1
  302. package/test/eyelang/conformance/expected/026_underscore_named_variable_reuse.pl +0 -1
  303. package/test/eyelang/conformance/expected/027_default_derived_output.pl +0 -3
  304. package/test/eyelang/conformance/expected/028_materialize_focus.pl +0 -1
  305. package/test/eyelang/conformance/expected/029_arithmetic_and_comparison.pl +0 -9
  306. package/test/eyelang/conformance/expected/030_strings_and_atoms.pl +0 -2
  307. package/test/eyelang/conformance/expected/031_lists_aggregation_ordering.pl +0 -9
  308. package/test/eyelang/conformance/expected/032_holds_parts.pl +0 -3
  309. package/test/eyelang/conformance/expected/033_negation_once_generators.pl +0 -2
  310. package/test/eyelang/conformance/expected/034_equality_and_inequality.pl +0 -4
  311. package/test/eyelang/conformance/expected/035_list_relations.pl +0 -4
  312. package/test/eyelang/conformance/expected/036_append_splits.pl +0 -3
  313. package/test/eyelang/conformance/expected/037_matching_and_comparison.pl +0 -5
  314. package/test/eyelang/conformance/expected/038_memoize_declaration.pl +0 -2
  315. package/test/eyelang/conformance/expected/039_numeric_functions.pl +0 -7
  316. package/test/eyelang/conformance/expected/040_between_enumeration.pl +0 -3
  317. package/test/eyelang/conformance/expected/041_smallest_divisor.pl +0 -1
  318. package/test/eyelang/conformance/expected/042_negation_filter.pl +0 -2
  319. package/test/eyelang/conformance/expected/043_once_user_predicate.pl +0 -1
  320. package/test/eyelang/conformance/expected/044_findall_user_goal.pl +0 -1
  321. package/test/eyelang/conformance/expected/045_sort_deduplicates_atoms.pl +0 -1
  322. package/test/eyelang/conformance/expected/046_append_bound_prefix_suffix.pl +0 -2
  323. package/test/eyelang/conformance/expected/047_nth0_index_generation.pl +0 -1
  324. package/test/eyelang/conformance/expected/048_set_nth0_edges.pl +0 -2
  325. package/test/eyelang/conformance/expected/049_select_duplicate_occurrences.pl +0 -2
  326. package/test/eyelang/conformance/expected/050_not_member_filter.pl +0 -1
  327. package/test/eyelang/conformance/expected/051_nested_holds_parts.pl +0 -3
  328. package/test/eyelang/conformance/expected/052_holds_member.pl +0 -2
  329. package/test/eyelang/conformance/expected/053_materialize_excludes_source_fact.pl +0 -1
  330. package/test/eyelang/conformance/expected/054_numeric_and_lexical_comparison.pl +0 -3
  331. package/test/eyelang/conformance/expected/055_string_matching_filters.pl +0 -2
  332. package/test/eyelang/conformance/expected/056_string_and_atom_concat.pl +0 -1
  333. package/test/eyelang/conformance/expected/057_countall_empty_and_nonempty.pl +0 -1
  334. package/test/eyelang/conformance/expected/058_sumall_numeric_template.pl +0 -1
  335. package/test/eyelang/conformance/expected/059_aggregate_min_template.pl +0 -1
  336. package/test/eyelang/conformance/expected/060_aggregate_max_compound_key.pl +0 -1
  337. package/test/eyelang/conformance/expected/061_date_difference.pl +0 -2
  338. package/test/eyelang/conformance/expected/062_reusable_numeric_builtins.pl +0 -8
  339. package/test/eyelang/conformance/expected/063_reusable_list_builtins.pl +0 -9
  340. package/test/eyelang/conformance/expected/064_reusable_string_builtins.pl +0 -10
  341. package/test/eyelang/conformance/expected/065_reusable_term_control_builtins.pl +0 -6
  342. package/test/eyelang/conformance/expected/066_numeric_edges.pl +0 -12
  343. package/test/eyelang/conformance/expected/067_list_edges.pl +0 -8
  344. package/test/eyelang/conformance/expected/068_list_generation_order.pl +0 -10
  345. package/test/eyelang/conformance/expected/069_list_summaries_and_sets.pl +0 -7
  346. package/test/eyelang/conformance/expected/070_matches_named_captures.pl +0 -1
  347. package/test/eyelang/conformance/expected/071_string_edges.pl +0 -8
  348. package/test/eyelang/conformance/expected/072_string_conversions.pl +0 -8
  349. package/test/eyelang/conformance/expected/073_term_introspection_edges.pl +0 -8
  350. package/test/eyelang/conformance/expected/074_forall_edges.pl +0 -5
  351. package/test/eyelang/conformance/expected/075_aggregation_edges.pl +0 -7
  352. package/test/eyelang/conformance/expected/076_composed_reusable_builtins.pl +0 -5
  353. package/test/eyelang/conformance/expected/077_recursive_path_with_lists.pl +0 -3
  354. package/test/eyelang/conformance/expected/078_mutual_recursion_with_arithmetic.pl +0 -7
  355. package/test/eyelang/conformance/expected/079_big_integer_arithmetic.pl +0 -6
  356. package/test/eyelang/conformance/expected/080_rounding_modes.pl +0 -8
  357. package/test/eyelang/conformance/expected/081_zero_safe_numeric_functions.pl +0 -7
  358. package/test/eyelang/conformance/expected/082_comparison_semantics.pl +0 -8
  359. package/test/eyelang/conformance/expected/083_between_modes_and_empty_ranges.pl +0 -8
  360. package/test/eyelang/conformance/expected/084_append_and_select_composition.pl +0 -10
  361. package/test/eyelang/conformance/expected/085_nth_and_update_edges.pl +0 -8
  362. package/test/eyelang/conformance/expected/086_slicing_pipeline.pl +0 -7
  363. package/test/eyelang/conformance/expected/087_sort_reverse_length.pl +0 -6
  364. package/test/eyelang/conformance/expected/088_list_summaries_failures.pl +0 -6
  365. package/test/eyelang/conformance/expected/089_string_split_join_pipeline.pl +0 -4
  366. package/test/eyelang/conformance/expected/090_string_substring_replace_edges.pl +0 -7
  367. package/test/eyelang/conformance/expected/091_string_case_and_trim.pl +0 -5
  368. package/test/eyelang/conformance/expected/092_scalar_string_conversions.pl +0 -7
  369. package/test/eyelang/conformance/expected/093_regex_named_captures_context.pl +0 -5
  370. package/test/eyelang/conformance/expected/094_context_holds_enumeration.pl +0 -8
  371. package/test/eyelang/conformance/expected/095_term_introspection_roundtrip.pl +0 -6
  372. package/test/eyelang/conformance/expected/096_functor_scalar_edges.pl +0 -6
  373. package/test/eyelang/conformance/expected/097_control_negation_once_forall.pl +0 -5
  374. package/test/eyelang/conformance/expected/098_aggregation_nested_templates.pl +0 -5
  375. package/test/eyelang/conformance/expected/099_materialize_multiple_arities.pl +0 -4
  376. package/test/eyelang/conformance/expected/100_reusable_builtin_workflow.pl +0 -6
  377. package/test/eyelang/conformance/expected/core/001_fact_output.out +0 -1
  378. package/test/eyelang/conformance/expected/core/002_rule_recursion.out +0 -2
  379. package/test/eyelang/conformance/expected/core/003_terms_and_readback.out +0 -13
  380. package/test/eyelang/conformance/expected/core/004_conjunction_and_parentheses.out +0 -1
  381. package/test/eyelang/conformance/expected/core/005_list_deconstruction.out +0 -2
  382. package/test/eyelang/conformance/expected/core/006_comma_formula_data.out +0 -1
  383. package/test/eyelang/conformance/expected/core/007_anonymous_variables.out +0 -1
  384. package/test/eyelang/conformance/expected/core/008_graphic_atoms.out +0 -3
  385. package/test/eyelang/conformance/expected/core/009_comments_and_whitespace.out +0 -2
  386. package/test/eyelang/conformance/expected/core/010_variable_scope_and_reuse.out +0 -2
  387. package/test/eyelang/conformance/expected/core/011_predicate_arity.out +0 -2
  388. package/test/eyelang/conformance/expected/core/012_nested_compound_unification.out +0 -2
  389. package/test/eyelang/conformance/expected/core/013_multiple_clauses_order.out +0 -2
  390. package/test/eyelang/conformance/expected/core/014_failure_filters_answers.out +0 -1
  391. package/test/eyelang/conformance/expected/core/015_improper_list_unification.out +0 -3
  392. package/test/eyelang/conformance/expected/core/016_zero_arity_compound.out +0 -1
  393. package/test/eyelang/conformance/expected/core/017_three_step_recursion.out +0 -3
  394. package/test/eyelang/conformance/expected/core/018_quoted_atom_readback.out +0 -3
  395. package/test/eyelang/conformance/expected/core/019_parenthesized_three_conjuncts.out +0 -1
  396. package/test/eyelang/conformance/expected/core/020_nested_list_terms.out +0 -2
  397. package/test/eyelang/conformance/expected/core/021_repeated_variable_head.out +0 -2
  398. package/test/eyelang/conformance/expected/core/022_rule_head_structure.out +0 -2
  399. package/test/eyelang/conformance/expected/core/023_quoted_escapes_readback.out +0 -2
  400. package/test/eyelang/conformance/expected/core/024_numeric_literal_readback.out +0 -3
  401. package/test/eyelang/conformance/expected/core/025_body_parentheses_with_formula_data.out +0 -1
  402. package/test/eyelang/conformance/expected/core/026_underscore_named_variable_reuse.out +0 -1
  403. package/test/eyelang/conformance/expected/extension/001_default_derived_output.out +0 -3
  404. package/test/eyelang/conformance/expected/extension/002_materialize_focus.out +0 -1
  405. package/test/eyelang/conformance/expected/extension/003_arithmetic_and_comparison.out +0 -9
  406. package/test/eyelang/conformance/expected/extension/004_strings_and_atoms.out +0 -2
  407. package/test/eyelang/conformance/expected/extension/005_lists_aggregation_ordering.out +0 -9
  408. package/test/eyelang/conformance/expected/extension/006_holds_parts.out +0 -3
  409. package/test/eyelang/conformance/expected/extension/007_negation_once_generators.out +0 -2
  410. package/test/eyelang/conformance/expected/extension/008_equality_and_inequality.out +0 -4
  411. package/test/eyelang/conformance/expected/extension/009_list_relations.out +0 -4
  412. package/test/eyelang/conformance/expected/extension/010_append_splits.out +0 -3
  413. package/test/eyelang/conformance/expected/extension/011_matching_and_comparison.out +0 -5
  414. package/test/eyelang/conformance/expected/extension/012_memoize_declaration.out +0 -2
  415. package/test/eyelang/conformance/expected/extension/013_numeric_functions.out +0 -7
  416. package/test/eyelang/conformance/expected/extension/014_between_enumeration.out +0 -3
  417. package/test/eyelang/conformance/expected/extension/015_smallest_divisor.out +0 -1
  418. package/test/eyelang/conformance/expected/extension/016_negation_filter.out +0 -2
  419. package/test/eyelang/conformance/expected/extension/017_once_user_predicate.out +0 -1
  420. package/test/eyelang/conformance/expected/extension/018_findall_user_goal.out +0 -1
  421. package/test/eyelang/conformance/expected/extension/019_sort_deduplicates_atoms.out +0 -1
  422. package/test/eyelang/conformance/expected/extension/020_append_bound_prefix_suffix.out +0 -2
  423. package/test/eyelang/conformance/expected/extension/021_nth0_index_generation.out +0 -1
  424. package/test/eyelang/conformance/expected/extension/022_set_nth0_edges.out +0 -2
  425. package/test/eyelang/conformance/expected/extension/023_select_duplicate_occurrences.out +0 -2
  426. package/test/eyelang/conformance/expected/extension/024_not_member_filter.out +0 -1
  427. package/test/eyelang/conformance/expected/extension/026_nested_holds_parts.out +0 -3
  428. package/test/eyelang/conformance/expected/extension/027_holds_member.out +0 -2
  429. package/test/eyelang/conformance/expected/extension/027_materialize_excludes_source_fact.out +0 -1
  430. package/test/eyelang/conformance/expected/extension/028_numeric_and_lexical_comparison.out +0 -3
  431. package/test/eyelang/conformance/expected/extension/029_string_matching_filters.out +0 -2
  432. package/test/eyelang/conformance/expected/extension/030_string_and_atom_concat.out +0 -1
  433. package/test/eyelang/conformance/expected/extension/031_countall_empty_and_nonempty.out +0 -1
  434. package/test/eyelang/conformance/expected/extension/032_sumall_numeric_template.out +0 -1
  435. package/test/eyelang/conformance/expected/extension/033_aggregate_min_template.out +0 -1
  436. package/test/eyelang/conformance/expected/extension/034_aggregate_max_compound_key.out +0 -1
  437. package/test/eyelang/conformance/expected/extension/035_date_difference.out +0 -2
  438. package/test/eyelang/conformance/expected/extension/036_reusable_numeric_builtins.out +0 -8
  439. package/test/eyelang/conformance/expected/extension/037_reusable_list_builtins.out +0 -9
  440. package/test/eyelang/conformance/expected/extension/038_reusable_string_builtins.out +0 -10
  441. package/test/eyelang/conformance/expected/extension/039_reusable_term_control_builtins.out +0 -6
  442. package/test/eyelang/conformance/expected/extension/044_matches_named_captures.out +0 -1
  443. package/test/eyelang/run-all.mjs +0 -20
  444. package/test/eyelang/run-conformance.mjs +0 -78
  445. package/test/eyelang/run-examples.mjs +0 -125
  446. package/test/eyelang/run-regression.mjs +0 -612
  447. package/test/eyelang/test-style.mjs +0 -94
  448. package/test/eyelang.test.js +0 -58
package/eyeling.js CHANGED
@@ -6242,7 +6242,7 @@ function runParsedDocumentOnce(mergedDocument, { rdfMode = false, outputPrefixes
6242
6242
  let outTriples = [];
6243
6243
  let queryDerived = [];
6244
6244
  if (hasQueries) {
6245
- const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, { prefixes });
6245
+ const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, null, { captureExplanations: false, prefixes });
6246
6246
  derived = res.derived;
6247
6247
  outTriples = res.queryTriples;
6248
6248
  queryDerived = res.queryDerived || [];
@@ -6929,7 +6929,7 @@ function factsContainOutputStrings(triplesForOutput) {
6929
6929
  let outDerived = [];
6930
6930
 
6931
6931
  if (hasQueries) {
6932
- const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, { prefixes });
6932
+ const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, null, { captureExplanations: engine.getProofCommentsEnabled(), prefixes });
6933
6933
  derived = res.derived;
6934
6934
  outTriples = res.queryTriples;
6935
6935
  outDerived = res.queryDerived;
@@ -7507,6 +7507,7 @@ const LOG_COLLECT_ALL_IN_IRI = LOG_NS + 'collectAllIn';
7507
7507
  const LOG_FOR_ALL_IN_IRI = LOG_NS + 'forAllIn';
7508
7508
  const LOG_INCLUDES_IRI = LOG_NS + 'includes';
7509
7509
  const LOG_NOT_INCLUDES_IRI = LOG_NS + 'notIncludes';
7510
+ const LOG_MEMOIZE_IRI = LOG_NS + 'memoize';
7510
7511
  const LOG_IMPLIES_IRI = LOG_NS + 'implies';
7511
7512
  const LOG_IMPLIED_BY_IRI = LOG_NS + 'impliedBy';
7512
7513
 
@@ -7608,6 +7609,7 @@ const FACT_INDEX_ARRAY_MAP_FIELDS = ['__byPred', '__byPNonFastS', '__byPNonFastO
7608
7609
  const FACT_INDEX_NESTED_ARRAY_MAP_FIELDS = ['__byPS', '__byPO'];
7609
7610
  const FACT_INDEX_MAP_FIELDS = FACT_INDEX_ARRAY_MAP_FIELDS.concat(FACT_INDEX_NESTED_ARRAY_MAP_FIELDS);
7610
7611
  const FACT_INDEX_REQUIRED_FIELDS = FACT_INDEX_ARRAY_FIELDS.concat(FACT_INDEX_MAP_FIELDS, ['__keySet']);
7612
+ const FACT_INDEX_ALL_FIELDS = FACT_INDEX_REQUIRED_FIELDS.concat(['__keySetComplete']);
7611
7613
 
7612
7614
  let version = 'dev';
7613
7615
  try {
@@ -8675,7 +8677,13 @@ function termLookupKey(t) {
8675
8677
  return t.__tid;
8676
8678
  }
8677
8679
  if (t instanceof Blank) return t.__tid;
8678
- if (t instanceof Literal) return literalLookupKey(t);
8680
+ if (t instanceof Literal) {
8681
+ const cached = t.__lookupKey;
8682
+ if (cached !== undefined) return cached;
8683
+ const key = literalLookupKey(t);
8684
+ Object.defineProperty(t, '__lookupKey', { value: key, enumerable: false });
8685
+ return key;
8686
+ }
8679
8687
 
8680
8688
  if (t instanceof ListTerm) {
8681
8689
  const cached = t.__lookupKey;
@@ -8713,6 +8721,13 @@ function tripleFastKey(tr) {
8713
8721
  return ks + '\t' + kp + '\t' + ko;
8714
8722
  }
8715
8723
 
8724
+ function resetFactIndexes(facts) {
8725
+ if (!facts) return;
8726
+ for (const name of FACT_INDEX_ALL_FIELDS) {
8727
+ try { delete facts[name]; } catch {}
8728
+ }
8729
+ }
8730
+
8716
8731
  function ensureFactIndexes(facts) {
8717
8732
  if (FACT_INDEX_REQUIRED_FIELDS.every((name) => facts[name])) return;
8718
8733
 
@@ -9143,6 +9158,157 @@ function isLogImpliedBy(p) {
9143
9158
  return p instanceof Iri && p.value === LOG_IMPLIED_BY_IRI;
9144
9159
  }
9145
9160
 
9161
+ function isLogMemoize(p) {
9162
+ return p instanceof Iri && p.value === LOG_MEMOIZE_IRI;
9163
+ }
9164
+
9165
+ function isTruthyMemoizeObject(o) {
9166
+ if (!(o instanceof Literal)) return false;
9167
+ if (o.value === 'true') return true;
9168
+ const info = parseBooleanLiteralInfo(o);
9169
+ return !!(info && info.value === true);
9170
+ }
9171
+
9172
+ // ===========================================================================
9173
+ // Predicate memoization declarations
9174
+ // ===========================================================================
9175
+ //
9176
+ // Eyeling accepts top-level declarations of the form:
9177
+ // :predicate log:memoize true.
9178
+ // They are engine directives, not data facts. Each declaration asks the
9179
+ // backward prover to table completed answers for that predicate during the
9180
+ // current reasoning scope. The hint is deliberately predicate-local and
9181
+ // conservative: unbound calls and finite-result probes still use the normal
9182
+ // path, and cached answers are invalidated when the fact/rule scope changes.
9183
+
9184
+ function __extractLogMemoizeDeclarations(facts) {
9185
+ const memoized = new Set();
9186
+ if (!Array.isArray(facts) || facts.length === 0) return memoized;
9187
+
9188
+ let write = 0;
9189
+ let removed = false;
9190
+ for (let read = 0; read < facts.length; read++) {
9191
+ const tr = facts[read];
9192
+ if (tr && isLogMemoize(tr.p) && tr.s instanceof Iri && isTruthyMemoizeObject(tr.o)) {
9193
+ memoized.add(tr.s.__tid);
9194
+ removed = true;
9195
+ continue;
9196
+ }
9197
+ if (write !== read) facts[write] = tr;
9198
+ write++;
9199
+ }
9200
+
9201
+ if (removed) {
9202
+ facts.length = write;
9203
+ resetFactIndexes(facts);
9204
+ }
9205
+ return memoized;
9206
+ }
9207
+
9208
+ function __attachMemoizedPredicates(scopeCarrier, memoized) {
9209
+ if (!scopeCarrier || !memoized || memoized.size === 0) return;
9210
+ __setHiddenWritable(scopeCarrier, 'memoizedPredicates', memoized);
9211
+ }
9212
+
9213
+ function __memoizedPredicateSet(facts, backRules) {
9214
+ return (facts && facts.memoizedPredicates) || (backRules && backRules.memoizedPredicates) || null;
9215
+ }
9216
+
9217
+ function __predicateIsMemoized(facts, backRules, p) {
9218
+ if (!(p instanceof Iri)) return false;
9219
+ const memoized = __memoizedPredicateSet(facts, backRules);
9220
+ return !!(memoized && memoized.has(p.__tid));
9221
+ }
9222
+
9223
+ function __makePredicateMemoTable() {
9224
+ return {
9225
+ scopeVersion: null,
9226
+ entries: new Map(),
9227
+ };
9228
+ }
9229
+
9230
+ function __ensurePredicateMemoTable(facts, backRules) {
9231
+ let table = (facts && facts.predicateMemoTable) || (backRules && backRules.predicateMemoTable) || null;
9232
+ if (!table) table = __makePredicateMemoTable();
9233
+ __setHiddenWritable(facts, 'predicateMemoTable', table);
9234
+ __setHiddenWritable(backRules, 'predicateMemoTable', table);
9235
+
9236
+ const version = goalTableScopeVersion(facts, backRules);
9237
+ if (table.scopeVersion !== version) {
9238
+ table.scopeVersion = version;
9239
+ table.entries.clear();
9240
+ }
9241
+ return table;
9242
+ }
9243
+
9244
+ function __memoKeyPart(t) {
9245
+ if (__termHasVarOrBlank(t)) return { bound: false, text: '_' };
9246
+ const fast = termLookupKey(t);
9247
+ if (fast !== null) return { bound: true, text: encodeLookupKeyPart(fast) };
9248
+ return { bound: true, text: skolemKeyFromTerm(t) };
9249
+ }
9250
+
9251
+ function __predicateMemoKey(goal) {
9252
+ if (!(goal && goal.p instanceof Iri)) return null;
9253
+ const sPart = __memoKeyPart(goal.s);
9254
+ const oPart = __memoKeyPart(goal.o);
9255
+ if (!sPart.bound && !oPart.bound) return null;
9256
+ return `${goal.p.__tid}|${sPart.text}|${oPart.text}`;
9257
+ }
9258
+
9259
+ function __makePredicateMemoEntry() {
9260
+ return {
9261
+ computing: false,
9262
+ complete: false,
9263
+ unsafe: false,
9264
+ answers: [],
9265
+ answerKeys: new Set(),
9266
+ };
9267
+ }
9268
+
9269
+ function __getPredicateMemoEntry(facts, backRules, key) {
9270
+ const table = __ensurePredicateMemoTable(facts, backRules);
9271
+ let entry = table.entries.get(key);
9272
+ if (!entry) {
9273
+ entry = __makePredicateMemoEntry();
9274
+ table.entries.set(key, entry);
9275
+ }
9276
+ return entry;
9277
+ }
9278
+
9279
+ function __canStorePredicateMemo(maxResults) {
9280
+ return !(typeof maxResults === 'number' && maxResults > 0);
9281
+ }
9282
+
9283
+ function __canMemoizeAnswerTerm(t) {
9284
+ if (t instanceof Var || t instanceof OpenListTerm) return false;
9285
+ if (t instanceof ListTerm) return t.elems.every(__canMemoizeAnswerTerm);
9286
+ if (t instanceof GraphTerm) return t.triples.every((tr) => __canMemoizeAnswerTerm(tr.s) && __canMemoizeAnswerTerm(tr.p) && __canMemoizeAnswerTerm(tr.o));
9287
+ return true;
9288
+ }
9289
+
9290
+ function __memoAnswerKeyPart(t) {
9291
+ const fast = termLookupKey(t);
9292
+ if (fast !== null) return encodeLookupKeyPart(fast);
9293
+ return skolemKeyFromTerm(t);
9294
+ }
9295
+
9296
+ function __memoAnswerKey(tr) {
9297
+ return __memoAnswerKeyPart(tr.s) + '\t' + __memoAnswerKeyPart(tr.p) + '\t' + __memoAnswerKeyPart(tr.o);
9298
+ }
9299
+
9300
+ function __storePredicateMemoAnswer(entry, rawGoal, subst) {
9301
+ const answer = applySubstTriple(rawGoal, subst || {});
9302
+ if (!__canMemoizeAnswerTerm(answer.s) || !__canMemoizeAnswerTerm(answer.p) || !__canMemoizeAnswerTerm(answer.o)) {
9303
+ entry.unsafe = true;
9304
+ return;
9305
+ }
9306
+ const key = __memoAnswerKey(answer);
9307
+ if (entry.answerKeys.has(key)) return;
9308
+ entry.answerKeys.add(key);
9309
+ entry.answers.push(answer);
9310
+ }
9311
+
9146
9312
  // ===========================================================================
9147
9313
  // Completed-goal answer tables (minimal tabling)
9148
9314
  // ===========================================================================
@@ -10056,6 +10222,47 @@ function proveGoals(goals, subst, facts, backRules, depth, visited, varGen, maxR
10056
10222
  continue;
10057
10223
  }
10058
10224
 
10225
+ if (frame.kind === 'memoComplete') {
10226
+ frame.entry.computing = false;
10227
+ if (frame.entry.unsafe) {
10228
+ frame.table.entries.delete(frame.key);
10229
+ } else {
10230
+ frame.entry.complete = true;
10231
+ }
10232
+ continue;
10233
+ }
10234
+
10235
+ if (frame.kind === 'memoAnswerIter') {
10236
+ const answers = frame.entry.answers;
10237
+ while (frame.idx < answers.length && results.length < max) {
10238
+ const answer = answers[frame.idx++];
10239
+ const mark = trail.length;
10240
+ if (!unifyTripleTrail(frame.goal0, answer)) {
10241
+ undoTo(mark);
10242
+ continue;
10243
+ }
10244
+
10245
+ if (!frame.restGoals.length) {
10246
+ results.push(gcCompactForGoals(substMut, [], answerVars));
10247
+ undoTo(mark);
10248
+ if (results.length >= max) return results;
10249
+ continue;
10250
+ }
10251
+
10252
+ stack.push(frame);
10253
+ stack.push({ kind: 'undo', substMark: mark, visitedMark: visitedTrail.length });
10254
+ stack.push({
10255
+ kind: 'node',
10256
+ goalsNow: frame.restGoals,
10257
+ curDepth: frame.curDepth + 1,
10258
+ canDeferBuiltins: frame.canDeferBuiltins,
10259
+ deferCount: 0,
10260
+ });
10261
+ break;
10262
+ }
10263
+ continue;
10264
+ }
10265
+
10059
10266
  if (frame.kind === 'deltaIter') {
10060
10267
  const deltas = frame.deltas;
10061
10268
  while (frame.idx < deltas.length && results.length < max) {
@@ -10197,7 +10404,21 @@ function proveGoals(goals, subst, facts, backRules, depth, visited, varGen, maxR
10197
10404
  }
10198
10405
 
10199
10406
  const rawGoal = goalsNow[0];
10200
- const restGoals = goalsNow.length > 1 ? goalsNow.slice(1) : [];
10407
+ let restGoals = goalsNow.length > 1 ? goalsNow.slice(1) : [];
10408
+
10409
+ if (rawGoal && rawGoal.__kind === 'memoStore') {
10410
+ __storePredicateMemoAnswer(rawGoal.entry, rawGoal.goal, substMut);
10411
+ if (rawGoal.stop && restGoals.length === 0) continue;
10412
+ stack.push({
10413
+ kind: 'node',
10414
+ goalsNow: restGoals,
10415
+ curDepth: frame.curDepth,
10416
+ canDeferBuiltins: frame.canDeferBuiltins,
10417
+ deferCount: 0,
10418
+ });
10419
+ continue;
10420
+ }
10421
+
10201
10422
  const goal0 = applySubstTriple(rawGoal, substMut);
10202
10423
 
10203
10424
  // 1) Builtins
@@ -10293,8 +10514,46 @@ function proveGoals(goals, subst, facts, backRules, depth, visited, varGen, maxR
10293
10514
  const goalKey = tripleKeyForVisited(goal0);
10294
10515
  const goalWasVisited = visitedCounts.has(goalKey);
10295
10516
 
10517
+ let memoCompleteFrame = null;
10518
+ let memoReplayFrame = null;
10519
+ if (__predicateIsMemoized(facts, backRules, goal0.p)) {
10520
+ const memoKey = __predicateMemoKey(goal0);
10521
+ if (memoKey !== null) {
10522
+ const memoEntry = __getPredicateMemoEntry(facts, backRules, memoKey);
10523
+ if (memoEntry.complete) {
10524
+ stack.push({
10525
+ kind: 'memoAnswerIter',
10526
+ entry: memoEntry,
10527
+ idx: 0,
10528
+ goal0,
10529
+ restGoals,
10530
+ curDepth: frame.curDepth,
10531
+ canDeferBuiltins: frame.canDeferBuiltins,
10532
+ });
10533
+ continue;
10534
+ }
10535
+ if (!memoEntry.computing && __canStorePredicateMemo(maxResults)) {
10536
+ memoEntry.computing = true;
10537
+ const table = __ensurePredicateMemoTable(facts, backRules);
10538
+ memoReplayFrame = {
10539
+ kind: 'memoAnswerIter',
10540
+ entry: memoEntry,
10541
+ idx: 0,
10542
+ goal0,
10543
+ restGoals,
10544
+ curDepth: frame.curDepth,
10545
+ canDeferBuiltins: frame.canDeferBuiltins,
10546
+ };
10547
+ memoCompleteFrame = { kind: 'memoComplete', entry: memoEntry, table, key: memoKey };
10548
+ restGoals = [{ __kind: 'memoStore', entry: memoEntry, goal: rawGoal, stop: true }];
10549
+ }
10550
+ }
10551
+ }
10552
+
10296
10553
  // 3) Backward rules (indexed by head predicate) — explored first
10297
10554
  if (goal0.p instanceof Iri) {
10555
+ if (memoReplayFrame) stack.push(memoReplayFrame);
10556
+ if (memoCompleteFrame) stack.push(memoCompleteFrame);
10298
10557
  ensureBackRuleIndexes(backRules);
10299
10558
  const candRules = (backRules.__byHeadPred.get(goal0.p.__tid) || []).concat(backRules.__wildHeadPred);
10300
10559
 
@@ -10326,6 +10585,8 @@ function proveGoals(goals, subst, facts, backRules, depth, visited, varGen, maxR
10326
10585
  });
10327
10586
  }
10328
10587
  } else {
10588
+ if (memoReplayFrame) stack.push(memoReplayFrame);
10589
+ if (memoCompleteFrame) stack.push(memoCompleteFrame);
10329
10590
  // No IRI predicate: rule indexing doesn't apply; only try all facts.
10330
10591
  stack.push({
10331
10592
  kind: 'factIter',
@@ -10531,6 +10792,10 @@ function __exitReasoning(code, message /* optional */) {
10531
10792
  function forwardChain(facts, forwardRules, backRules, onDerived /* optional */, opts = {}) {
10532
10793
  enterReasoningRun();
10533
10794
  try {
10795
+ const memoizedPredicates = __extractLogMemoizeDeclarations(facts);
10796
+ __attachMemoizedPredicates(facts, memoizedPredicates);
10797
+ __attachMemoizedPredicates(backRules, memoizedPredicates);
10798
+
10534
10799
  ensureFactIndexes(facts);
10535
10800
  ensureBackRuleIndexes(backRules);
10536
10801
 
@@ -11169,7 +11434,7 @@ function reasonStream(input, opts = {}) {
11169
11434
  if (Array.isArray(logQueryRules) && logQueryRules.length) {
11170
11435
  // Query-selection mode: derive full closure, then output only the unique
11171
11436
  // instantiated conclusion triples of the log:query directives.
11172
- const res = forwardChainAndCollectLogQueryConclusions(facts, frules, brules, logQueryRules, { prefixes });
11437
+ const res = forwardChainAndCollectLogQueryConclusions(facts, frules, brules, logQueryRules, null, { captureExplanations: proof, prefixes });
11173
11438
  derived = res.derived;
11174
11439
  queryTriples = res.queryTriples;
11175
11440
  queryDerived = res.queryDerived;
@@ -11203,7 +11468,7 @@ function reasonStream(input, opts = {}) {
11203
11468
  onDerived(payload);
11204
11469
  }
11205
11470
  },
11206
- { prefixes },
11471
+ { captureExplanations: proof, prefixes },
11207
11472
  );
11208
11473
  }
11209
11474
 
@@ -14850,7 +15115,7 @@ function parseN3Text(text, opts = {}) {
14850
15115
  }
14851
15116
 
14852
15117
  const tokens = lex(text, { rdf });
14853
- const parser = new Parser(tokens);
15118
+ const parser = new Parser(tokens, { sourceOffsets: sourceLocations });
14854
15119
  if (baseIri) parser.prefixes.setBase(baseIri);
14855
15120
  const [prefixes, triples, frules, brules, logQueryRules] = parser.parseDocument();
14856
15121
 
@@ -15125,7 +15390,7 @@ function annotateSourceOffset(obj, offset) {
15125
15390
  }
15126
15391
 
15127
15392
  class Parser {
15128
- constructor(tokens) {
15393
+ constructor(tokens, options = {}) {
15129
15394
  this.toks = tokens;
15130
15395
  this.pos = 0;
15131
15396
  this.prefixes = PrefixEnv.newDefault();
@@ -15139,6 +15404,7 @@ class Parser {
15139
15404
  // makes derived output read naturally, e.g. ':s :p _:b.' preceding
15140
15405
  // '_:b :q :r.'
15141
15406
  this.pendingTriplesAfter = [];
15407
+ this.trackSourceOffsets = !!(options && options.sourceOffsets);
15142
15408
  }
15143
15409
 
15144
15410
  peek() {
@@ -15151,6 +15417,10 @@ class Parser {
15151
15417
  return tok;
15152
15418
  }
15153
15419
 
15420
+ annotateSourceOffset(obj, offset) {
15421
+ return this.trackSourceOffsets ? annotateSourceOffset(obj, offset) : obj;
15422
+ }
15423
+
15154
15424
  fail(message, tok = this.peek()) {
15155
15425
  const off = tok && typeof tok.offset === 'number' ? tok.offset : null;
15156
15426
  throw new N3SyntaxError(message, off);
@@ -15255,12 +15525,12 @@ class Parser {
15255
15525
  this.next();
15256
15526
  const second = this.parseTerm();
15257
15527
  this.expectDot();
15258
- forwardRules.push(annotateSourceOffset(this.makeRule(first, second, true), statementOffset));
15528
+ forwardRules.push(this.annotateSourceOffset(this.makeRule(first, second, true), statementOffset));
15259
15529
  } else if (this.peek().typ === 'OpImpliedBy') {
15260
15530
  this.next();
15261
15531
  const second = this.parseTerm();
15262
15532
  this.expectDot();
15263
- backwardRules.push(annotateSourceOffset(this.makeRule(first, second, false), statementOffset));
15533
+ backwardRules.push(this.annotateSourceOffset(this.makeRule(first, second, false), statementOffset));
15264
15534
  } else {
15265
15535
  let more;
15266
15536
 
@@ -15279,16 +15549,16 @@ class Parser {
15279
15549
 
15280
15550
  // normalize explicit log:implies / log:impliedBy at top-level
15281
15551
  for (const tr0 of more) {
15282
- const tr = annotateSourceOffset(tr0, statementOffset);
15552
+ const tr = this.annotateSourceOffset(tr0, statementOffset);
15283
15553
  if (isLogImplies(tr.p) && tr.s instanceof GraphTerm && tr.o instanceof GraphTerm) {
15284
- forwardRules.push(annotateSourceOffset(this.makeRule(tr.s, tr.o, true), statementOffset));
15554
+ forwardRules.push(this.annotateSourceOffset(this.makeRule(tr.s, tr.o, true), statementOffset));
15285
15555
  } else if (isLogImpliedBy(tr.p) && tr.s instanceof GraphTerm && tr.o instanceof GraphTerm) {
15286
- backwardRules.push(annotateSourceOffset(this.makeRule(tr.s, tr.o, false), statementOffset));
15556
+ backwardRules.push(this.annotateSourceOffset(this.makeRule(tr.s, tr.o, false), statementOffset));
15287
15557
  } else if (isLogQuery(tr.p) && tr.s instanceof GraphTerm && tr.o instanceof GraphTerm) {
15288
15558
  // Output-selection directive: { premise } log:query { conclusion }.
15289
15559
  // When present at top-level, eyeling prints only the instantiated conclusion
15290
15560
  // triples (unique) instead of all newly derived facts.
15291
- logQueries.push(annotateSourceOffset(this.makeRule(tr.s, tr.o, true), statementOffset));
15561
+ logQueries.push(this.annotateSourceOffset(this.makeRule(tr.s, tr.o, true), statementOffset));
15292
15562
  } else {
15293
15563
  triples.push(tr);
15294
15564
  }
package/lib/cli.js CHANGED
@@ -564,7 +564,7 @@ function runParsedDocumentOnce(mergedDocument, { rdfMode = false, outputPrefixes
564
564
  let outTriples = [];
565
565
  let queryDerived = [];
566
566
  if (hasQueries) {
567
- const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, { prefixes });
567
+ const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, null, { captureExplanations: false, prefixes });
568
568
  derived = res.derived;
569
569
  outTriples = res.queryTriples;
570
570
  queryDerived = res.queryDerived || [];
@@ -1251,7 +1251,7 @@ function factsContainOutputStrings(triplesForOutput) {
1251
1251
  let outDerived = [];
1252
1252
 
1253
1253
  if (hasQueries) {
1254
- const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, { prefixes });
1254
+ const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, null, { captureExplanations: engine.getProofCommentsEnabled(), prefixes });
1255
1255
  derived = res.derived;
1256
1256
  outTriples = res.queryTriples;
1257
1257
  outDerived = res.queryDerived;