eyelang 1.7.3 → 1.7.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 (301) hide show
  1. package/README.md +1 -0
  2. package/docs/guide.md +8 -1
  3. package/docs/language-reference.md +1 -1
  4. package/package.json +3 -2
  5. package/test/conformance/README.md +7 -1
  6. package/test/conformance/cases/aggregation/aggregate_max_no_answers_fails.eye +2 -0
  7. package/test/conformance/cases/aggregation/aggregate_min_structured_key.eye +5 -0
  8. package/test/conformance/cases/aggregation/countall_zero.eye +2 -0
  9. package/test/conformance/cases/aggregation/findall_empty_bag.eye +2 -0
  10. package/test/conformance/cases/aggregation/sumall_empty_zero.eye +2 -0
  11. package/test/conformance/cases/arithmetic/between_bound_value.eye +2 -0
  12. package/test/conformance/cases/arithmetic/between_singleton.eye +2 -0
  13. package/test/conformance/cases/arithmetic/duration_comparison.eye +2 -0
  14. package/test/conformance/cases/arithmetic/float_add_and_div.eye +3 -0
  15. package/test/conformance/cases/arithmetic/min_max_mixed.eye +3 -0
  16. package/test/conformance/cases/arithmetic/mod_negative_left.eye +2 -0
  17. package/test/conformance/cases/arithmetic/neg_abs_integer.eye +4 -0
  18. package/test/conformance/cases/arithmetic/pow_negative_exponent_fails.eye +2 -0
  19. package/test/conformance/cases/arithmetic/pow_zero_exponent.eye +2 -0
  20. package/test/conformance/cases/arithmetic/rounding_negative_float.eye +5 -0
  21. package/test/conformance/cases/arithmetic/smallest_divisor_prime.eye +2 -0
  22. package/test/conformance/cases/arithmetic/sqrt_negative_fails.eye +2 -0
  23. package/test/conformance/cases/atoms/angle_iri_percent_encoded.eye +2 -0
  24. package/test/conformance/cases/atoms/graphic_atom_predicate.eye +3 -0
  25. package/test/conformance/cases/atoms/graphic_less_than_atom.eye +4 -0
  26. package/test/conformance/cases/atoms/iri_as_predicate_name_quoted.eye +3 -0
  27. package/test/conformance/cases/atoms/iri_mailto_readback.eye +4 -0
  28. package/test/conformance/cases/atoms/iri_query_fragment_readback.eye +4 -0
  29. package/test/conformance/cases/atoms/iri_urn_readback.eye +4 -0
  30. package/test/conformance/cases/atoms/quoted_relative_iri_not_angle.eye +2 -0
  31. package/test/conformance/cases/atoms/quoted_urn_iri_readback.eye +4 -0
  32. package/test/conformance/cases/builtins/atom_string_iri_atom.eye +3 -0
  33. package/test/conformance/cases/builtins/eq_unifies_iri_atoms.eye +3 -0
  34. package/test/conformance/cases/context/holds_compound_formula.eye +2 -0
  35. package/test/conformance/cases/context/holds_fails_when_missing.eye +2 -0
  36. package/test/conformance/cases/context/holds_parts_from_formula.eye +2 -0
  37. package/test/conformance/cases/control/double_negation_ground_goal.eye +3 -0
  38. package/test/conformance/cases/control/forall_detects_counterexample.eye +5 -0
  39. package/test/conformance/cases/control/forall_empty_generator_true.eye +2 -0
  40. package/test/conformance/cases/control/negation_with_bound_generator.eye +5 -0
  41. package/test/conformance/cases/control/once_keeps_first_answer.eye +4 -0
  42. package/test/conformance/cases/declarations/det_semidet_do_not_emit_without_materialize.eye +5 -0
  43. package/test/conformance/cases/declarations/mode_ignored_when_arity_mismatch.eye +5 -0
  44. package/test/conformance/cases/declarations/table_is_also_fact.eye +4 -0
  45. package/test/conformance/cases/lists/empty_list_term.eye +4 -0
  46. package/test/conformance/cases/lists/head_rest_last.eye +4 -0
  47. package/test/conformance/cases/lists/improper_list_readback.eye +4 -0
  48. package/test/conformance/cases/lists/length_empty_and_nested.eye +3 -0
  49. package/test/conformance/cases/lists/list_to_set_structural_duplicates.eye +2 -0
  50. package/test/conformance/cases/lists/list_with_iri_atoms.eye +4 -0
  51. package/test/conformance/cases/lists/min_list_empty_fails.eye +2 -0
  52. package/test/conformance/cases/lists/nth0_known_value.eye +2 -0
  53. package/test/conformance/cases/lists/nth0_out_of_range_fails.eye +2 -0
  54. package/test/conformance/cases/lists/reverse_empty.eye +2 -0
  55. package/test/conformance/cases/lists/select_all_occurrences.eye +2 -0
  56. package/test/conformance/cases/lists/set_nth0_middle.eye +2 -0
  57. package/test/conformance/cases/lists/slice_middle.eye +2 -0
  58. package/test/conformance/cases/lists/slice_out_of_range_fails.eye +2 -0
  59. package/test/conformance/cases/lists/sort_structured_terms.eye +2 -0
  60. package/test/conformance/cases/lists/sum_list_empty_zero.eye +2 -0
  61. package/test/conformance/cases/lists/sum_min_max_list.eye +4 -0
  62. package/test/conformance/cases/lists/take_zero_and_drop_all.eye +3 -0
  63. package/test/conformance/cases/materialize/arity_specific_outputs.eye +4 -0
  64. package/test/conformance/cases/materialize/source_facts_suppressed.eye +5 -0
  65. package/test/conformance/cases/negation/not_known_goal_fails.eye +4 -0
  66. package/test/conformance/cases/negation/not_unknown_goal_succeeds.eye +3 -0
  67. package/test/conformance/cases/rules/left_to_right_body_binding.eye +4 -0
  68. package/test/conformance/cases/rules/transitive_rule_three_edges.eye +7 -0
  69. package/test/conformance/cases/strings/atom_string_from_string.eye +2 -0
  70. package/test/conformance/cases/strings/casefold_atoms.eye +3 -0
  71. package/test/conformance/cases/strings/contains_empty_needle.eye +2 -0
  72. package/test/conformance/cases/strings/join_mixed_scalars.eye +2 -0
  73. package/test/conformance/cases/strings/matches_simple_alternation.eye +2 -0
  74. package/test/conformance/cases/strings/named_regex_two_groups.eye +2 -0
  75. package/test/conformance/cases/strings/not_matches_simple_pattern.eye +2 -0
  76. package/test/conformance/cases/strings/number_string_from_string.eye +2 -0
  77. package/test/conformance/cases/strings/number_string_rejects_non_numeric.eye +2 -0
  78. package/test/conformance/cases/strings/replace_empty_search_no_change.eye +2 -0
  79. package/test/conformance/cases/strings/split_without_separator_match.eye +2 -0
  80. package/test/conformance/cases/strings/substring_out_of_range_fails.eye +2 -0
  81. package/test/conformance/cases/strings/substring_zero_count.eye +2 -0
  82. package/test/conformance/cases/strings/term_string_nested_term.eye +2 -0
  83. package/test/conformance/cases/strings/trim_tabs_and_spaces.eye +2 -0
  84. package/test/conformance/cases/syntax/comments_inside_program.eye +4 -0
  85. package/test/conformance/cases/syntax/parenthesized_query_style_body.eye +5 -0
  86. package/test/conformance/cases/syntax/quoted_atom_with_newline_escape.eye +3 -0
  87. package/test/conformance/cases/syntax/string_with_tab_escape.eye +2 -0
  88. package/test/conformance/cases/table/tabled_left_recursion_path.eye +7 -0
  89. package/test/conformance/cases/terms/arg_first_and_second.eye +3 -0
  90. package/test/conformance/cases/terms/arg_zero_fails.eye +2 -0
  91. package/test/conformance/cases/terms/compound_name_arguments_atom_zero_args.eye +3 -0
  92. package/test/conformance/cases/terms/compound_name_arguments_bad_args_fail.eye +2 -0
  93. package/test/conformance/cases/terms/compound_name_arguments_builds_atom_from_empty_args.eye +3 -0
  94. package/test/conformance/cases/terms/compound_name_arguments_builds_compound.eye +2 -0
  95. package/test/conformance/cases/terms/compound_name_arguments_iri_name.eye +2 -0
  96. package/test/conformance/cases/terms/functor_atom_arity_zero.eye +3 -0
  97. package/test/conformance/cases/terms/functor_number_and_string.eye +3 -0
  98. package/test/conformance/cases/terms/term_string_readback_iri_list.eye +2 -0
  99. package/test/conformance/cases/unification/compound_arity_mismatch_fails.eye +2 -0
  100. package/test/conformance/cases/unification/list_tail_binding.eye +2 -0
  101. package/test/conformance/cases/unification/nested_repeated_variable.eye +2 -0
  102. package/test/conformance/cases/unification/scalar_cross_type_same_lexical_value.eye +3 -0
  103. package/test/conformance/cases/variables/anonymous_in_two_goals.eye +4 -0
  104. package/test/conformance/cases/variables/clause_local_variable_names.eye +5 -0
  105. package/test/conformance/cases/variables/question_uppercase_variable.eye +4 -0
  106. package/test/conformance/cases/variables/question_variable_digits_and_underscore.eye +2 -0
  107. package/test/conformance/cases/variables/question_variable_uppercase_name.eye +2 -0
  108. package/test/conformance/cases/variables/variable_scope_per_clause.eye +6 -0
  109. package/test/conformance/errors/atoms/hash_comment_not_atom_at_line_start.eye +1 -0
  110. package/test/conformance/errors/atoms/relative_angle_name_rejected.eye +1 -0
  111. package/test/conformance/errors/atoms/space_in_angle_iri_rejected.eye +1 -0
  112. package/test/conformance/errors/atoms/unclosed_angle_iri_rejected.eye +1 -0
  113. package/test/conformance/errors/lists/missing_list_tail.eye +1 -0
  114. package/test/conformance/errors/rules/rule_head_cannot_be_empty_parentheses.eye +1 -0
  115. package/test/conformance/errors/syntax/angle_iri_with_space_rejected.eye +1 -0
  116. package/test/conformance/errors/syntax/bad_question_digit_variable.eye +1 -0
  117. package/test/conformance/errors/syntax/bad_question_variable.eye +1 -0
  118. package/test/conformance/errors/syntax/empty_body_after_rule_marker.eye +1 -0
  119. package/test/conformance/errors/syntax/empty_compound_nested.eye +1 -0
  120. package/test/conformance/errors/syntax/missing_final_dot_rejected.eye +1 -0
  121. package/test/conformance/errors/syntax/missing_period.eye +1 -0
  122. package/test/conformance/errors/syntax/relative_angle_iri_rejected.eye +1 -0
  123. package/test/conformance/errors/syntax/trailing_comma_in_body.eye +1 -0
  124. package/test/conformance/errors/syntax/unclosed_compound.eye +1 -0
  125. package/test/conformance/errors/syntax/unclosed_list.eye +1 -0
  126. package/test/conformance/errors/syntax/unclosed_list_rejected.eye +1 -0
  127. package/test/conformance/errors/syntax/unclosed_quoted_atom.eye +1 -0
  128. package/test/conformance/errors/syntax/unclosed_string.eye +1 -0
  129. package/test/conformance/errors/syntax/unquoted_colon_predicate.eye +1 -0
  130. package/test/conformance/errors/syntax/unquoted_dotted_predicate.eye +1 -0
  131. package/test/conformance/errors/syntax/uppercase_predicate_rejected.eye +1 -0
  132. package/test/conformance/errors/terms/zero_arity_compound_nested_rejected.eye +1 -0
  133. package/test/conformance/errors/variables/bare_underscore_in_list_rejected.eye +1 -0
  134. package/test/conformance/errors/variables/bare_underscore_name_in_compound_rejected.eye +1 -0
  135. package/test/conformance/errors/variables/question_digit_rejected.eye +1 -0
  136. package/test/conformance/errors/variables/question_dot_rejected.eye +1 -0
  137. package/test/conformance/errors/variables/uppercase_in_body_rejected.eye +1 -0
  138. package/test/conformance/expected/aggregation/aggregate_max_no_answers_fails.eye +1 -0
  139. package/test/conformance/expected/aggregation/aggregate_min_structured_key.eye +1 -0
  140. package/test/conformance/expected/aggregation/countall_zero.eye +1 -0
  141. package/test/conformance/expected/aggregation/findall_empty_bag.eye +1 -0
  142. package/test/conformance/expected/aggregation/sumall_empty_zero.eye +1 -0
  143. package/test/conformance/expected/arithmetic/between_bound_value.eye +1 -0
  144. package/test/conformance/expected/arithmetic/between_singleton.eye +1 -0
  145. package/test/conformance/expected/arithmetic/duration_comparison.eye +1 -0
  146. package/test/conformance/expected/arithmetic/float_add_and_div.eye +2 -0
  147. package/test/conformance/expected/arithmetic/min_max_mixed.eye +2 -0
  148. package/test/conformance/expected/arithmetic/mod_negative_left.eye +1 -0
  149. package/test/conformance/expected/arithmetic/neg_abs_integer.eye +2 -0
  150. package/test/conformance/expected/arithmetic/pow_negative_exponent_fails.eye +1 -0
  151. package/test/conformance/expected/arithmetic/pow_zero_exponent.eye +1 -0
  152. package/test/conformance/expected/arithmetic/rounding_negative_float.eye +4 -0
  153. package/test/conformance/expected/arithmetic/smallest_divisor_prime.eye +1 -0
  154. package/test/conformance/expected/arithmetic/sqrt_negative_fails.eye +1 -0
  155. package/test/conformance/expected/atoms/angle_iri_percent_encoded.eye +0 -0
  156. package/test/conformance/expected/atoms/graphic_atom_predicate.eye +1 -0
  157. package/test/conformance/expected/atoms/graphic_less_than_atom.eye +1 -0
  158. package/test/conformance/expected/atoms/iri_as_predicate_name_quoted.eye +1 -0
  159. package/test/conformance/expected/atoms/iri_mailto_readback.eye +1 -0
  160. package/test/conformance/expected/atoms/iri_query_fragment_readback.eye +1 -0
  161. package/test/conformance/expected/atoms/iri_urn_readback.eye +1 -0
  162. package/test/conformance/expected/atoms/quoted_relative_iri_not_angle.eye +0 -0
  163. package/test/conformance/expected/atoms/quoted_urn_iri_readback.eye +1 -0
  164. package/test/conformance/expected/builtins/atom_string_iri_atom.eye +1 -0
  165. package/test/conformance/expected/builtins/eq_unifies_iri_atoms.eye +1 -0
  166. package/test/conformance/expected/context/holds_compound_formula.eye +1 -0
  167. package/test/conformance/expected/context/holds_fails_when_missing.eye +1 -0
  168. package/test/conformance/expected/context/holds_parts_from_formula.eye +2 -0
  169. package/test/conformance/expected/control/double_negation_ground_goal.eye +1 -0
  170. package/test/conformance/expected/control/forall_detects_counterexample.eye +1 -0
  171. package/test/conformance/expected/control/forall_empty_generator_true.eye +1 -0
  172. package/test/conformance/expected/control/negation_with_bound_generator.eye +1 -0
  173. package/test/conformance/expected/control/once_keeps_first_answer.eye +1 -0
  174. package/test/conformance/expected/declarations/det_semidet_do_not_emit_without_materialize.eye +1 -0
  175. package/test/conformance/expected/declarations/mode_ignored_when_arity_mismatch.eye +1 -0
  176. package/test/conformance/expected/declarations/table_is_also_fact.eye +1 -0
  177. package/test/conformance/expected/lists/empty_list_term.eye +1 -0
  178. package/test/conformance/expected/lists/head_rest_last.eye +3 -0
  179. package/test/conformance/expected/lists/improper_list_readback.eye +1 -0
  180. package/test/conformance/expected/lists/length_empty_and_nested.eye +2 -0
  181. package/test/conformance/expected/lists/list_to_set_structural_duplicates.eye +1 -0
  182. package/test/conformance/expected/lists/list_with_iri_atoms.eye +1 -0
  183. package/test/conformance/expected/lists/min_list_empty_fails.eye +1 -0
  184. package/test/conformance/expected/lists/nth0_known_value.eye +1 -0
  185. package/test/conformance/expected/lists/nth0_out_of_range_fails.eye +1 -0
  186. package/test/conformance/expected/lists/reverse_empty.eye +1 -0
  187. package/test/conformance/expected/lists/select_all_occurrences.eye +3 -0
  188. package/test/conformance/expected/lists/set_nth0_middle.eye +1 -0
  189. package/test/conformance/expected/lists/slice_middle.eye +0 -0
  190. package/test/conformance/expected/lists/slice_out_of_range_fails.eye +1 -0
  191. package/test/conformance/expected/lists/sort_structured_terms.eye +1 -0
  192. package/test/conformance/expected/lists/sum_list_empty_zero.eye +1 -0
  193. package/test/conformance/expected/lists/sum_min_max_list.eye +3 -0
  194. package/test/conformance/expected/lists/take_zero_and_drop_all.eye +2 -0
  195. package/test/conformance/expected/materialize/arity_specific_outputs.eye +0 -0
  196. package/test/conformance/expected/materialize/source_facts_suppressed.eye +1 -0
  197. package/test/conformance/expected/negation/not_known_goal_fails.eye +0 -0
  198. package/test/conformance/expected/negation/not_unknown_goal_succeeds.eye +1 -0
  199. package/test/conformance/expected/rules/left_to_right_body_binding.eye +1 -0
  200. package/test/conformance/expected/rules/transitive_rule_three_edges.eye +6 -0
  201. package/test/conformance/expected/strings/atom_string_from_string.eye +1 -0
  202. package/test/conformance/expected/strings/casefold_atoms.eye +2 -0
  203. package/test/conformance/expected/strings/contains_empty_needle.eye +1 -0
  204. package/test/conformance/expected/strings/join_mixed_scalars.eye +1 -0
  205. package/test/conformance/expected/strings/matches_simple_alternation.eye +1 -0
  206. package/test/conformance/expected/strings/named_regex_two_groups.eye +1 -0
  207. package/test/conformance/expected/strings/not_matches_simple_pattern.eye +1 -0
  208. package/test/conformance/expected/strings/number_string_from_string.eye +1 -0
  209. package/test/conformance/expected/strings/number_string_rejects_non_numeric.eye +1 -0
  210. package/test/conformance/expected/strings/replace_empty_search_no_change.eye +1 -0
  211. package/test/conformance/expected/strings/split_without_separator_match.eye +1 -0
  212. package/test/conformance/expected/strings/substring_out_of_range_fails.eye +1 -0
  213. package/test/conformance/expected/strings/substring_zero_count.eye +1 -0
  214. package/test/conformance/expected/strings/term_string_nested_term.eye +1 -0
  215. package/test/conformance/expected/strings/trim_tabs_and_spaces.eye +1 -0
  216. package/test/conformance/expected/syntax/comments_inside_program.eye +0 -0
  217. package/test/conformance/expected/syntax/parenthesized_query_style_body.eye +1 -0
  218. package/test/conformance/expected/syntax/quoted_atom_with_newline_escape.eye +0 -0
  219. package/test/conformance/expected/syntax/string_with_tab_escape.eye +0 -0
  220. package/test/conformance/expected/table/tabled_left_recursion_path.eye +1 -0
  221. package/test/conformance/expected/terms/arg_first_and_second.eye +2 -0
  222. package/test/conformance/expected/terms/arg_zero_fails.eye +1 -0
  223. package/test/conformance/expected/terms/compound_name_arguments_atom_zero_args.eye +1 -0
  224. package/test/conformance/expected/terms/compound_name_arguments_bad_args_fail.eye +1 -0
  225. package/test/conformance/expected/terms/compound_name_arguments_builds_atom_from_empty_args.eye +1 -0
  226. package/test/conformance/expected/terms/compound_name_arguments_builds_compound.eye +1 -0
  227. package/test/conformance/expected/terms/compound_name_arguments_iri_name.eye +1 -0
  228. package/test/conformance/expected/terms/functor_atom_arity_zero.eye +1 -0
  229. package/test/conformance/expected/terms/functor_number_and_string.eye +2 -0
  230. package/test/conformance/expected/terms/term_string_readback_iri_list.eye +1 -0
  231. package/test/conformance/expected/unification/compound_arity_mismatch_fails.eye +1 -0
  232. package/test/conformance/expected/unification/list_tail_binding.eye +1 -0
  233. package/test/conformance/expected/unification/nested_repeated_variable.eye +1 -0
  234. package/test/conformance/expected/unification/scalar_cross_type_same_lexical_value.eye +2 -0
  235. package/test/conformance/expected/variables/anonymous_in_two_goals.eye +1 -0
  236. package/test/conformance/expected/variables/clause_local_variable_names.eye +2 -0
  237. package/test/conformance/expected/variables/question_uppercase_variable.eye +1 -0
  238. package/test/conformance/expected/variables/question_variable_digits_and_underscore.eye +1 -0
  239. package/test/conformance/expected/variables/question_variable_uppercase_name.eye +1 -0
  240. package/test/conformance/expected/variables/variable_scope_per_clause.eye +2 -0
  241. package/test/conformance/expected-errors/atoms/hash_comment_not_atom_at_line_start.txt +1 -0
  242. package/test/conformance/expected-errors/atoms/relative_angle_name_rejected.txt +1 -0
  243. package/test/conformance/expected-errors/atoms/space_in_angle_iri_rejected.txt +1 -0
  244. package/test/conformance/expected-errors/atoms/unclosed_angle_iri_rejected.txt +1 -0
  245. package/test/conformance/expected-errors/lists/missing_list_tail.txt +1 -0
  246. package/test/conformance/expected-errors/rules/rule_head_cannot_be_empty_parentheses.txt +1 -0
  247. package/test/conformance/expected-errors/syntax/angle_iri_with_space_rejected.txt +1 -0
  248. package/test/conformance/expected-errors/syntax/bad_question_digit_variable.txt +1 -0
  249. package/test/conformance/expected-errors/syntax/bad_question_variable.txt +1 -0
  250. package/test/conformance/expected-errors/syntax/empty_body_after_rule_marker.txt +1 -0
  251. package/test/conformance/expected-errors/syntax/empty_compound_nested.txt +1 -0
  252. package/test/conformance/expected-errors/syntax/missing_final_dot_rejected.txt +1 -0
  253. package/test/conformance/expected-errors/syntax/missing_period.txt +1 -0
  254. package/test/conformance/expected-errors/syntax/relative_angle_iri_rejected.txt +1 -0
  255. package/test/conformance/expected-errors/syntax/trailing_comma_in_body.txt +1 -0
  256. package/test/conformance/expected-errors/syntax/unclosed_compound.txt +1 -0
  257. package/test/conformance/expected-errors/syntax/unclosed_list.txt +1 -0
  258. package/test/conformance/expected-errors/syntax/unclosed_list_rejected.txt +1 -0
  259. package/test/conformance/expected-errors/syntax/unclosed_quoted_atom.txt +1 -0
  260. package/test/conformance/expected-errors/syntax/unclosed_string.txt +1 -0
  261. package/test/conformance/expected-errors/syntax/unquoted_colon_predicate.txt +1 -0
  262. package/test/conformance/expected-errors/syntax/unquoted_dotted_predicate.txt +1 -0
  263. package/test/conformance/expected-errors/syntax/uppercase_predicate_rejected.txt +1 -0
  264. package/test/conformance/expected-errors/terms/zero_arity_compound_nested_rejected.txt +1 -0
  265. package/test/conformance/expected-errors/variables/bare_underscore_in_list_rejected.txt +1 -0
  266. package/test/conformance/expected-errors/variables/bare_underscore_name_in_compound_rejected.txt +1 -0
  267. package/test/conformance/expected-errors/variables/question_digit_rejected.txt +1 -0
  268. package/test/conformance/expected-errors/variables/question_dot_rejected.txt +1 -0
  269. package/test/conformance/expected-errors/variables/uppercase_in_body_rejected.txt +1 -0
  270. package/test/conformance/expected-warnings/negation/negative_unknown_group_quiet.eye +1 -0
  271. package/test/conformance/expected-warnings/negation/negative_unknown_group_quiet.txt +0 -0
  272. package/test/conformance/expected-warnings/negation/no_negation_quiet.eye +1 -0
  273. package/test/conformance/expected-warnings/negation/no_negation_quiet.txt +0 -0
  274. package/test/conformance/expected-warnings/negation/stratified_negative_unknown_after_positive_quiet.eye +1 -0
  275. package/test/conformance/expected-warnings/negation/stratified_negative_unknown_after_positive_quiet.txt +0 -0
  276. package/test/conformance/expected-warnings/negation/stratified_two_level_quiet.eye +1 -0
  277. package/test/conformance/expected-warnings/negation/stratified_two_level_quiet.txt +0 -0
  278. package/test/conformance/expected-warnings/negation/unstratified_positive_prefix.eye +0 -0
  279. package/test/conformance/expected-warnings/negation/unstratified_positive_prefix.txt +2 -0
  280. package/test/conformance/expected-warnings/negation/unstratified_three_step.eye +1 -0
  281. package/test/conformance/expected-warnings/negation/unstratified_three_step.txt +2 -0
  282. package/test/conformance/expected-warnings/negation/unstratified_two_arity_cycle.eye +0 -0
  283. package/test/conformance/expected-warnings/negation/unstratified_two_arity_cycle.txt +3 -0
  284. package/test/conformance/expected-warnings/negation/unstratified_two_independent_cycles.eye +0 -0
  285. package/test/conformance/expected-warnings/negation/unstratified_two_independent_cycles.txt +5 -0
  286. package/test/conformance/expected-warnings/negation/unstratified_with_iri_predicates.eye +0 -0
  287. package/test/conformance/expected-warnings/negation/unstratified_with_iri_predicates.txt +3 -0
  288. package/test/conformance/expected-warnings/negation/warning_preserves_multiple_stdout_answers.eye +0 -0
  289. package/test/conformance/expected-warnings/negation/warning_preserves_multiple_stdout_answers.txt +3 -0
  290. package/test/conformance/warnings/negation/negative_unknown_group_quiet.eye +2 -0
  291. package/test/conformance/warnings/negation/no_negation_quiet.eye +3 -0
  292. package/test/conformance/warnings/negation/stratified_negative_unknown_after_positive_quiet.eye +3 -0
  293. package/test/conformance/warnings/negation/stratified_two_level_quiet.eye +5 -0
  294. package/test/conformance/warnings/negation/unstratified_positive_prefix.eye +5 -0
  295. package/test/conformance/warnings/negation/unstratified_three_step.eye +6 -0
  296. package/test/conformance/warnings/negation/unstratified_two_arity_cycle.eye +4 -0
  297. package/test/conformance/warnings/negation/unstratified_two_independent_cycles.eye +6 -0
  298. package/test/conformance/warnings/negation/unstratified_with_iri_predicates.eye +4 -0
  299. package/test/conformance/warnings/negation/warning_preserves_multiple_stdout_answers.eye +5 -0
  300. package/test/run-conformance-report.mjs +108 -0
  301. package/test/run-regression.mjs +13 -0
