eyeprolog 1.5.84 → 1.5.85

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 (83) hide show
  1. package/conformance-report.md +2 -2
  2. package/package.json +1 -1
  3. package/src/quads.js +39 -13
  4. package/test/conformance/NEUMERKEL-LATEST.md +3 -7
  5. package/test/conformance/README.md +1 -1
  6. package/test/conformance/THIRD_PARTY.md +1 -0
  7. package/test/conformance/cases/iso/scryer_backslash_atom.pl +8 -0
  8. package/test/conformance/cases/iso/scryer_bare_exponent_lexing.pl +10 -0
  9. package/test/conformance/cases/iso/scryer_bracket_and_curly_term_parsing.pl +12 -0
  10. package/test/conformance/cases/iso/scryer_default_prefix_operator_priorities.pl +8 -0
  11. package/test/conformance/cases/iso/scryer_dollar_sign_atoms.pl +10 -0
  12. package/test/conformance/cases/iso/scryer_empty_list_atom_functor.pl +7 -0
  13. package/test/conformance/cases/iso/scryer_exponent_minus_lexing.pl +12 -0
  14. package/test/conformance/cases/iso/scryer_large_float_exponent.pl +11 -0
  15. package/test/conformance/cases/iso/scryer_line_continuation_in_quoted_atoms.pl +15 -0
  16. package/test/conformance/cases/iso/scryer_lower_priority_prefix_with_infix.pl +11 -0
  17. package/test/conformance/cases/iso/scryer_mixed_prefix_infix_operator_priority.pl +11 -0
  18. package/test/conformance/cases/iso/scryer_op_error_conditions.pl +29 -0
  19. package/test/conformance/cases/iso/scryer_operator_application_vs_functor_notation.pl +10 -0
  20. package/test/conformance/cases/iso/scryer_postfix_operator_negative_number.pl +10 -0
  21. package/test/conformance/cases/iso/scryer_prefix_minus_chain.pl +8 -0
  22. package/test/conformance/cases/iso/scryer_quote_and_char_code_literals.pl +16 -0
  23. package/test/conformance/cases/iso/scryer_special_atom_names.pl +10 -0
  24. package/test/conformance/cases/iso/scryer_subnormal_float_underflow.pl +9 -0
  25. package/test/conformance/cases/iso/scryer_unary_plus_compound.pl +12 -0
  26. package/test/conformance/cases/iso/scryer_user_operator_with_prefix_minus.pl +14 -0
  27. package/test/conformance/cases/iso/trealla_append_modes.pl +11 -0
  28. package/test/conformance/cases/iso/trealla_arithmetic_constants.pl +7 -0
  29. package/test/conformance/cases/iso/trealla_atom_codes_unicode.pl +11 -0
  30. package/test/conformance/cases/iso/trealla_bignum_arithmetic.pl +32 -0
  31. package/test/conformance/cases/iso/trealla_call_missing_extended_arity.pl +6 -0
  32. package/test/conformance/cases/iso/trealla_findall_solution_independence.pl +9 -0
  33. package/test/conformance/cases/iso/trealla_float_parts_extremes.pl +25 -0
  34. package/test/conformance/cases/iso/trealla_forall_double_negation.pl +12 -0
  35. package/test/conformance/cases/iso/trealla_if_then_else_backtracking.pl +22 -0
  36. package/test/conformance/cases/iso/trealla_number_codes_char_literal.pl +6 -0
  37. package/test/conformance/cases/iso/trealla_shared_variable_unification.pl +63 -0
  38. package/test/conformance/cases/iso/trealla_term_variables_partial_list_error.pl +6 -0
  39. package/test/conformance/cases/iso/trealla_variable_goal_normalization.pl +11 -0
  40. package/test/conformance/cases/iso/trealla_write_canonical_operators.pl +26 -0
  41. package/test/conformance/cases/iso/trealla_write_term_duplicate_variable_names.pl +6 -0
  42. package/test/conformance/expected/iso/scryer_backslash_atom.pl +1 -0
  43. package/test/conformance/expected/iso/scryer_bare_exponent_lexing.pl +1 -0
  44. package/test/conformance/expected/iso/scryer_bracket_and_curly_term_parsing.pl +1 -0
  45. package/test/conformance/expected/iso/scryer_default_prefix_operator_priorities.pl +1 -0
  46. package/test/conformance/expected/iso/scryer_dollar_sign_atoms.pl +1 -0
  47. package/test/conformance/expected/iso/scryer_empty_list_atom_functor.pl +1 -0
  48. package/test/conformance/expected/iso/scryer_exponent_minus_lexing.pl +1 -0
  49. package/test/conformance/expected/iso/scryer_large_float_exponent.pl +1 -0
  50. package/test/conformance/expected/iso/scryer_line_continuation_in_quoted_atoms.pl +1 -0
  51. package/test/conformance/expected/iso/scryer_lower_priority_prefix_with_infix.pl +1 -0
  52. package/test/conformance/expected/iso/scryer_mixed_prefix_infix_operator_priority.pl +1 -0
  53. package/test/conformance/expected/iso/scryer_op_error_conditions.pl +5 -0
  54. package/test/conformance/expected/iso/scryer_operator_application_vs_functor_notation.pl +1 -0
  55. package/test/conformance/expected/iso/scryer_postfix_operator_negative_number.pl +1 -0
  56. package/test/conformance/expected/iso/scryer_prefix_minus_chain.pl +1 -0
  57. package/test/conformance/expected/iso/scryer_quote_and_char_code_literals.pl +1 -0
  58. package/test/conformance/expected/iso/scryer_special_atom_names.pl +1 -0
  59. package/test/conformance/expected/iso/scryer_subnormal_float_underflow.pl +1 -0
  60. package/test/conformance/expected/iso/scryer_unary_plus_compound.pl +1 -0
  61. package/test/conformance/expected/iso/scryer_user_operator_with_prefix_minus.pl +1 -0
  62. package/test/conformance/expected/iso/trealla_append_modes.pl +6 -0
  63. package/test/conformance/expected/iso/trealla_arithmetic_constants.pl +1 -0
  64. package/test/conformance/expected/iso/trealla_atom_codes_unicode.pl +2 -0
  65. package/test/conformance/expected/iso/trealla_bignum_arithmetic.pl +4 -0
  66. package/test/conformance/expected/iso/trealla_call_missing_extended_arity.pl +1 -0
  67. package/test/conformance/expected/iso/trealla_findall_solution_independence.pl +1 -0
  68. package/test/conformance/expected/iso/trealla_float_parts_extremes.pl +4 -0
  69. package/test/conformance/expected/iso/trealla_forall_double_negation.pl +1 -0
  70. package/test/conformance/expected/iso/trealla_if_then_else_backtracking.pl +5 -0
  71. package/test/conformance/expected/iso/trealla_number_codes_char_literal.pl +1 -0
  72. package/test/conformance/expected/iso/trealla_shared_variable_unification.pl +10 -0
  73. package/test/conformance/expected/iso/trealla_term_variables_partial_list_error.pl +1 -0
  74. package/test/conformance/expected/iso/trealla_variable_goal_normalization.pl +1 -0
  75. package/test/conformance/expected/iso/trealla_write_canonical_operators.pl +5 -0
  76. package/test/conformance/expected/iso/trealla_write_term_duplicate_variable_names.pl +2 -0
  77. package/test/fixtures/README.md +8 -11
  78. package/test/fixtures/prologue_quad.pl +166 -13
  79. package/test/neumerkel.mjs +7 -6
  80. package/test/regression/cases-regression.mjs +21 -38
  81. package/the-art-of-eyeprolog.md +1 -1
  82. package/test/fixtures/prologue_call_nth_quad.pl +0 -32
  83. package/test/fixtures/prologue_call_nth_quad_runner.pl +0 -2
