eyeling 1.34.4 → 1.34.5

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 (252) hide show
  1. package/docs/eyelang-guide.md +1 -1
  2. package/docs/eyelang-language-reference.md +16 -31
  3. package/package.json +1 -1
  4. package/test/eyelang/conformance/README.md +9 -11
  5. package/test/eyelang/conformance/cases/001_fact_output.pl +4 -0
  6. package/test/eyelang/conformance/cases/002_rule_recursion.pl +7 -0
  7. package/test/eyelang/conformance/cases/002_rule_recursion.query +1 -0
  8. package/test/eyelang/conformance/cases/003_terms_and_readback.pl +16 -0
  9. package/test/eyelang/conformance/cases/003_terms_and_readback.query +1 -0
  10. package/test/eyelang/conformance/cases/004_conjunction_and_parentheses.pl +5 -0
  11. package/test/eyelang/conformance/cases/004_conjunction_and_parentheses.query +1 -0
  12. package/test/eyelang/conformance/cases/005_list_deconstruction.pl +6 -0
  13. package/test/eyelang/conformance/cases/005_list_deconstruction.query +1 -0
  14. package/test/eyelang/conformance/cases/006_comma_formula_data.pl +4 -0
  15. package/test/eyelang/conformance/cases/006_comma_formula_data.query +1 -0
  16. package/test/eyelang/conformance/cases/007_anonymous_variables.pl +5 -0
  17. package/test/eyelang/conformance/cases/007_anonymous_variables.query +1 -0
  18. package/test/eyelang/conformance/cases/008_graphic_atoms.pl +6 -0
  19. package/test/eyelang/conformance/cases/008_graphic_atoms.query +1 -0
  20. package/test/eyelang/conformance/cases/009_comments_and_whitespace.pl +5 -0
  21. package/test/eyelang/conformance/cases/009_comments_and_whitespace.query +1 -0
  22. package/test/eyelang/conformance/cases/010_variable_scope_and_reuse.pl +8 -0
  23. package/test/eyelang/conformance/cases/010_variable_scope_and_reuse.query +1 -0
  24. package/test/eyelang/conformance/cases/011_predicate_arity.pl +6 -0
  25. package/test/eyelang/conformance/cases/011_predicate_arity.query +1 -0
  26. package/test/eyelang/conformance/cases/012_nested_compound_unification.pl +5 -0
  27. package/test/eyelang/conformance/cases/012_nested_compound_unification.query +1 -0
  28. package/test/eyelang/conformance/cases/013_multiple_clauses_order.pl +6 -0
  29. package/test/eyelang/conformance/cases/013_multiple_clauses_order.query +1 -0
  30. package/test/eyelang/conformance/cases/014_failure_filters_answers.pl +7 -0
  31. package/test/eyelang/conformance/cases/014_failure_filters_answers.query +1 -0
  32. package/test/eyelang/conformance/cases/015_improper_list_unification.pl +6 -0
  33. package/test/eyelang/conformance/cases/015_improper_list_unification.query +1 -0
  34. package/test/eyelang/conformance/cases/016_zero_arity_compound.pl +4 -0
  35. package/test/eyelang/conformance/cases/016_zero_arity_compound.query +1 -0
  36. package/test/eyelang/conformance/cases/017_three_step_recursion.pl +8 -0
  37. package/test/eyelang/conformance/cases/017_three_step_recursion.query +1 -0
  38. package/test/eyelang/conformance/cases/018_quoted_atom_readback.pl +6 -0
  39. package/test/eyelang/conformance/cases/018_quoted_atom_readback.query +1 -0
  40. package/test/eyelang/conformance/cases/019_parenthesized_three_conjuncts.pl +7 -0
  41. package/test/eyelang/conformance/cases/019_parenthesized_three_conjuncts.query +1 -0
  42. package/test/eyelang/conformance/cases/020_nested_list_terms.pl +5 -0
  43. package/test/eyelang/conformance/cases/020_nested_list_terms.query +1 -0
  44. package/test/eyelang/conformance/cases/021_repeated_variable_head.pl +7 -0
  45. package/test/eyelang/conformance/cases/022_rule_head_structure.pl +5 -0
  46. package/test/eyelang/conformance/cases/023_quoted_escapes_readback.pl +5 -0
  47. package/test/eyelang/conformance/cases/024_numeric_literal_readback.pl +6 -0
  48. package/test/eyelang/conformance/cases/025_body_parentheses_with_formula_data.pl +5 -0
  49. package/test/eyelang/conformance/cases/026_underscore_named_variable_reuse.pl +5 -0
  50. package/test/eyelang/conformance/cases/027_default_derived_output.pl +5 -0
  51. package/test/eyelang/conformance/cases/028_materialize_focus.pl +5 -0
  52. package/test/eyelang/conformance/cases/029_arithmetic_and_comparison.pl +11 -0
  53. package/test/eyelang/conformance/cases/029_arithmetic_and_comparison.query +1 -0
  54. package/test/eyelang/conformance/cases/030_strings_and_atoms.pl +4 -0
  55. package/test/eyelang/conformance/cases/030_strings_and_atoms.query +1 -0
  56. package/test/eyelang/conformance/cases/031_lists_aggregation_ordering.pl +10 -0
  57. package/test/eyelang/conformance/cases/031_lists_aggregation_ordering.query +1 -0
  58. package/test/eyelang/conformance/cases/032_holds_parts.pl +4 -0
  59. package/test/eyelang/conformance/cases/033_negation_once_generators.pl +7 -0
  60. package/test/eyelang/conformance/cases/033_negation_once_generators.query +1 -0
  61. package/test/eyelang/conformance/cases/034_equality_and_inequality.pl +6 -0
  62. package/test/eyelang/conformance/cases/034_equality_and_inequality.query +1 -0
  63. package/test/eyelang/conformance/cases/035_list_relations.pl +5 -0
  64. package/test/eyelang/conformance/cases/035_list_relations.query +1 -0
  65. package/test/eyelang/conformance/cases/036_append_splits.pl +3 -0
  66. package/test/eyelang/conformance/cases/036_append_splits.query +1 -0
  67. package/test/eyelang/conformance/cases/037_matching_and_comparison.pl +7 -0
  68. package/test/eyelang/conformance/cases/037_matching_and_comparison.query +1 -0
  69. package/test/eyelang/conformance/cases/038_memoize_declaration.pl +8 -0
  70. package/test/eyelang/conformance/cases/038_memoize_declaration.query +1 -0
  71. package/test/eyelang/conformance/cases/039_numeric_functions.pl +9 -0
  72. package/test/eyelang/conformance/cases/039_numeric_functions.query +1 -0
  73. package/test/eyelang/conformance/cases/040_between_enumeration.pl +3 -0
  74. package/test/eyelang/conformance/cases/040_between_enumeration.query +1 -0
  75. package/test/eyelang/conformance/cases/041_smallest_divisor.pl +3 -0
  76. package/test/eyelang/conformance/cases/041_smallest_divisor.query +1 -0
  77. package/test/eyelang/conformance/cases/042_negation_filter.pl +7 -0
  78. package/test/eyelang/conformance/cases/042_negation_filter.query +1 -0
  79. package/test/eyelang/conformance/cases/043_once_user_predicate.pl +5 -0
  80. package/test/eyelang/conformance/cases/043_once_user_predicate.query +1 -0
  81. package/test/eyelang/conformance/cases/044_findall_user_goal.pl +6 -0
  82. package/test/eyelang/conformance/cases/044_findall_user_goal.query +1 -0
  83. package/test/eyelang/conformance/cases/045_sort_deduplicates_atoms.pl +3 -0
  84. package/test/eyelang/conformance/cases/045_sort_deduplicates_atoms.query +1 -0
  85. package/test/eyelang/conformance/cases/046_append_bound_prefix_suffix.pl +4 -0
  86. package/test/eyelang/conformance/cases/046_append_bound_prefix_suffix.query +1 -0
  87. package/test/eyelang/conformance/cases/047_nth0_index_generation.pl +3 -0
  88. package/test/eyelang/conformance/cases/047_nth0_index_generation.query +1 -0
  89. package/test/eyelang/conformance/cases/048_set_nth0_edges.pl +4 -0
  90. package/test/eyelang/conformance/cases/048_set_nth0_edges.query +1 -0
  91. package/test/eyelang/conformance/cases/049_select_duplicate_occurrences.pl +3 -0
  92. package/test/eyelang/conformance/cases/049_select_duplicate_occurrences.query +1 -0
  93. package/test/eyelang/conformance/cases/050_not_member_filter.pl +6 -0
  94. package/test/eyelang/conformance/cases/050_not_member_filter.query +1 -0
  95. package/test/eyelang/conformance/cases/051_nested_holds_parts.pl +4 -0
  96. package/test/eyelang/conformance/cases/052_holds_member.pl +3 -0
  97. package/test/eyelang/conformance/cases/053_materialize_excludes_source_fact.pl +6 -0
  98. package/test/eyelang/conformance/cases/054_numeric_and_lexical_comparison.pl +5 -0
  99. package/test/eyelang/conformance/cases/054_numeric_and_lexical_comparison.query +1 -0
  100. package/test/eyelang/conformance/cases/055_string_matching_filters.pl +6 -0
  101. package/test/eyelang/conformance/cases/055_string_matching_filters.query +1 -0
  102. package/test/eyelang/conformance/cases/056_string_and_atom_concat.pl +3 -0
  103. package/test/eyelang/conformance/cases/056_string_and_atom_concat.query +1 -0
  104. package/test/eyelang/conformance/cases/057_countall_empty_and_nonempty.pl +4 -0
  105. package/test/eyelang/conformance/cases/057_countall_empty_and_nonempty.query +1 -0
  106. package/test/eyelang/conformance/cases/058_sumall_numeric_template.pl +5 -0
  107. package/test/eyelang/conformance/cases/058_sumall_numeric_template.query +1 -0
  108. package/test/eyelang/conformance/cases/059_aggregate_min_template.pl +5 -0
  109. package/test/eyelang/conformance/cases/059_aggregate_min_template.query +1 -0
  110. package/test/eyelang/conformance/cases/060_aggregate_max_compound_key.pl +5 -0
  111. package/test/eyelang/conformance/cases/060_aggregate_max_compound_key.query +1 -0
  112. package/test/eyelang/conformance/cases/061_date_difference.pl +4 -0
  113. package/test/eyelang/conformance/cases/062_reusable_numeric_builtins.pl +10 -0
  114. package/test/eyelang/conformance/cases/063_reusable_list_builtins.pl +11 -0
  115. package/test/eyelang/conformance/cases/064_reusable_string_builtins.pl +12 -0
  116. package/test/eyelang/conformance/cases/065_reusable_term_control_builtins.pl +11 -0
  117. package/test/eyelang/conformance/cases/066_numeric_edges.pl +14 -0
  118. package/test/eyelang/conformance/cases/067_list_edges.pl +10 -0
  119. package/test/eyelang/conformance/cases/068_list_generation_order.pl +7 -0
  120. package/test/eyelang/conformance/cases/069_list_summaries_and_sets.pl +9 -0
  121. package/test/eyelang/conformance/cases/070_matches_named_captures.pl +13 -0
  122. package/test/eyelang/conformance/cases/071_string_edges.pl +10 -0
  123. package/test/eyelang/conformance/cases/072_string_conversions.pl +10 -0
  124. package/test/eyelang/conformance/cases/073_term_introspection_edges.pl +10 -0
  125. package/test/eyelang/conformance/cases/074_forall_edges.pl +10 -0
  126. package/test/eyelang/conformance/cases/075_aggregation_edges.pl +12 -0
  127. package/test/eyelang/conformance/cases/076_composed_reusable_builtins.pl +8 -0
  128. package/test/eyelang/conformance/cases/077_recursive_path_with_lists.pl +10 -0
  129. package/test/eyelang/conformance/cases/078_mutual_recursion_with_arithmetic.pl +7 -0
  130. package/test/eyelang/conformance/cases/079_big_integer_arithmetic.pl +8 -0
  131. package/test/eyelang/conformance/cases/080_rounding_modes.pl +10 -0
  132. package/test/eyelang/conformance/cases/081_zero_safe_numeric_functions.pl +9 -0
  133. package/test/eyelang/conformance/cases/082_comparison_semantics.pl +10 -0
  134. package/test/eyelang/conformance/cases/083_between_modes_and_empty_ranges.pl +8 -0
  135. package/test/eyelang/conformance/cases/084_append_and_select_composition.pl +7 -0
  136. package/test/eyelang/conformance/cases/085_nth_and_update_edges.pl +8 -0
  137. package/test/eyelang/conformance/cases/086_slicing_pipeline.pl +10 -0
  138. package/test/eyelang/conformance/cases/087_sort_reverse_length.pl +8 -0
  139. package/test/eyelang/conformance/cases/088_list_summaries_failures.pl +8 -0
  140. package/test/eyelang/conformance/cases/089_string_split_join_pipeline.pl +7 -0
  141. package/test/eyelang/conformance/cases/090_string_substring_replace_edges.pl +9 -0
  142. package/test/eyelang/conformance/cases/091_string_case_and_trim.pl +7 -0
  143. package/test/eyelang/conformance/cases/092_scalar_string_conversions.pl +9 -0
  144. package/test/eyelang/conformance/cases/093_regex_named_captures_context.pl +8 -0
  145. package/test/eyelang/conformance/cases/094_context_holds_enumeration.pl +7 -0
  146. package/test/eyelang/conformance/cases/095_term_introspection_roundtrip.pl +8 -0
  147. package/test/eyelang/conformance/cases/096_functor_scalar_edges.pl +8 -0
  148. package/test/eyelang/conformance/cases/097_control_negation_once_forall.pl +13 -0
  149. package/test/eyelang/conformance/cases/098_aggregation_nested_templates.pl +11 -0
  150. package/test/eyelang/conformance/cases/099_materialize_multiple_arities.pl +8 -0
  151. package/test/eyelang/conformance/cases/100_reusable_builtin_workflow.pl +10 -0
  152. package/test/eyelang/conformance/expected/001_fact_output.pl +1 -0
  153. package/test/eyelang/conformance/expected/002_rule_recursion.pl +2 -0
  154. package/test/eyelang/conformance/expected/003_terms_and_readback.pl +13 -0
  155. package/test/eyelang/conformance/expected/004_conjunction_and_parentheses.pl +1 -0
  156. package/test/eyelang/conformance/expected/005_list_deconstruction.pl +2 -0
  157. package/test/eyelang/conformance/expected/006_comma_formula_data.pl +1 -0
  158. package/test/eyelang/conformance/expected/007_anonymous_variables.pl +1 -0
  159. package/test/eyelang/conformance/expected/008_graphic_atoms.pl +3 -0
  160. package/test/eyelang/conformance/expected/009_comments_and_whitespace.pl +2 -0
  161. package/test/eyelang/conformance/expected/010_variable_scope_and_reuse.pl +2 -0
  162. package/test/eyelang/conformance/expected/011_predicate_arity.pl +2 -0
  163. package/test/eyelang/conformance/expected/012_nested_compound_unification.pl +2 -0
  164. package/test/eyelang/conformance/expected/013_multiple_clauses_order.pl +2 -0
  165. package/test/eyelang/conformance/expected/014_failure_filters_answers.pl +1 -0
  166. package/test/eyelang/conformance/expected/015_improper_list_unification.pl +3 -0
  167. package/test/eyelang/conformance/expected/016_zero_arity_compound.pl +1 -0
  168. package/test/eyelang/conformance/expected/017_three_step_recursion.pl +3 -0
  169. package/test/eyelang/conformance/expected/018_quoted_atom_readback.pl +3 -0
  170. package/test/eyelang/conformance/expected/019_parenthesized_three_conjuncts.pl +1 -0
  171. package/test/eyelang/conformance/expected/020_nested_list_terms.pl +2 -0
  172. package/test/eyelang/conformance/expected/021_repeated_variable_head.pl +2 -0
  173. package/test/eyelang/conformance/expected/022_rule_head_structure.pl +2 -0
  174. package/test/eyelang/conformance/expected/023_quoted_escapes_readback.pl +2 -0
  175. package/test/eyelang/conformance/expected/024_numeric_literal_readback.pl +3 -0
  176. package/test/eyelang/conformance/expected/025_body_parentheses_with_formula_data.pl +1 -0
  177. package/test/eyelang/conformance/expected/026_underscore_named_variable_reuse.pl +1 -0
  178. package/test/eyelang/conformance/expected/027_default_derived_output.pl +3 -0
  179. package/test/eyelang/conformance/expected/028_materialize_focus.pl +1 -0
  180. package/test/eyelang/conformance/expected/029_arithmetic_and_comparison.pl +9 -0
  181. package/test/eyelang/conformance/expected/030_strings_and_atoms.pl +2 -0
  182. package/test/eyelang/conformance/expected/031_lists_aggregation_ordering.pl +9 -0
  183. package/test/eyelang/conformance/expected/032_holds_parts.pl +3 -0
  184. package/test/eyelang/conformance/expected/033_negation_once_generators.pl +2 -0
  185. package/test/eyelang/conformance/expected/034_equality_and_inequality.pl +4 -0
  186. package/test/eyelang/conformance/expected/035_list_relations.pl +4 -0
  187. package/test/eyelang/conformance/expected/036_append_splits.pl +3 -0
  188. package/test/eyelang/conformance/expected/037_matching_and_comparison.pl +5 -0
  189. package/test/eyelang/conformance/expected/038_memoize_declaration.pl +2 -0
  190. package/test/eyelang/conformance/expected/039_numeric_functions.pl +7 -0
  191. package/test/eyelang/conformance/expected/040_between_enumeration.pl +3 -0
  192. package/test/eyelang/conformance/expected/041_smallest_divisor.pl +1 -0
  193. package/test/eyelang/conformance/expected/042_negation_filter.pl +2 -0
  194. package/test/eyelang/conformance/expected/043_once_user_predicate.pl +1 -0
  195. package/test/eyelang/conformance/expected/044_findall_user_goal.pl +1 -0
  196. package/test/eyelang/conformance/expected/045_sort_deduplicates_atoms.pl +1 -0
  197. package/test/eyelang/conformance/expected/046_append_bound_prefix_suffix.pl +2 -0
  198. package/test/eyelang/conformance/expected/047_nth0_index_generation.pl +1 -0
  199. package/test/eyelang/conformance/expected/048_set_nth0_edges.pl +2 -0
  200. package/test/eyelang/conformance/expected/049_select_duplicate_occurrences.pl +2 -0
  201. package/test/eyelang/conformance/expected/050_not_member_filter.pl +1 -0
  202. package/test/eyelang/conformance/expected/051_nested_holds_parts.pl +3 -0
  203. package/test/eyelang/conformance/expected/052_holds_member.pl +2 -0
  204. package/test/eyelang/conformance/expected/053_materialize_excludes_source_fact.pl +1 -0
  205. package/test/eyelang/conformance/expected/054_numeric_and_lexical_comparison.pl +3 -0
  206. package/test/eyelang/conformance/expected/055_string_matching_filters.pl +2 -0
  207. package/test/eyelang/conformance/expected/056_string_and_atom_concat.pl +1 -0
  208. package/test/eyelang/conformance/expected/057_countall_empty_and_nonempty.pl +1 -0
  209. package/test/eyelang/conformance/expected/058_sumall_numeric_template.pl +1 -0
  210. package/test/eyelang/conformance/expected/059_aggregate_min_template.pl +1 -0
  211. package/test/eyelang/conformance/expected/060_aggregate_max_compound_key.pl +1 -0
  212. package/test/eyelang/conformance/expected/061_date_difference.pl +2 -0
  213. package/test/eyelang/conformance/expected/062_reusable_numeric_builtins.pl +8 -0
  214. package/test/eyelang/conformance/expected/063_reusable_list_builtins.pl +9 -0
  215. package/test/eyelang/conformance/expected/064_reusable_string_builtins.pl +10 -0
  216. package/test/eyelang/conformance/expected/065_reusable_term_control_builtins.pl +6 -0
  217. package/test/eyelang/conformance/expected/066_numeric_edges.pl +12 -0
  218. package/test/eyelang/conformance/expected/067_list_edges.pl +8 -0
  219. package/test/eyelang/conformance/expected/068_list_generation_order.pl +10 -0
  220. package/test/eyelang/conformance/expected/069_list_summaries_and_sets.pl +7 -0
  221. package/test/eyelang/conformance/expected/070_matches_named_captures.pl +1 -0
  222. package/test/eyelang/conformance/expected/071_string_edges.pl +8 -0
  223. package/test/eyelang/conformance/expected/072_string_conversions.pl +8 -0
  224. package/test/eyelang/conformance/expected/073_term_introspection_edges.pl +8 -0
  225. package/test/eyelang/conformance/expected/074_forall_edges.pl +5 -0
  226. package/test/eyelang/conformance/expected/075_aggregation_edges.pl +7 -0
  227. package/test/eyelang/conformance/expected/076_composed_reusable_builtins.pl +5 -0
  228. package/test/eyelang/conformance/expected/077_recursive_path_with_lists.pl +3 -0
  229. package/test/eyelang/conformance/expected/078_mutual_recursion_with_arithmetic.pl +7 -0
  230. package/test/eyelang/conformance/expected/079_big_integer_arithmetic.pl +6 -0
  231. package/test/eyelang/conformance/expected/080_rounding_modes.pl +8 -0
  232. package/test/eyelang/conformance/expected/081_zero_safe_numeric_functions.pl +7 -0
  233. package/test/eyelang/conformance/expected/082_comparison_semantics.pl +8 -0
  234. package/test/eyelang/conformance/expected/083_between_modes_and_empty_ranges.pl +8 -0
  235. package/test/eyelang/conformance/expected/084_append_and_select_composition.pl +10 -0
  236. package/test/eyelang/conformance/expected/085_nth_and_update_edges.pl +8 -0
  237. package/test/eyelang/conformance/expected/086_slicing_pipeline.pl +7 -0
  238. package/test/eyelang/conformance/expected/087_sort_reverse_length.pl +6 -0
  239. package/test/eyelang/conformance/expected/088_list_summaries_failures.pl +6 -0
  240. package/test/eyelang/conformance/expected/089_string_split_join_pipeline.pl +4 -0
  241. package/test/eyelang/conformance/expected/090_string_substring_replace_edges.pl +7 -0
  242. package/test/eyelang/conformance/expected/091_string_case_and_trim.pl +5 -0
  243. package/test/eyelang/conformance/expected/092_scalar_string_conversions.pl +7 -0
  244. package/test/eyelang/conformance/expected/093_regex_named_captures_context.pl +5 -0
  245. package/test/eyelang/conformance/expected/094_context_holds_enumeration.pl +8 -0
  246. package/test/eyelang/conformance/expected/095_term_introspection_roundtrip.pl +6 -0
  247. package/test/eyelang/conformance/expected/096_functor_scalar_edges.pl +6 -0
  248. package/test/eyelang/conformance/expected/097_control_negation_once_forall.pl +5 -0
  249. package/test/eyelang/conformance/expected/098_aggregation_nested_templates.pl +5 -0
  250. package/test/eyelang/conformance/expected/099_materialize_multiple_arities.pl +4 -0
  251. package/test/eyelang/conformance/expected/100_reusable_builtin_workflow.pl +6 -0
  252. package/test/eyelang/run-conformance.mjs +20 -22