package/README.md CHANGED
@@ -62,6 +62,7 @@ python3 -m http.server
62
62
  ```bash
63
63
  npm test
64
64
  npm run test:conformance
65
+ npm run conformance:report
65
66
  npm run test:examples
66
67
  npm run test:regression
67
68
  ```
package/docs/guide.md CHANGED
@@ -497,7 +497,13 @@ node test/run-regression.mjs
497
497
  node test/run-examples.mjs
498
498
  ```
499
499
 
500
- The conformance suite lives in [`test/conformance/`](../test/conformance/) as a file-based eyelang corpus. Positive cases pair `cases/<name>.eye` with exact expected stdout under `expected/<name>.eye`; negative cases pair `errors/<name>.eye` with exact expected error text under `expected-errors/<name>.txt`; warning cases pair `warnings/<name>.eye` with exact `--warnings` stdout and stderr files under `expected-warnings/`. Cases may be grouped in category directories such as `atoms/`, `variables/`, `negation/`, and `syntax/`, so another implementation can reuse the same corpus as an executable language contract. The suite covers the standard language surface from the language reference, including reusable built-ins, standard errors, and standard warnings. The regression suite lives in [`test/run-regression.mjs`](../test/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
500
+ Summarize the conformance corpus by category:
501
+
502
+ ```sh
503
+ npm run conformance:report
504
+ ```
505
+
506
+ The conformance suite lives in [`test/conformance/`](../test/conformance/) as a file-based eyelang corpus. Positive cases pair `cases/<name>.eye` with exact expected stdout under `expected/<name>.eye`; negative cases pair `errors/<name>.eye` with exact expected error text under `expected-errors/<name>.txt`; warning cases pair `warnings/<name>.eye` with exact `--warnings` stdout and stderr files under `expected-warnings/`. Cases may be grouped in category directories such as `arithmetic/`, `strings/`, `lists/`, `terms/`, `atoms/`, `variables/`, `negation/`, and `syntax/`, so another implementation can reuse the same corpus as an executable language contract. The suite covers the standard language surface from the language reference, including reusable built-ins, standard errors, and standard warnings. The regression suite lives in [`test/run-regression.mjs`](../test/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
501
507
 
502
508
  ## Development and release
503
509
 
@@ -506,6 +512,7 @@ Common commands:
506
512
  ```sh