@@ -24,7 +24,7 @@ bytes, avoiding a second live fetch and its race window.
24
24
  | context | 11 | 0 | 0 | 0 | 11 |
25
25
  | control | 15 | 0 | 0 | 0 | 15 |
26
26
  | explicit-tabling | 6 | 0 | 0 | 0 | 6 |
27
- | iso | 176 | 219 | 0 | 0 | 395 |
27
+ | iso | 211 | 219 | 0 | 0 | 430 |
28
28
  | lists | 52 | 3 | 0 | 0 | 55 |
29
29
  | modules | 2 | 0 | 0 | 0 | 2 |
30
30
  | negation | 8 | 0 | 19 | 0 | 27 |
@@ -37,7 +37,7 @@ bytes, avoiding a second live fetch and its race window.
37
37
  | terms | 26 | 3 | 0 | 0 | 29 |
38
38
  | unification | 18 | 0 | 0 | 0 | 18 |
39
39
  | variables | 16 | 7 | 0 | 0 | 23 |
40
- | **Total** | **498** | **274** | **19** | **21** | **812** |
40
+ | **Total** | **533** | **274** | **19** | **21** | **847** |
41
41
 
42
42
  ## DCG conformance clarification
43
43
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.5.84",
6
+ "version": "1.5.85",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/src/quads.js CHANGED
@@ -252,14 +252,29 @@ function checkAnswerPermutation(program, query, leaves, actual, alternative) {
252
252
 
253
253
  function malformedAlternative(query, alternative) {
254
254
  const queryNames = new Set(namedVariables(query).map((variable) => variable.name));
255
- for (const leaf of splitOperator(alternative, ';').map(describeLeaf)) {
255
+ const altLeaves = splitOperator(alternative, ';').map(describeLeaf);
256
+ // `sto` is written once, on the branch's first outcome, to declare the
257
+ // whole `;`-separated branch occurs-check/rational-tree dependent (see the
258
+ // matching `leaves.some((leaf) => leaf.sto)` in checkAlternative); a later
259
+ // leaf in the same branch carries that declaration too even though only
260
+ // the first leaf's text says so.
261
+ const branchSto = altLeaves.some((leaf) => leaf.sto);
262
+ for (const leaf of altLeaves) {
256
263
  if (leaf.malformed != null) return leaf.malformed;
257
264
  const names = new Set();
258
265
  const substitutions = [...leaf.bindings, ...leaf.approximations];
266
+ // A binding's left-hand variable may be a query variable, or an auxiliary
267
+ // variable this same answer description already introduced on an earlier
268
+ // binding's right-hand side. `Xs = [_A|_B], _B = [E|_B]` names the "rest
269
+ // of the same infinite structure" as _B before binding it -- the usual
270
+ // idiom for describing a rational-tree or repeating-pattern answer
271
+ // (see also substitutionMatches, which resolves these the same way).
272
+ const introduced = new Set(queryNames);
259
273
  for (const binding of substitutions) {
260
274
  const name = binding.args[0].name;
261
- if (!queryNames.has(name) || names.has(name)) return binding;
275
+ if (!introduced.has(name) || names.has(name)) return binding;
262
276
  names.add(name);
277
+ for (const variable of namedVariables(binding.args[1])) introduced.add(variable.name);
263
278
  }
264
279
  for (const binding of substitutions) {
265
280
  const name = binding.args[0].name;
@@ -276,7 +291,7 @@ function malformedAlternative(query, alternative) {
276
291
  // outside `sto`: an answer description should give each variable's
277
292
  // value in fully resolved form rather than in terms of a sibling
278
293
  // binding.
279
- if (!leaf.sto && referenced.some((variable) => names.has(variable.name))) return binding;
294
+ if (!branchSto && referenced.some((variable) => names.has(variable.name))) return binding;
280
295
  }
281
296
  }
282
297
  return null;
@@ -522,22 +537,33 @@ function substitutionMatches(query, bindings, approximations, actualEnv) {
522
537
  const queryVariablesByName = new Map(queryVariables.map((variable) => [variable.name, variable]));
523
538
  const expectedEnv = new Env();
524
539
  const rebound = new Set();
540
+ // A binding's left-hand variable may be a query variable, or an auxiliary
541
+ // variable this same answer description already introduced on an earlier
542
+ // binding's right-hand side (see malformedAlternative's matching
543
+ // `introduced` set): `Xs = [_A|_B], _B = [E|_B]` names the "rest of the
544
+ // same infinite structure" as _B before binding it, the usual idiom for
545
+ // describing a rational-tree or repeating-pattern answer.
546
+ const introduced = new Set(queryNames);
525
547
  for (const binding of [...bindings, ...approximations]) {
526
548
  const variable = binding.args[0];
527
- if (!queryNames.has(variable.name) || rebound.has(variable.name)) return false;
549
+ if (!introduced.has(variable.name) || rebound.has(variable.name)) return false;
528
550
  rebound.add(variable.name);
529
551
  if (binding.name === '=') {
530
552
  if (!unify(variable, binding.args[1], expectedEnv)) return false;
531
- continue;
553
+ } else {
554
+ // Approximate (~~) bindings compare against an actually observed value,
555
+ // which only exists for the query's own variables.
556
+ const actualVariable = queryVariablesByName.get(variable.name);
557
+ if (actualVariable == null) return false;
558
+ const actualValue = deref(actualVariable, actualEnv);
559
+ if (!approximatelyMatches(actualValue, binding.args[1])) return false;
560
+ // Once the approximate predicate has accepted the actual float, bind the
561
+ // expected-side variable to that exact observed term. This lets the
562
+ // ordinary variant matcher continue to check the rest of the answer,
563
+ // including variable sharing, without turning `~~` into a fuzzy unifier.
564
+ if (!unify(variable, copyResolved(actualValue, actualEnv), expectedEnv)) return false;
532
565
  }
533
- const actualVariable = queryVariablesByName.get(variable.name);
534
- const actualValue = deref(actualVariable, actualEnv);
535
- if (!approximatelyMatches(actualValue, binding.args[1])) return false;
536
- // Once the approximate predicate has accepted the actual float, bind the
537
- // expected-side variable to that exact observed term. This lets the
538
- // ordinary variant matcher continue to check the rest of the answer,
539
- // including variable sharing, without turning `~~` into a fuzzy unifier.
540
- if (!unify(variable, copyResolved(actualValue, actualEnv), expectedEnv)) return false;
566
+ for (const referenced of namedVariables(binding.args[1])) introduced.add(referenced.name);
541
567
  }
542
568
  const expected = compound('$quad_answer', queryVariables.map((variable) => copyResolved(variable, expectedEnv)));
543
569
  const actual = compound('$quad_answer', queryVariables.map((variable) => copyResolved(variable, actualEnv)));
@@ -1,6 +1,6 @@
1
1
  # EyeProlog — latest Neumerkel conformity
2
2
 
3
- Status: **PASS — 1 divergence to be addressed** — **718/719** discovered upstream cases passed.
3
+ Status: **PASS** — **758/758** discovered upstream cases passed.
4
4
 
5
5
  This tracked report records the latest upstream inventory successfully checked by EyeProlog.
6
6
  `npm test` fetches the eight TU Wien sources again and executes the discovered cases.
@@ -15,13 +15,9 @@ Counts are output from upstream, not hard-coded test constants.
15
15
  | dif/2 | 26 | 26 |
16
16
  | length/2 | 37 | 37 |
17
17
  | phrase/2,3 | 58 | 58 |
18
- | Prologue draft | 32 | 33 |
18
+ | Prologue draft | 72 | 72 |
19
19
  | setup_call_cleanup/3 | 25 | 25 |
20
- | **Total** | **718** | **719** |
21
-
22
- ## Known divergences
23
-
24
- - **Prologue draft** (line 118): bounded=false: EyeProlog reports no max_integer value at all (ISO 7.11.1.1), so this quad's evaluation_error(int_overflow) | Max = unbounded pair never applies
20
+ | **Total** | **758** | **758** |
25
21
 
26
22
  ## Upstream sources
27
23
 
@@ -138,7 +138,7 @@ Selected cases are adapted from the ISO and standard-core suites of Logtalk,
138
138
  Scryer Prolog, Trealla Prolog, and SWI-Prolog. Their upstream identifiers and licenses
139
139
  are recorded in [THIRD_PARTY.md](THIRD_PARTY.md).
140
140
 
141
- The corpus has 395 cases in `iso/` and 812 file-based conformance cases in total. Of those, 11 cases in `stc/` are explicitly labelled working-draft review evidence rather than normative ISO claims. The strict-reader WG17 syntax matrix is discovered dynamically and executed live by the Neumerkel gate, the same as its other seven TU Wien sources; release/report checks separately verify the tracked `NEUMERKEL-LATEST.md`. The generated `conformance-report.md` records local corpus totals and links to that live evidence. Together with regression, documentation-sync, API, example, and book-example checks, `npm test` is the release gate.
141
+ The corpus has 430 cases in `iso/` and 847 file-based conformance cases in total. Of those, 11 cases in `stc/` are explicitly labelled working-draft review evidence rather than normative ISO claims. The strict-reader WG17 syntax matrix is discovered dynamically and executed live by the Neumerkel gate, the same as its other seven TU Wien sources; release/report checks separately verify the tracked `NEUMERKEL-LATEST.md`. The generated `conformance-report.md` records local corpus totals and links to that live evidence. Together with regression, documentation-sync, API, example, and book-example checks, `npm test` is the release gate.
142
142
 
143
143
  ## Updating expected output
144
144
 
@@ -70,6 +70,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70
70
 
71
71
  Selected standard-core cases under `iso/` are adapted from the numbered tests
72
72
  in [`tests/tests`](https://github.com/trealla-prolog/trealla/tree/main/tests/tests)
73
+ and [`tests/issues`](https://github.com/trealla-prolog/trealla/tree/main/tests/issues)
73
74
  in Trealla Prolog. Each adapted file identifies its upstream test file. The
74
75
  cases were rewritten for EyeProlog's query and exact-output harness.
75
76
 
@@ -0,0 +1,8 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 41. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: backslash_atom(A)
5
+
6
+ backslash_atom(A) :-
7
+ A = ('\\'),
8
+ A = (\).
@@ -0,0 +1,10 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 49. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(9, xf, e9).
5
+
6
+ %% goal: bare_exponent_lexing(X)
7
+
8
+ bare_exponent_lexing(X) :-
9
+ X = (1e9),
10
+ X = e9(1).
@@ -0,0 +1,12 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 291, 307, and 309. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: bracket_and_curly_term_parsing(A, B, C)
5
+
6
+ bracket_and_curly_term_parsing(A, B, C) :-
7
+ A = [(a,b)],
8
+ A = [','(a,b)],
9
+ B = [/**/],
10
+ B == [],
11
+ C = {a,b},
12
+ C = '{}'(','(a,b)).
@@ -0,0 +1,8 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 79-80. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: default_prefix_operator_priorities(A, B)
5
+
6
+ default_prefix_operator_priorities(A, B) :-
7
+ current_op(A, fy, -),
8
+ current_op(B, fy, +).
@@ -0,0 +1,10 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 198-199. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: dollar_sign_atoms(A, B)
5
+
6
+ dollar_sign_atoms(A, B) :-
7
+ atom($-),
8
+ atom(-$),
9
+ A = ($-),
10
+ B = (-$).
@@ -0,0 +1,7 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 97. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: empty_list_atom_functor(X)
5
+
6
+ empty_list_atom_functor(X) :-
7
+ '[]'(1) = [ ](X).
@@ -0,0 +1,12 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 50-51, 204, and 220. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(9, xf, e).
5
+
6
+ %% goal: exponent_minus_lexing(X, Y)
7
+
8
+ exponent_minus_lexing(X, Y) :-
9
+ X = (1e-9),
10
+ X = -(e(1), 9),
11
+ Y = (1.0e- 9),
12
+ Y = -(e(1.0), 9).
@@ -0,0 +1,11 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 53. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: large_float_exponent(X)
5
+
6
+ large_float_exponent(X) :-
7
+ X = 1.0e100,
8
+ float(X),
9
+ X > 1.0e99,
10
+ Y is X / 10.0,
11
+ Y =:= 1.0e99.
@@ -0,0 +1,15 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 7-10. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: line_continuation_in_quoted_atoms(A, B, C)
5
+
6
+ line_continuation_in_quoted_atoms(A, B, C) :-
7
+ A = '\
8
+ ',
9
+ A == '',
10
+ B = '\
11
+ a',
12
+ B == a,
13
+ C = 'a\
14
+ b',
15
+ C == 'a b'.
@@ -0,0 +1,11 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 164. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(7, fy, p).
5
+ :- op(9, yfx, p).
6
+
7
+ %% goal: lower_priority_prefix_with_infix(T)
8
+
9
+ lower_priority_prefix_with_infix(T) :-
10
+ T = (1 p p p 2),
11
+ T = p(1, p(p(2))).
@@ -0,0 +1,11 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 163. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(9, fy, p).
5
+ :- op(9, xfy, p).
6
+
7
+ %% goal: mixed_prefix_infix_priority(T)
8
+
9
+ mixed_prefix_infix_priority(T) :-
10
+ T = (1 p p p 2),
11
+ T = p(1, p(p(2))).
@@ -0,0 +1,29 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 70-72, 99, 158, 237, and 268. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: comma_operator_immutable(E1, E2, E3)
5
+
6
+ comma_operator_immutable(E1, E2, E3) :-
7
+ catch((op(1000,xfy,','), fail), error(E1, _), true),
8
+ catch((op(1001,xfy,','), fail), error(E2, _), true),
9
+ catch((op(0,xfy,','), fail), error(E3, _), true).
10
+
11
+ %% goal: bar_low_priority_rejected(E)
12
+
13
+ bar_low_priority_rejected(E) :-
14
+ catch((op(999,xfy,'|'), fail), error(E, _), true).
15
+
16
+ %% goal: invalid_operator_specifier(E)
17
+
18
+ invalid_operator_specifier(E) :-
19
+ catch((op(100,yfy,foo), fail), error(E, _), true).
20
+
21
+ %% goal: curly_braces_operator_rejected(E)
22
+
23
+ curly_braces_operator_rejected(E) :-
24
+ catch((op(500,xfy,'{}'), fail), error(E, _), true).
25
+
26
+ %% goal: infix_postfix_clash_rejected(E)
27
+
28
+ infix_postfix_clash_rejected(E) :-
29
+ catch((op(699,xf,>), fail), error(E, _), true).
@@ -0,0 +1,10 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 234-235. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(400, fx, f).
5
+
6
+ %% goal: space_before_paren_is_operator_application(T)
7
+
8
+ space_before_paren_is_operator_application(T) :-
9
+ T = (f (1,2)),
10
+ T = f(','(1,2)).
@@ -0,0 +1,10 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 55. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(1, yf, yf1).
5
+
6
+ %% goal: postfix_operator_negative_number(T)
7
+
8
+ postfix_operator_negative_number(T) :-
9
+ T = {-1 yf1},
10
+ T = {yf1(-1)}.
@@ -0,0 +1,8 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, test
2
+ % 236. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: prefix_minus_chain(X)
5
+
6
+ prefix_minus_chain(X) :-
7
+ X = (a- - -b),
8
+ X = -(a, -(-(b))).
@@ -0,0 +1,16 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 100, 103, 114-116, and 165. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: quote_and_char_code_literals(A, B, C, D)
5
+
6
+ quote_and_char_code_literals(A, B, C, D) :-
7
+ '''' = '\'',
8
+ A = '\141\141',
9
+ A == a141,
10
+ B = 0'\',
11
+ integer(B),
12
+ C = 0''',
13
+ integer(C),
14
+ C == B,
15
+ D = '.''-''.',
16
+ atom(D).
@@ -0,0 +1,10 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 308 and 324. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: special_atom_names(A, B)
5
+
6
+ special_atom_names(A, B) :-
7
+ A = '.+',
8
+ atom(A),
9
+ B = '%',
10
+ atom(B).
@@ -0,0 +1,9 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 172-173. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: subnormal_float_underflow(X)
5
+
6
+ subnormal_float_underflow(X) :-
7
+ X is 10.0** -323,
8
+ X > 0.0,
9
+ X =:= 1.0e-323.
@@ -0,0 +1,12 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 65-66 and 318. See test/conformance/THIRD_PARTY.md.
3
+
4
+ %% goal: unary_plus_compound(A, B)
5
+
6
+ unary_plus_compound(A, B) :-
7
+ compound(+1),
8
+ compound(+ 1),
9
+ A = (+1),
10
+ A = +(1),
11
+ B = (+ (1*2)^3),
12
+ B = +((1*2)^3).
@@ -0,0 +1,14 @@
1
+ % Adapted from Scryer Prolog tests-pl/iso-conformity-tests.pl, tests
2
+ % 215, 248, and 249. See test/conformance/THIRD_PARTY.md.
3
+
4
+ :- op(100, yfx, ~).
5
+
6
+ %% goal: user_operator_with_prefix_minus(A, B, C)
7
+
8
+ user_operator_with_prefix_minus(A, B, C) :-
9
+ A = (- (1~2~3)),
10
+ A = -(~(~(1,2),3)),
11
+ B = (- (1~2)),
12
+ B = -(~(1,2)),
13
+ C = (1~2),
14
+ C = ~(1,2).
@@ -0,0 +1,11 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0046.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: append_concat(X0)
4
+
5
+ append_concat(L) :-
6
+ append([a,b],[c,d],L).
7
+
8
+ %% goal: append_split(X0, X1)
9
+
10
+ append_split(L1, L2) :-
11
+ append(L1, L2, [a,b,c,d]).
@@ -0,0 +1,7 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0066.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: euler_and_int_division(X0, X1)
4
+
5
+ euler_and_int_division(E, Q) :-
6
+ E is e,
7
+ Q is 1 / 10.
@@ -0,0 +1,11 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0034.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: atom_codes_cjk(ok)
4
+
5
+ atom_codes_cjk(ok) :-
6
+ atom_codes('一二三', [19968, 20108, 19977]).
7
+
8
+ %% goal: atom_codes_cjk_reverse(X0)
9
+
10
+ atom_codes_cjk_reverse(Atom) :-
11
+ atom_codes(Atom, [19968, 20108, 19977]).
@@ -0,0 +1,32 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0079.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: bignum_ops(X0, X1, X2, X3, X4)
4
+
5
+ bignum_ops(N1, GcdA, GcdB, Mod, Div) :-
6
+ N1 is -123456789012345678901234567890,
7
+ N1 =:= -123456789012345678901234567890,
8
+ GcdA is gcd(987654321098765432109876543210, 42),
9
+ GcdA =:= 42,
10
+ GcdB is gcd(987654321098765432109876543210, 123456789012345678901234567890),
11
+ GcdB =:= 9000000000900000000090,
12
+ Mod is 15241578753238836750495351562536198787501905199875019052100 mod 1234567890123456789123,
13
+ Div is 15241578753238836750495351562536198787501905199875019052100 div 12345678901234567891234567.
14
+
15
+ %% goal: bignum_float_conversion(X0)
16
+
17
+ bignum_float_conversion(F) :-
18
+ F is float(1881676372353657772546715999894626455109783106026821047606410765129148590562263).
19
+
20
+ %% goal: bignum_mod_rem_agree_for_positive_operands(X0, X1)
21
+
22
+ bignum_mod_rem_agree_for_positive_operands(Mod, Rem) :-
23
+ Mod is 15241578753238836750495351562536198787501905199875019052100 mod 1234567890123456789123,
24
+ Rem is 15241578753238836750495351562536198787501905199875019052100 rem 1234567890123456789123,
25
+ Mod =:= Rem.
26
+
27
+ %% goal: bignum_gcd_commutative(X0, X1)
28
+
29
+ bignum_gcd_commutative(A, B) :-
30
+ A is gcd(987654321098765432109876543210, 42),
31
+ B is gcd(42, 987654321098765432109876543210),
32
+ A =:= B.
@@ -0,0 +1,6 @@
1
+ % Adapted from Trealla Prolog tests/issues/test0159.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: call_extends_missing_arity(X0, X1)
4
+
5
+ call_extends_missing_arity(Error, Context) :-
6
+ catch(call(true, false), error(Error, Context), true).
@@ -0,0 +1,9 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0071.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: findall_solutions_are_independent_copies(ok)
4
+
5
+ findall_solutions_are_independent_copies(ok) :-
6
+ findall(I, member(I, [A,B,B,A]), [A1,B1,B2,A2]),
7
+ A1 \== A2,
8
+ B1 \== B2,
9
+ A1 \== B1.
@@ -0,0 +1,25 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0117.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: float_parts_1e30(X0, X1)
4
+
5
+ float_parts_1e30(I, F) :-
6
+ I is float_integer_part(1.0e30),
7
+ F is float_fractional_part(1.0e30).
8
+
9
+ %% goal: float_parts_neg1e30(X0, X1)
10
+
11
+ float_parts_neg1e30(I, F) :-
12
+ I is float_integer_part(-1.0e30),
13
+ F is float_fractional_part(-1.0e30).
14
+
15
+ %% goal: float_parts_1e300(X0, X1)
16
+
17
+ float_parts_1e300(I, F) :-
18
+ I is float_integer_part(1.0e300),
19
+ F is float_fractional_part(1.0e300).
20
+
21
+ %% goal: float_parts_zero(X0, X1)
22
+
23
+ float_parts_zero(I, F) :-
24
+ I is float_integer_part(0.0),
25
+ F is float_fractional_part(0.0).
@@ -0,0 +1,12 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0010.pl, test0011.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ :- dynamic(seen/2).
4
+
5
+ upto(N, X) :- N > 0, N1 is N - 1, upto(N1, X).
6
+ upto(N, X) :- N > 0, X = N.
7
+
8
+ %% goal: forall_via_double_negation(X0)
9
+
10
+ forall_via_double_negation(Pairs) :-
11
+ \+ (upto(3, I), upto(I, J), \+ assertz(seen(I, J))),
12
+ findall(I-J, retract(seen(I, J)), Pairs).
@@ -0,0 +1,22 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0045.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ cond(1).
4
+ cond(2).
5
+
6
+ ok(a).
7
+ ok(b).
8
+
9
+ %% goal: then_branch_backtracks(X0)
10
+
11
+ then_branch_backtracks(X) :-
12
+ (true -> ok(X) ; fail).
13
+
14
+ %% goal: else_branch_backtracks(X0)
15
+
16
+ else_branch_backtracks(X) :-
17
+ (fail -> fail ; ok(X)).
18
+
19
+ %% goal: cond_commits_to_first_solution(X0)
20
+
21
+ cond_commits_to_first_solution(X) :-
22
+ (cond(X) -> true ; true).
@@ -0,0 +1,6 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0102.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: number_codes_char_literal(X0)
4
+
5
+ number_codes_char_literal(N) :-
6
+ number_codes(N, [48, 39, 92, 110]).
@@ -0,0 +1,63 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0064.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ :- dynamic(p/2).
4
+ :- dynamic(p/3).
5
+
6
+ p(Z, Z).
7
+ clouds(are, nice).
8
+ p(Z, h(Z, W), f(W)).
9
+
10
+ %% goal: fact_unifies_leaving_variable_unbound(ok)
11
+
12
+ fact_unifies_leaving_variable_unbound(ok) :-
13
+ findall(Z, p(Z, Z), [Z]),
14
+ var(Z).
15
+
16
+ %% goal: distinct_arguments_reject(ok)
17
+
18
+ distinct_arguments_reject(ok) :-
19
+ \+ p(z, w).
20
+
21
+ %% goal: repeated_argument_accepts(ok)
22
+
23
+ repeated_argument_accepts(ok) :-
24
+ p(w, w).
25
+
26
+ %% goal: distinct_fact_arguments_reject(ok)
27
+
28
+ distinct_fact_arguments_reject(ok) :-
29
+ \+ clouds(Z, Z).
30
+
31
+ %% goal: fact_second_argument(X0)
32
+
33
+ fact_second_argument(Zs) :-
34
+ findall(Z, clouds(are, Z), Zs).
35
+
36
+ %% goal: nested_pattern_rejects_conflict(ok)
37
+
38
+ nested_pattern_rejects_conflict(ok) :-
39
+ \+ p(z, h(z, z), f(w)).
40
+
41
+ %% goal: nested_pattern_accepts(ok)
42
+
43
+ nested_pattern_accepts(ok) :-
44
+ p(z, h(z, w), f(w)).
45
+
46
+ %% goal: nested_shared_variable_binds_consistently(X0)
47
+
48
+ nested_shared_variable_binds_consistently(Ws) :-
49
+ findall(W, p(z, h(z, W), f(w)), Ws).
50
+
51
+ %% goal: nested_shared_variable_all_positions(X0)
52
+
53
+ nested_shared_variable_all_positions(Zs) :-
54
+ findall(Z, p(Z, h(Z, w), f(Z)), Zs).
55
+
56
+ %% goal: retract_reassert_roundtrip(ok)
57
+
58
+ retract_reassert_roundtrip(ok) :-
59
+ retract(p(_, _, _)),
60
+ assertz(p(Z, h(Z, W), f(W))),
61
+ p(f(f(a)), h(f(f(a)), f(a)), f(f(a))),
62
+ retract(p(Z, h(Z, W), f(W))),
63
+ \+ clause(p(_, _, _), true).
@@ -0,0 +1,6 @@
1
+ % Adapted from Trealla Prolog tests/tests/test0074.pl.
2
+ % See test/conformance/THIRD_PARTY.md.
3
+ %% goal: term_variables_partial_list_type_error(ok)
4
+
5
+ term_variables_partial_list_type_error(ok) :-
6
+ catch(term_variables(t, [_, _|a]), error(type_error(list, [_, _|a]), _), true).