@@ -460,7 +460,7 @@ node test/eyelang/run-regression.mjs
460
460
  node test/eyelang/run-examples.mjs
461
461
  ```
462
462
 
463
- The conformance suite lives in [`test/eyelang/conformance/`](../test/eyelang/conformance/) and is split into `core` and `extension` profiles matching the language reference. Each case is a small program with an exact expected stdout file, and some internal conformance cases also include a goal file for testing the embeddable solver, so other implementations can reuse the same cases. The regression suite lives in [`test/eyelang/run-regression.mjs`](../test/eyelang/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
463
+ The conformance suite lives in [`test/eyelang/conformance/`](../test/eyelang/conformance/) as one flat eyelang corpus. Each case is a small `.pl` program with an exact expected stdout `.pl` file, and some cases also include a goal file for testing the embeddable solver, so other implementations can reuse the same cases. The suite covers the standard language surface from the language reference, including reusable built-ins. The regression suite lives in [`test/eyelang/run-regression.mjs`](../test/eyelang/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
464
464
 
465
465
  ## Development and release
466
466
 
@@ -41,7 +41,7 @@
41
41
  - [9.8 Aggregation and ordering](#98-aggregation-and-ordering)
42
42
  - [9.9 Context terms](#99-context-terms)
43
43
  - [9.10 Search control](#910-search-control)
44
- - [10. Extension built-ins](#10-extension-built-ins)
44
+ - [10. Implementation-specific built-ins](#10-implementation-specific-built-ins)
45
45
  - [11. Declarations](#11-declarations)
46
46
  - [11.1 Memoization](#111-memoization)
47
47
  - [11.2 Default-output materialization](#112-default-output-materialization)
@@ -51,10 +51,7 @@
51
51
  - [12.3 Sockets and AI agents](#123-sockets-and-ai-agents)
52
52
  - [13. Output and read-back profile](#13-output-and-read-back-profile)
53
53
  - [13.1 Explanation output](#131-explanation-output)
54
- - [14. Conformance profiles](#14-conformance-profiles)
55
- - [14.1 Core language profile](#141-core-language-profile)
56
- - [14.2 Standard built-in profile](#142-standard-built-in-profile)
57
- - [14.3 Standard host profile](#143-standard-host-profile)
54
+ - [14. Conformance](#14-conformance)
58
55
  - [15. Relationship to ISO Prolog](#15-relationship-to-iso-prolog)
59
56
  - [16. Examples](#16-examples)
60
57
  - [16.1 Transitive closure](#161-transitive-closure)
@@ -345,7 +342,7 @@ This section specifies the **standard built-ins** of the eyelang language. An im
345
342
 
346
343
  A built-in call is still written as an atomic formula, but the relation is provided by the host implementation rather than by source clauses. Several built-ins are mode-sensitive: they are intended to run when their input arguments are sufficiently ground, and implementations may leave user-defined clauses visible when that mode is not yet satisfied.
347
344
 
348
- Implementations MAY provide additional built-ins, but such built-ins are extensions and are not part of this normative catalog. Extension built-ins are discussed separately in section 10.
345
+ Implementations MAY provide additional built-ins, but such built-ins are implementation-specific and are not part of this normative catalog. Implementation-specific built-ins are discussed separately in section 10.
349
346
 
350
347
  ### 9.1 Equality and unification
351
348
 
@@ -485,13 +482,13 @@ The N3 example [`context-schema-audit.n3`](../examples/context-schema-audit.n3)
485
482
  | `once(Goal)` | Succeeds with at most the first solution of `Goal`. |
486
483
  | `forall(Generator, Test)` | Succeeds when every solution of `Generator` also satisfies `Test`; succeeds vacuously when `Generator` has no solutions. |
487
484
 
488
- ## 10. Extension built-ins
485
+ ## 10. Implementation-specific built-ins
489
486
 
490
- Implementations MAY provide additional built-ins beyond the standard predicates listed above. Such built-ins are **extension built-ins**. They are useful for embedding eyelang in particular host environments, exposing efficient finite-domain solvers, or providing domain-specific relations for examples and applications.
487
+ Implementations MAY provide additional built-ins beyond the standard predicates listed above. Such built-ins are **implementation-specific built-ins**. They are useful for embedding eyelang in particular host environments, exposing efficient finite-domain solvers, or providing domain-specific relations for applications.
491
488
 
492
- Extension built-ins are not required for conformance to this specification. A portable eyelang program SHOULD NOT depend on an extension built-in unless the target implementation explicitly documents that extension.
489
+ Implementation-specific built-ins are not required for conformance to this specification. A portable eyelang program SHOULD NOT depend on one unless the target implementation explicitly documents it.
493
490
 
494
- An extension built-in SHOULD obey the same surface-language discipline as standard built-ins:
491
+ An implementation-specific built-in SHOULD obey the same surface-language discipline as standard built-ins:
495
492
 
496
493
  - it is called using ordinary atomic-formula syntax, for example `some_extension(A, B)`;
497
494
  - its arguments and results are eyelang terms from the Herbrand universe;
@@ -499,9 +496,9 @@ An extension built-in SHOULD obey the same surface-language discipline as standa
499
496
  - it SHOULD document its intended modes, especially which arguments must be ground before it runs deterministically;
500
497
  - it MUST NOT change the meaning of ordinary facts, rules, unification, or standard built-ins.
501
498
 
502
- For example, an implementation may include extension modules for number-theory algorithms, matrix operations, or host-specific integrations. Those modules may be valuable and may make example programs much faster, but their predicate names, arities, algorithms, and modes are implementation-defined unless they are separately standardized.
499
+ For example, an implementation may include host-specific integrations or domain accelerators. Those modules may be valuable and may make applications much faster, but their predicate names, arities, algorithms, and modes are implementation-defined unless they are separately standardized.
503
500
 
504
- An implementation that provides explanation output SHOULD make extension built-ins explainable at least as opaque successful or failed built-in calls, so that proof traces do not incorrectly report "no clauses" for a host-provided relation.
501
+ An implementation that provides explanation output SHOULD make implementation-specific built-ins explainable at least as opaque successful or failed built-in calls, so that proof traces do not incorrectly report "no clauses" for a host-provided relation.
505
502
 
506
503
  ## 11. Declarations
507
504
 
@@ -623,37 +620,25 @@ Default host output behavior is:
623
620
 
624
621
  When proof output is enabled, each answer SHOULD be followed by a machine-readable `why/2` fact. Explanation output is ordinary eyelang syntax whose second argument is a nested abstract proof term such as `proof(goal(G), by(Method), bindings(Bindings), uses(Proofs))`; implementations SHOULD print `goal(...)` and `by(...)` on separate lines for readability. A proof term preserves the answer goal, derivation method, relevant bindings, and nested uses while omitting proof IDs. User clauses SHOULD be referenced explicitly as `fact(Filename, clause(N))` or `rule(Filename, clause(N))`, where `N` is the 1-based clause number within that source. Built-ins SHOULD be referenced as `builtin(Name, Arity)` because they do not come from source clauses. Explanation output is outside the logical semantics of the input program and MUST NOT change the set of answers.
625
622
 
626
- ## 14. Conformance profiles
623
+ ## 14. Conformance
627
624
 
628
- ### 14.1 Core language profile
629
-
630
- A conforming core language implementation supports:
625
+ A conforming eyelang implementation supports the standard language described above as one conformance surface rather than as separate core and extension profiles. This includes:
631
626
 
632
627
  - lexical syntax described above;
633
628
  - facts and definite clauses;
634
629
  - first-order unification without occurs check;
635
630
  - left-to-right goal-directed proof search;
636
631
  - lists and comma conjunctions;
637
- - answer printing.
638
-
639
- ### 14.2 Standard built-in profile
640
-
641
- A conforming standard built-in implementation supports the built-ins listed in section 9. These are the portable built-ins independent implementations should implement when they claim standard built-in compatibility.
642
-
643
- ### 14.3 Standard host profile
644
-
645
- A conforming standard host also supports:
646
-
632
+ - answer printing and read-back formatting;
633
+ - the standard built-ins listed in section 9;
647
634
  - `memoize/2` declarations;
648
635
  - `materialize/2` declarations;
649
636
  - default derived output;
650
- - explanation output;
651
- - stdin, file, and URL inputs in the CLI.
652
-
653
- Browser execution, package layout, and any extension built-ins described in implementation documentation are outside this specification unless separately standardized.
637
+ - explanation output when the host exposes proof output.
654
638
 
639
+ Browser execution, package layout, CLI URL loading, and any implementation-specific built-ins described in host documentation are outside this conformance surface unless separately standardized.
655
640
 
656
- Conformance cases for these profiles live in the repository under `conformance/`. They are run by `npm test` before the example suite, and can be run alone with `npm run test:conformance`. The cases use exact expected standard output files so independent implementations can compare behavior case by case.
641
+ Conformance cases live in the repository under `test/eyelang/conformance/`. They are run by `npm test` before the example suite, and can be run alone with `node test/eyelang/run-conformance.mjs`. Each case has an input program under `conformance/cases/` and an exact expected standard-output file under `conformance/expected/`; both use `.pl` so expected output remains eyelang-readable.
657
642
 
658
643
  ## 15. Relationship to ISO Prolog
659
644
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.34.4",
3
+ "version": "1.34.5",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -4,8 +4,8 @@ This directory contains the executable conformance cases for the eyelang languag
4
4
 
5
5
  The suite is intentionally file-based so another implementation can run the same programs and compare exact standard output. A case consists of:
6
6
 
7
- - `conformance/cases/<profile>/<name>.pl` — input program;
8
- - `conformance/expected/<profile>/<name>.out` — exact expected standard output.
7
+ - `conformance/cases/<name>.pl` — input program;
8
+ - `conformance/expected/<name>.pl` — exact expected standard output, stored as eyelang-readable facts.
9
9
 
10
10
  The current runner compares standard output from normal execution. Proof explanations are opt-in in the CLI and are not part of these conformance goldens. Standard error, performance, and resource limits are outside this suite.
11
11
 
@@ -23,23 +23,21 @@ Run only the conformance suite:
23
23
  node test/eyelang/run-conformance.mjs
24
24
  ```