507
513
  npm run test:eyelang # alias for npm test
508
514
  npm test # full conformance, regression/API/white-box, examples, and proof examples
515
+ npm run conformance:report # conformance coverage summary by category
509
516
  node test/run-conformance.mjs
510
517
  node test/run-regression.mjs
511
518
  node test/run-examples.mjs
@@ -702,7 +702,7 @@ A conforming eyelang implementation supports the standard language described abo
702
702
 
703
703
  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.
704
704
 
705
- Conformance cases live in the repository under `test/conformance/`. They are run by `npm test` before the example suite, and can be run alone with `node test/run-conformance.mjs`. Positive cases have input programs under `conformance/cases/` and exact expected standard-output files under `conformance/expected/`; both use `.eye` so expected output remains eyelang-readable. Expected-error cases live under `conformance/errors/` with exact messages under `conformance/expected-errors/`. Expected-warning cases live under `conformance/warnings/` with exact `--warnings` stdout and stderr files under `conformance/expected-warnings/`.
705
+ Conformance cases live in the repository under `test/conformance/`. They are run by `npm test` before the example suite, and can be run alone with `node test/run-conformance.mjs`. Positive cases have input programs under `conformance/cases/` and exact expected standard-output files under `conformance/expected/`; both use `.eye` so expected output remains eyelang-readable. Expected-error cases live under `conformance/errors/` with exact messages under `conformance/expected-errors/`. Expected-warning cases live under `conformance/warnings/` with exact `--warnings` stdout and stderr files under `conformance/expected-warnings/`. The corpus is grouped by language area, including arithmetic, strings, lists, terms, atoms, variables, negation, declarations, materialization, rules, syntax, and errors.
706
706
 
707
707
  ## 15. Relationship to ISO Prolog
708
708
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyelang",
3
- "version": "1.7.3",
3
+ "version": "1.7.5",
4
4
  "description": "A small Prolog-like logic programming language for rules, goals, answers, and proofs.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -44,6 +44,7 @@
44
44
  "test:examples": "node test/run-examples.mjs",
45
45
  "test:regression": "node test/run-regression.mjs",
46
46
  "preversion": "npm test",
47
- "postversion": "git push origin HEAD --follow-tags"
47
+ "postversion": "git push origin HEAD --follow-tags",
48
+ "conformance:report": "node test/run-conformance-report.mjs"
48
49
  }
49
50
  }
@@ -20,7 +20,7 @@ Expected-warning cases consist of:
20
20
  - `conformance/expected-warnings/<name>.eye` — exact expected standard output;
21
21
  - `conformance/expected-warnings/<name>.txt` — exact expected standard error.
22
22
 
23
- Case names may be nested in category directories such as `atoms/`, `variables/`, `negation/`, or `syntax/`. Expected files mirror the same relative path.
23
+ Case names may be nested in category directories such as `arithmetic/`, `strings/`, `lists/`, `terms/`, `atoms/`, `variables/`, `negation/`, or `syntax/`. Expected files mirror the same relative path.
24
24
 