25
25
 
26
- Run a single conformance profile directly:
26
+ Run matching conformance cases by passing a filename fragment:
27
27
 
28
28
  ```sh
29
- node test/eyelang/run-conformance.mjs core
30
- node test/eyelang/run-conformance.mjs extension
29
+ node test/eyelang/run-conformance.mjs reusable
30
+ node test/eyelang/run-conformance.mjs 092_scalar_string_conversions
31
31
  ```
32
32
 
33
33
  The runner executes materialized programs in-process through the public JavaScript API so small conformance cases avoid measuring Node startup overhead.
34
34
 
35
- ## Profiles
35
+ ## Scope
36
36
 
37
- `core` covers the portable core language profile from the [eyelang language reference](../../../docs/eyelang-language-reference.md): lexical syntax, facts, definite clauses, first-order terms, lists, conjunction, structured unification through user predicates, left-to-right goal-directed proof search, materialized output, and read-back printing.
37
+ The conformance corpus is a single eyelang suite. It covers the standard language described by the language reference: lexical syntax, facts, definite clauses, first-order terms, lists, conjunction, structured unification, left-to-right goal-directed proof search, materialized output, read-back printing, standard built-ins, declarations, and standard host behavior.
38
38
 
39
- `extension` covers the standard built-in and host behavior exercised by the current reference implementation: arithmetic, comparison, strings, list relations, aggregation, context-term helpers, term-inspection helpers, search-control helpers, `memoize/2`, `materialize/2`, and default derived output.
40
-
41
- The profile name `extension` is a test-suite grouping name. It does not mean that these cases are outside the eyelang language reference; most of them correspond to the standard built-in profile and standard host profile in the [eyelang language reference](../../../docs/eyelang-language-reference.md).
39
+ The suite deliberately does not separate `core` and `extension` profiles. Reusable built-ins such as arithmetic, strings, lists, aggregation, context terms, term inspection, and search control are part of the standard eyelang conformance surface. Implementation-specific built-ins may still exist in downstream hosts, but they should have their own tests outside this corpus unless they are standardized.
42
40
 