25
25
  ## Running the suite
26
26
 
@@ -36,6 +36,12 @@ Run only the conformance suite:
36
36
  node test/run-conformance.mjs
37
37
  ```
38
38
 
39
+ Summarize conformance coverage by category:
40
+
41
+ ```sh
42
+ npm run conformance:report
43
+ ```
44
+
39
45
  Run matching conformance cases by passing a filename or directory fragment:
40
46
 
41
47
  ```sh
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(aggregate_max(?key, ?value, missing(?value), ?bestKey, ?bestValue)).
@@ -0,0 +1,5 @@
1
+ materialize(answer, 2).
2
+ candidate(a, 3).
3
+ candidate(b, 1).
4
+ candidate(c, 2).
5
+ answer(?key, ?value) :- aggregate_min(score(?score), ?name, candidate(?name, ?score), ?key, ?value).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?n) :- countall(missing(?x), ?n).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?bag) :- findall(?x, missing(?x), ?bag).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?n) :- sumall(?x, missing(?x), ?n).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- between(1, 5, 3).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- between(4, 4, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- lt("P1Y", "P2Y"), gt("P1Y2M", "P1Y1M").
@@ -0,0 +1,3 @@
1
+ materialize(answer, 2).
2
+ answer(add, ?x) :- add(1.5, 2.25, ?x).
3
+ answer(div, ?x) :- div(7, 2, ?x).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 2).
2
+ answer(min, ?x) :- min(3, 2.5, ?x).
3
+ answer(max, ?x) :- max(3, 2.5, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- mod(-7, 3, ?x).
@@ -0,0 +1,4 @@
1
+ % Integer-preserving unary arithmetic.
2
+ materialize(answer, 2).
3
+ answer(neg, ?x) :- neg(7, ?x).
4
+ answer(abs, ?x) :- abs(-7, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(pow(2, -1, ?x)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- pow(9, 0, ?x).
@@ -0,0 +1,5 @@
1
+ materialize(answer, 2).
2
+ answer(floor, ?x) :- floor(-1.2, ?x).
3
+ answer(ceiling, ?x) :- ceiling(-1.2, ?x).
4
+ answer(trunc, ?x) :- trunc(-1.8, ?x).
5
+ answer(rounded, ?x) :- rounded(-1.5, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- smallest_divisor_from(17, 2, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(sqrt(-1, ?x)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(<https://example.org/a%20b?x=1#frag>).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 1).
2
+ '<=>'(ok).
3
+ answer(ok) :- '<=>'(ok).
@@ -0,0 +1,4 @@
1
+ % A lone graphic < remains a graphic atom, not an IRI opener.
2
+ materialize(answer, 1).
3
+ seed(<).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 1).
2
+ '<urn:example:predicate>'(ok).
3
+ answer(ok) :- '<urn:example:predicate>'(ok).
@@ -0,0 +1,4 @@
1
+ % Non-http absolute IRI atoms are ordinary atoms.
2
+ materialize(answer, 1).
3
+ seed(<mailto:alice@example.org>).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,4 @@
1
+ % Query strings and fragments are part of the IRI atom text.
2
+ materialize(answer, 1).
3
+ seed(<https://example.org/path?x=1#frag>).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,4 @@
1
+ % URN IRI atoms read back in angle-bracket form.
2
+ materialize(answer, 1).
3
+ seed(<urn:example:alpha>).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer('example:relative').
@@ -0,0 +1,4 @@
1
+ % Quoted absolute IRI atoms use canonical angle-bracket read-back.
2
+ materialize(answer, 1).
3
+ seed('urn:example:quoted').
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,3 @@
1
+ % atom_string/2 converts an IRI atom to its lexical string.
2
+ materialize(answer, 1).
3
+ answer(?text) :- atom_string(<urn:example:a>, ?text).
@@ -0,0 +1,3 @@
1
+ % eq/2 unifies angle and quoted spellings of the same absolute IRI atom.
2
+ materialize(answer, 1).
3
+ answer(ok) :- eq(<urn:example:a>, 'urn:example:a').
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- holds((likes(alice, tea), likes(bob, coffee)), likes(alice, tea)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(holds((p(a), q(b)), r(c))).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 3).
2
+ answer(?name, ?left, ?right) :- holds((edge(a, b), label(a, "A")), ?name, [?left, ?right]).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 1).
2
+ seed(a).
3
+ answer(ok) :- not(not(seed(a))).
@@ -0,0 +1,5 @@
1
+ materialize(answer, 1).
2
+ item(a).
3
+ item(b).
4
+ good(a).
5
+ answer(ok) :- not(forall(item(?x), good(?x))).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- forall(missing(?x), fail(?x)).
@@ -0,0 +1,5 @@
1
+ materialize(answer, 1).
2
+ item(a).
3
+ item(b).
4
+ blocked(b).
5
+ answer(?x) :- item(?x), not(blocked(?x)).
@@ -0,0 +1,4 @@
1
+ materialize(answer, 1).
2
+ choice(a).
3
+ choice(b).
4
+ answer(?x) :- once(choice(?x)).
@@ -0,0 +1,5 @@
1
+ materialize(answer, 1).
2
+ det(answer, 1).
3
+ semidet(aux, 1).
4
+ aux(ok).
5
+ answer(ok) :- aux(ok).
@@ -0,0 +1,5 @@
1
+ % Invalid advisory mode length is ignored as metadata but remains a fact.
2
+ materialize(answer, 1).
3
+ mode(edge, 2, [in]).
4
+ edge(a, b).
5
+ answer(ok) :- mode(edge, 2, [in]), edge(a, b).
@@ -0,0 +1,4 @@
1
+ % Declarations remain ordinary facts unless materialized output excludes them.
2
+ materialize(answer, 2).
3
+ table(path, 2).
4
+ answer(?name, ?arity) :- table(?name, ?arity).
@@ -0,0 +1,4 @@
1
+ % The empty list is a first-class term.
2
+ materialize(answer, 1).
3
+ seed([]).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,4 @@
1
+ materialize(answer, 2).
2
+ answer(head, ?x) :- head([a, b, c], ?x).
3
+ answer(rest, ?x) :- rest([a, b, c], ?x).
4
+ answer(last, ?x) :- last([a, b, c], ?x).
@@ -0,0 +1,4 @@
1
+ % Improper lists preserve their tail in read-back.
2
+ materialize(answer, 1).
3
+ seed([a, b | tail]).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 2).
2
+ answer(empty, ?x) :- length([], ?x).
3
+ answer(nested, ?x) :- length([[a], [b, c]], ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- list_to_set([pair(a, 1), pair(a, 1), pair(a, 2)], ?x).
@@ -0,0 +1,4 @@
1
+ % Lists can contain IRI atoms directly.
2
+ materialize(answer, 1).
3
+ seed([<urn:example:a>, <urn:example:b>]).
4
+ answer(?x) :- seed(?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(min_list([], ?x)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- nth0(2, [a, b, c], c).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(nth0(5, [a], ?x)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- reverse([], ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 2).
2
+ answer(?item, ?rest) :- select(?item, [a, b, a], ?rest).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- set_nth0(1, [a, b, c], z, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- slice([a, b, c, d], 1, 2, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(slice([a], 1, 2, ?x)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- sort([b(2), a(3), a(1)], ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- sum_list([], ?x).
@@ -0,0 +1,4 @@
1
+ materialize(answer, 2).
2
+ answer(sum, ?x) :- sum_list([5, -2, 7], ?x).
3
+ answer(min, ?x) :- min_list([5, -2, 7], ?x).
4
+ answer(max, ?x) :- max_list([5, -2, 7], ?x).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 2).
2
+ answer(take, ?x) :- take(0, [a, b], ?x).
3
+ answer(drop, ?x) :- drop(2, [a, b], ?x).
@@ -0,0 +1,4 @@
1
+ materialize(answer, 1).
2
+ answer(one).
3
+ answer(two, ignored).
4
+ answer(three, ignored, ignored).
@@ -0,0 +1,5 @@
1
+ % materialize/2 prints derived answers, not source facts for the same predicate.
2
+ materialize(answer, 1).
3
+ seed(a).
4
+ answer(source).
5
+ answer(?x) :- seed(?x).
@@ -0,0 +1,4 @@
1
+ % Negation fails when its inner goal succeeds.
2
+ materialize(answer, 1).
3
+ seen(a).
4
+ answer(ok) :- not(seen(a)).
@@ -0,0 +1,3 @@
1
+ % Negation succeeds when its inner goal has no solution.
2
+ materialize(answer, 1).
3
+ answer(ok) :- not(missing(fact)).
@@ -0,0 +1,4 @@
1
+ materialize(answer, 2).
2
+ parent(alice, bob).
3
+ parent(bob, clara).
4
+ answer(?x, ?z) :- parent(?x, ?y), parent(?y, ?z).
@@ -0,0 +1,7 @@
1
+ materialize(path, 2).
2
+ table(path, 2).
3
+ edge(a, b).
4
+ edge(b, c).
5
+ edge(c, d).
6
+ path(?x, ?y) :- edge(?x, ?y).
7
+ path(?x, ?z) :- edge(?x, ?y), path(?y, ?z).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?atom) :- atom_string(?atom, "hello_world").
@@ -0,0 +1,3 @@
1
+ materialize(answer, 2).
2
+ answer(lower, ?x) :- lowercase("HelloWorld", ?x).
3
+ answer(upper, ?x) :- uppercase(helloWorld, ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- contains("abc", "").
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?text) :- join([a, "b", 3], "-", ?text).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- matches("beta", "alpha|beta").
@@ -0,0 +1,2 @@
1
+ materialize(answer, 2).
2
+ answer(?first, ?last) :- matches("Ada Lovelace", "^(?<first>[A-Za-z]+) (?<last>[A-Za-z]+)$", ?ctx), holds(?ctx, first, ?first), holds(?ctx, last, ?last).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not_matches("abc", "x|y").
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?n) :- number_string(?n, "42").
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(number_string(?n, "four")).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?text) :- replace("abc", "", "X", ?text).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?parts) :- split("abc", ",", ?parts).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(substring("abc", 2, 5, ?text)).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?text) :- substring("abcdef", 2, 0, ?text).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?text) :- term_string(pair(<urn:example:a>, [1, two]), ?text).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- trim(" hello ", ?x).
@@ -0,0 +1,4 @@
1
+ % Leading comment.
2
+ materialize(answer, 1). % trailing comment
3
+
4
+ answer(ok). % another trailing comment
@@ -0,0 +1,5 @@
1
+ % Parentheses may group a body conjunction without changing meaning.
2
+ materialize(answer, 1).
3
+ a(ok).
4
+ b(ok).
5
+ answer(?x) :- (a(?x), b(?x)).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 1).
2
+ answer('line
3
+ break').
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer("a b").
@@ -0,0 +1,7 @@
1
+ materialize(answer, 1).
2
+ table(reachable, 2).
3
+ edge(a, b).
4
+ edge(b, c).
5
+ reachable(?x, ?z) :- reachable(?x, ?y), edge(?y, ?z).
6
+ reachable(?x, ?y) :- edge(?x, ?y).
7
+ answer(?x) :- reachable(a, ?x).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 2).
2
+ answer(first, ?x) :- arg(1, pair(a, b), ?x).
3
+ answer(second, ?x) :- arg(2, pair(a, b), ?x).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(arg(0, pair(a, b), ?x)).
@@ -0,0 +1,3 @@
1
+ % compound_name_arguments/3 observes atoms as name plus empty argument list.
2
+ materialize(answer, 2).
3
+ answer(?name, ?args) :- compound_name_arguments(nil, ?name, ?args).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(compound_name_arguments(?x, pair, [a | b])).
@@ -0,0 +1,3 @@
1
+ % Building a term with an empty argument list yields an atom, not nil().
2
+ materialize(answer, 1).
3
+ answer(?term) :- compound_name_arguments(?term, nil, []).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- compound_name_arguments(?x, pair, [a, b]).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 2).
2
+ answer(?name, ?args) :- compound_name_arguments(<urn:example:a>, ?name, ?args).
@@ -0,0 +1,3 @@
1
+ % Atoms are zero-arity terms for functor/3.
2
+ materialize(answer, 2).
3
+ answer(?name, ?arity) :- functor(nil, ?name, ?arity).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 3).
2
+ answer(number, ?name, ?arity) :- functor(42, ?name, ?arity).
3
+ answer(string, ?name, ?arity) :- functor("hi", ?name, ?arity).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?text) :- term_string([<urn:example:a>, <urn:example:b>], ?text).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(ok) :- not(eq(pair(a), pair(a, b))).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?tail) :- eq([a, b, c], [a | ?tail]).
@@ -0,0 +1,2 @@
1
+ materialize(answer, 1).
2
+ answer(?x) :- eq(pair(?x, box(?x)), pair(a, box(a))).
@@ -0,0 +1,3 @@
1
+ materialize(answer, 1).
2
+ answer(atom_number) :- eq(a, "a").
3
+ answer(number_string) :- eq(7, "7").
@@ -0,0 +1,4 @@
1
+ % Each ?_ occurrence is fresh, so these two goals do not have to agree.
2
+ materialize(answer, 1).
3
+ pair(a, b).
4
+ answer(ok) :- pair(?_, ?_).
@@ -0,0 +1,5 @@
1
+ materialize(answer, 1).
2
+ helper(a).
3
+ helper(b).
4
+ answer(?x) :- helper(?x).
5
+ answer(?x) :- helper(?x), eq(?x, c).
@@ -0,0 +1,4 @@
1
+ % The question mark, not letter case, marks variables.
2
+ materialize(answer, 1).
3
+ item(ok).
4
+ answer(?X) :- item(?X).