43
41
  ## Updating expected output
44
42
 
45
- There is no committed auto-accept mode. To update an expected file, run the matching case with the conformance runner, inspect the result, and replace the corresponding file under `conformance/expected/<profile>/` deliberately.
43
+ There is no committed auto-accept mode. To update an expected file, run the matching case with the conformance runner, inspect the result, and replace the corresponding file under `conformance/expected/` deliberately.
@@ -0,0 +1,4 @@
1
+ % Reference 6, 7, 11: facts can be exposed through a materialized derived predicate.
2
+ materialize(parent, 2).
3
+ base_parent(pat, jan).
4
+ parent(X, Y) :- base_parent(X, Y).
@@ -0,0 +1,7 @@
1
+ % Reference 6, 7: definite clauses, conjunction, and recursive proof search.
2
+ materialize(ancestor, 2).
3
+ parent(pat, jan).
4
+ parent(jan, emma).
5
+ ancestor_any(X, Y) :- parent(X, Y).
6
+ ancestor_any(X, Z) :- parent(X, Y), ancestor_any(Y, Z).
7
+ ancestor(pat, Y) :- ancestor_any(pat, Y).
@@ -0,0 +1 @@
1
+ ancestor(pat, X)
@@ -0,0 +1,16 @@
1
+ % Reference 3, 5, 11: scalars, compounds, lists, and read-back printing.
2
+ materialize(value, 2).
3
+ raw_value(atom, pat).
4
+ raw_value(quoted_atom, 'atom with spaces').
5
+ raw_value(quoted_quote, 'needs''quote').
6
+ raw_value(empty_atom, '').
7
+ raw_value(string, "line\nquote: \"ok\"").
8
+ raw_value(integer, -42).
9
+ raw_value(decimal, 0.25).
10
+ raw_value(scientific, 1.25e-3).
11
+ raw_value(compound, pair(3, nested(atom, [x, y]))).
12
+ raw_value(zero_arity, nil()).
13
+ raw_value(empty_list, []).
14
+ raw_value(proper_list, [a, b, c]).
15
+ raw_value(improper_list, [a, b | tail]).
16
+ value(K, V) :- raw_value(K, V).
@@ -0,0 +1,5 @@
1
+ % Reference 5.5, 7: parenthesized comma terms are conjunctions in goal position.
2
+ p(a).
3
+ q(a).
4
+ ok(X, yes) :- (p(X), q(X)).
5
+ materialize(ok, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 5.4, 12.1: list syntax and unification in rule heads.
2
+ first([X | _Rest], X).
3
+ tail([_Head | Tail], Tail).
4
+ answer(first, X) :- first([a, b, c], X).
5
+ answer(tail, Tail) :- tail([a, b, c], Tail).
6
+ materialize(answer, 2).
@@ -0,0 +1,4 @@
1
+ % Reference 5.5: comma terms remain data outside goal position.
2
+ record((name(alice, "Alice"), knows(alice, bob))).
3
+ answer(formula, F) :- record(F).
4
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 3.4, 5.1, 7.1: each anonymous variable occurrence is fresh.
2
+ pair(a, one).
3
+ pair(b, two).
4
+ answer(fresh, yes) :- pair(a, _), pair(b, _).
5
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 3.5, 5.2, 11: graphic atom constants are scalar terms.
2
+ materialize(value, 2).
3
+ raw_value(hash, #).
4
+ raw_value(arrow, =>).
5
+ raw_value(comparison, =<).
6
+ value(K, V) :- raw_value(K, V).
@@ -0,0 +1,5 @@
1
+ % Reference 3.2, 3.6: comments are ignored outside quoted text and atoms.
2
+ item(quoted_percent, "% not a comment"). % trailing comment
3
+ item(quoted_atom, 'has % sign').
4
+ answer(K, V) :- item(K, V).
5
+ materialize(answer, 2).
@@ -0,0 +1,8 @@
1
+ % Reference 5.1, 7.1: variable occurrences are scoped per clause and reused within a clause.
2
+ edge(a, b).
3
+ edge(b, c).
4
+ edge(c, d).
5
+ two_step(X, Z) :- edge(X, Y), edge(Y, Z).
6
+ answer(from_a, Z) :- two_step(a, Z).
7
+ answer(from_b, Z) :- two_step(b, Z).
8
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 6: predicate name and arity both identify a predicate group.
2
+ p(a).
3
+ p(a, b).
4
+ answer(unary, X) :- p(X).
5
+ answer(binary, pair(X, Y)) :- p(X, Y).
6
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 5.3, 7.1: unification follows nested compound term structure.
2
+ fact(pair(a, nested(b, [c, d]))).
3
+ answer(middle, X) :- fact(pair(a, nested(X, [c, d]))).
4
+ answer(list_tail, T) :- fact(pair(a, nested(b, [c | T]))).
5
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 6, 7: multiple clauses for one predicate are explored as alternatives.
2
+ color(red).
3
+ color(blue).
4
+ paint(X) :- color(X).
5
+ answer(color, X) :- paint(X).
6
+ materialize(answer, 2).
@@ -0,0 +1,7 @@
1
+ % Reference 7.2: a failing subgoal removes that candidate answer.
2
+ candidate(a).
3
+ candidate(b).
4
+ allowed(a).
5
+ answer(X, ok) :- candidate(X), allowed(X).
6
+
7
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 5.4: improper list surface syntax unifies with head-tail structure.
2
+ cell([head | tail], head, tail).
3
+ answer(list, L) :- cell(L, head, tail).
4
+ answer(head, H) :- cell([H | tail], H, tail).
5
+ answer(tail, T) :- cell([head | T], head, T).
6
+ materialize(answer, 2).
@@ -0,0 +1,4 @@
1
+ % Reference 4, 5.3: zero-arity compounds are written and matched with parentheses.
2
+ status(nil(), ok).
3
+ answer(value, X) :- status(X, ok).
4
+ materialize(answer, 2).
@@ -0,0 +1,8 @@
1
+ % Reference 7: recursive definite clauses can derive paths beyond one step.
2
+ link(a, b).
3
+ link(b, c).
4
+ link(c, d).
5
+ path(X, Y) :- link(X, Y).
6
+ path(X, Z) :- link(X, Y), path(Y, Z).
7
+ answer(reachable, X) :- path(a, X).
8
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 3.5, 11: quoted atoms preserve spaces, quotes, and the empty atom.
2
+ symbol('two words').
3
+ symbol('needs''quote').
4
+ symbol('').
5
+ answer(symbol, X) :- symbol(X).
6
+ materialize(answer, 2).
@@ -0,0 +1,7 @@
1
+ % Reference 5.5, 7: parenthesized comma terms with more than two members are conjunctions as goals.
2
+ p(a).
3
+ q(a).
4
+ r(a).
5
+ ok(X) :- (p(X), q(X), r(X)).
6
+ answer(ok, X) :- ok(X).
7
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 5.3, 5.4: lists may contain structured terms that unify positionally.
2
+ node([pair(a, b), pair(c, d)]).
3
+ answer(first_key, X) :- node([pair(X, _), pair(c, d)]).
4
+ answer(second_key, X) :- node([pair(a, b), pair(X, d)]).
5
+ materialize(answer, 2).
@@ -0,0 +1,7 @@
1
+ % Reference 5.1, 7.1: repeated variables in a rule body require the same term.
2
+ pair(a, a).
3
+ pair(a, b).
4
+ pair(c, c).
5
+ diagonal(X) :- pair(X, X).
6
+ answer(diagonal, X) :- diagonal(X).
7
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 5.3, 6, 7.1: structured rule heads destructure matching goals.
2
+ unpack(pair(X, Y), X, Y).
3
+ answer(first, A) :- unpack(pair(alpha, beta), A, _).
4
+ answer(second, B) :- unpack(pair(alpha, beta), _, B).
5
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 3.5, 11: quoted strings and atoms preserve escape sequences at read-back.
2
+ raw(string, "line\nnext\t\\slash").
3
+ raw(atom, 'line\nnext\t\\slash').
4
+ answer(K, V) :- raw(K, V).
5
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 3.3, 11: signed, decimal, and exponent numeric literals retain lexical form.
2
+ raw(negative_decimal, -3.5).
3
+ raw(positive_exp, 6.02e23).
4
+ raw(negative_exp, -1.0e-3).
5
+ answer(K, V) :- raw(K, V).
6
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 5.5, 7: formula data can be passed through parenthesized conjunctions.
2
+ record((left(a), right(b))).
3
+ accept((left(a), right(b))).
4
+ answer(ok, F) :- (record(F), accept(F)).
5
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 3.4, 5.1: variables beginning with underscore are named variables unless exactly _.
2
+ pair(a, a).
3
+ pair(a, b).
4
+ answer(shared, _Value) :- pair(_Value, _Value).
5
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 11: default output prints new ground binary derivations, not source facts.
2
+ parent(pat, jan).
3
+ parent(jan, emma).
4
+ ancestor(X, Y) :- parent(X, Y).
5
+ ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).
@@ -0,0 +1,5 @@
1
+ % Reference 10.2, 11: materialize/2 restricts selected default predicate groups.
2
+ materialize(answer, 2).
3
+ seed(a).
4
+ helper(X, y) :- seed(X).
5
+ answer(X, ok) :- helper(X, y).
@@ -0,0 +1,11 @@
1
+ % Reference 9.2, 9.3: arithmetic and comparison built-ins.
2
+ answer(sum, X) :- add(2, 3, X).
3
+ answer(diff, X) :- sub(7, 4, X).
4
+ answer(product, X) :- mul(6, 7, X).
5
+ answer(integer_division, X) :- div(7, 2, X).
6
+ answer(remainder, X) :- mod(7, 2, X).
7
+ answer(power, X) :- pow(2, 8, X).
8
+ answer(minimum, X) :- min(3, 9, X).
9
+ answer(less_than, true) :- lt(3, 9).
10
+ answer(greater_equal, true) :- ge(9, 9).
11
+ materialize(answer, 2).
@@ -0,0 +1,4 @@
1
+ % Reference 9.6: atom and string built-ins.
2
+ answer(str_concat, X) :- str_concat("eye", "lang", X).
3
+ answer(contains, true) :- contains("eyelang", "lang").
4
+ materialize(answer, 2).
@@ -0,0 +1,10 @@
1
+ % Reference 9.7, 9.8: list, aggregation, and ordering built-ins.
2
+ answer(member, X) :- member(X, [a, b]).
3
+ answer(append, X) :- append([a], [b, c], X).
4
+ answer(nth0, X) :- nth0(1, [a, b, c], X).
5
+ answer(set_nth0, X) :- set_nth0(1, [a, b, c], x, X).
6
+ answer(reverse, X) :- reverse([a, b, c], X).
7
+ answer(length, N) :- length([a, b, c], N).
8
+ answer(findall, X) :- findall(N, between(1, 3, N), X).
9
+ answer(sort, X) :- sort([b, a, b], X).
10
+ materialize(answer, 2).
@@ -0,0 +1,4 @@
1
+ % Reference 9.9: holds/3 exposes context members of any arity.
2
+ context((ready, name(alice, "Alice"), route(alice, bob, 7))).
3
+ answer(parts, exposed(Name, Args)) :- context(C), holds(C, Name, Args).
4
+ materialize(answer, 2).
@@ -0,0 +1,7 @@
1
+ % Reference 9.5, 9.10: generators, negation as failure, and once/1.
2
+ candidate(a).
3
+ candidate(b).
4
+ closed(b).
5
+ answer(open, X) :- candidate(X), not(closed(X)).
6
+ answer(first_between, X) :- once(between(2, 4, X)).
7
+ materialize(answer, 2).
@@ -0,0 +1,6 @@
1
+ % Reference 9.1: eq/2 unifies terms and neq/2 succeeds on non-unifiable terms.
2
+ answer(eq_variable, X) :- eq(X, pair(a, [b, c])).
3
+ answer(eq_nested, true) :- eq(pair(X, X), pair(same, same)).
4
+ answer(neq_atoms, true) :- neq(alice, bob).
5
+ answer(neq_structures, true) :- neq(pair(a), pair(a, b)).
6
+ materialize(answer, 2).
@@ -0,0 +1,5 @@
1
+ % Reference 9.7: rest/2, select/3, and not_member/2.
2
+ answer(rest, X) :- rest([a, b, c], X).
3
+ answer(select, selected(X, R)) :- select(X, [a, b], R).
4
+ answer(not_member, true) :- not_member(c, [a, b]).
5
+ materialize(answer, 2).
@@ -0,0 +1,3 @@
1
+ % Reference 9.7: append/3 can enumerate proper prefix/suffix splits.
2
+ answer(split, split(A, B)) :- append(A, B, [a, b]).
3
+ materialize(answer, 2).
@@ -0,0 +1,7 @@
1
+ % Reference 9.3, 9.6: lexical comparison and simple text matching.
2
+ answer(matches, true) :- matches("eyelang", "eye").
3
+ answer(not_matches, true) :- not_matches("eyelang", "cat").
4
+ answer(lex_lt, true) :- lt(alpha, beta).
5
+ answer(lex_gt, true) :- gt(beta, alpha).
6
+ answer(numeric_le, true) :- le(2, 2).
7
+ materialize(answer, 2).
@@ -0,0 +1,8 @@
1
+ % Reference 10.1: memoize/2 is a declaration and does not change answers.
2
+ materialize(reach, 2).
3
+ memoize(reach_any, 2).
4
+ edge(a, b).
5
+ edge(b, c).
6
+ reach_any(X, Y) :- edge(X, Y).
7
+ reach_any(X, Z) :- edge(X, Y), reach_any(Y, Z).
8
+ reach(a, Y) :- reach_any(a, Y).
@@ -0,0 +1,9 @@
1
+ % Reference 9.2: scalar arithmetic functions return numeric values.
2
+ answer(neg, X) :- neg(5, X).
3
+ answer(abs, X) :- abs(-5, X).
4
+ answer(rounded, X) :- rounded(2.6, X).
5
+ answer(sin_zero, X) :- sin(0, X).
6
+ answer(cos_zero, X) :- cos(0, X).
7
+ answer(log_one, X) :- log(1, X).
8
+ answer(float_division, X) :- div(7.0, 2.0, X).
9
+ materialize(answer, 2).
@@ -0,0 +1,3 @@
1
+ % Reference 9.5: between/3 enumerates every integer in an inclusive range.
2
+ answer(n, X) :- between(3, 5, X).
3
+ materialize(answer, 2).
@@ -0,0 +1,3 @@
1
+ % Reference 9.5: smallest_divisor_from/3 finds the first divisor at or above the start.
2
+ answer(divisor, D) :- smallest_divisor_from(21, 2, D).
3
+ materialize(answer, 2).