eyeprolog 1.3.31 → 1.3.32
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.
- package/README.md +4 -2
- package/package.json +1 -1
- package/src/solver.js +1 -1
- package/src/standard-library.js +1 -1
- package/test/conformance/ISO-COMPLIANCE.md +4 -4
- package/test/conformance/ISO-IMPLEMENTATION-DEFINED.md +146 -0
- package/test/conformance/ISO-MATRIX.md +7 -6
- package/test/run-regression.mjs +37 -2
- package/the-art-of-eyeprolog.md +8 -4
package/README.md
CHANGED
|
@@ -182,6 +182,8 @@ modules, DCGs, quads, libraries, proofs, and the other documented extensions.
|
|
|
182
182
|
|
|
183
183
|
The auditable processor-requirement checklist lives in
|
|
184
184
|
[`test/conformance/ISO-COMPLIANCE.md`](test/conformance/ISO-COMPLIANCE.md).
|
|
185
|
+
The ISO 5.4 implementation-defined/implementation-specific decision index is
|
|
186
|
+
[`test/conformance/ISO-IMPLEMENTATION-DEFINED.md`](test/conformance/ISO-IMPLEMENTATION-DEFINED.md).
|
|
185
187
|
The separate [WG17 syntax ledger](test/conformance/WG17-SYNTAX-STATUS.md)
|
|
186
188
|
records executable dispositions for the vendored active upstream WG17 syntax
|
|
187
189
|
cases and runs as part of `npm test`. Reviewed cases can pin exact outcomes;
|
|
@@ -211,7 +213,7 @@ left-associative operators, so state is handed repeatedly from one nonterminal
|
|
|
211
213
|
to the next rather than hidden in host code.
|
|
212
214
|
|
|
213
215
|
Deep finite DCG traversal is kept relational but does not have to consume one
|
|
214
|
-
general solver frame per token. In particular, the interoperable
|
|
216
|
+
general solver frame per token. In particular, the interoperable `... //0`
|
|
215
217
|
helper from `library(iso_ext)` can scan a finite compact list iteratively, and a
|
|
216
218
|
following grammar that is statically known to leave the DCG state unchanged can
|
|
217
219
|
be continued without rebuilding a full clause-resolution frame for every
|
|
@@ -242,7 +244,7 @@ headroom, so an exhausted finite heap is reported as a catchable
|
|
|
242
244
|
`resource_error(memory)` instead of degenerating into quadratic list checks.
|
|
243
245
|
|
|
244
246
|
`library(iso_ext)` is also accepted as a common interop module name.
|
|
245
|
-
EyeProlog exports `call_nth/2`, `time/1`, and the DCG helper
|
|
247
|
+
EyeProlog exports `call_nth/2`, `time/1`, and the DCG helper `... //0` there.
|
|
246
248
|
The latter describes an arbitrary number of input elements and supports the
|
|
247
249
|
nonterminal hand-off benchmark discussed in issue #49. These common predicates
|
|
248
250
|
may be imported explicitly, while source/CLI/API dependency loading can resolve
|
package/package.json
CHANGED
package/src/solver.js
CHANGED
|
@@ -1333,7 +1333,7 @@ function bundledEllipsisPlan(solver, group, goal, rest, env) {
|
|
|
1333
1333
|
}
|
|
1334
1334
|
|
|
1335
1335
|
// length/2 and other native constructors can leave a known finite list as a
|
|
1336
|
-
// compact spine. The ordinary
|
|
1336
|
+
// compact spine. The ordinary ... //0 relation simply enumerates every
|
|
1337
1337
|
// suffix of such a list; doing that directly avoids clause freshening and
|
|
1338
1338
|
// recursive solver depth for every consumed element. Non-compact and open
|
|
1339
1339
|
// list cases retain the ordinary Prolog definition.
|
package/src/standard-library.js
CHANGED
|
@@ -118,7 +118,7 @@ export const eyePrologInteropAutoload = Object.freeze({
|
|
|
118
118
|
// allowing Trealla-style unqualified source to use the same autoload entry.
|
|
119
119
|
'call_nth/2': 'iso_ext',
|
|
120
120
|
// Trealla exposes time/1 as a meta timing predicate and library(iso_ext)
|
|
121
|
-
// supplies
|
|
121
|
+
// supplies ... //0. Autoload both so UWN's DCG hand-off benchmark runs
|
|
122
122
|
// unchanged while their implementations remain outside the ISO core.
|
|
123
123
|
'time/1': 'iso_ext',
|
|
124
124
|
'.../2': 'iso_ext',
|
|
@@ -21,9 +21,9 @@ error-ordering alternative to an individual executable assertion.
|
|
|
21
21
|
| 5.1(a) prepare conforming Prolog text | audit | Clause 6 parser/tokenizer coverage, directive coverage, syntax-error corpus, and the [complete vendored WG17 syntax matrix](WG17-SYNTAX-STATUS.md). Wider shall-by-shall text-processing audit remains open. |
|
|
22
22
|
| 5.1(b) execute conforming Prolog goals | audit | Clause 7-9 conformance corpus plus regression/API/example gates. A normative goal-semantics ledger is still being expanded. |
|
|
23
23
|
| 5.1(c) reject nonconforming text/read-terms | audit | Dedicated syntax-error cases and strict-core extension rejection. Exhaustive lexical rejection coverage remains open. |
|
|
24
|
-
| 5.1(d) document permitted variations |
|
|
24
|
+
| 5.1(d) document permitted variations | covered | The clause-by-clause [ISO 5.4 decision index](ISO-IMPLEMENTATION-DEFINED.md) records every explicit implementation-defined decision found in the Part 1 + Corrigenda baseline and separately inventories implementation-specific extension families. Rows marked `audit gap` remain conformance work, but the variation is no longer undocumented. |
|
|
25
25
|
| 5.1(e) offer a strictly conforming mode | covered | `--iso-strict` and API option `isoStrict: true` restrict the processor to the Part 1 + Corrigenda 1-3 core language surface, remove EyeProlog-only registry/flag/operator features, and disable automatic tabling/recursion guards. |
|
|
26
|
-
| 5.4 accompanying documentation |
|
|
26
|
+
| 5.4 accompanying documentation | covered | *The Art of EyeProlog* remains the implementation reference; [ISO-IMPLEMENTATION-DEFINED.md](ISO-IMPLEMENTATION-DEFINED.md) is the closed clause-by-clause 5.4 decision index and points each decision to implementation evidence or an explicit audit gap. |
|
|
27
27
|
| 5.5 extensions preserve standard text | covered | Default mode retains EyeProlog extensions; strict core mode removes their language/runtime interpretation. Regression tests ensure the default profile remains unchanged. |
|
|
28
28
|
|
|
29
29
|
## Normative language families
|
|
@@ -95,6 +95,6 @@ ISO/IEC 13211-1 processor” until all of the following are true:
|
|
|
95
95
|
difference explained or fixed;
|
|
96
96
|
4. prescribed modes, errors, side effects, and relevant error precedence for
|
|
97
97
|
every Part 1 built-in have executable coverage;
|
|
98
|
-
5. every
|
|
99
|
-
|
|
98
|
+
5. every `audit gap` recorded in the ISO 5.4 decision index is either fixed or
|
|
99
|
+
explicitly excluded from the strict-conformance claim; and
|
|
100
100
|
6. an external conformance run has found no unexplained deviations.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# ISO/IEC 13211-1 implementation-defined and implementation-specific profile
|
|
2
|
+
|
|
3
|
+
This is the clause-by-clause ISO 5.4 decision index for EyeProlog. The
|
|
4
|
+
normative baseline used for this table is **ISO/IEC 13211-1:1995** together
|
|
5
|
+
with **Technical Corrigenda 1:2007, 2:2012, and 3:2017**. The current WG17/STC
|
|
6
|
+
pages at complang.tuwien.ac.at are useful review input, but draft proposals are
|
|
7
|
+
not silently treated as normative changes to that licensed baseline.
|
|
8
|
+
|
|
9
|
+
[*The Art of EyeProlog*](../../the-art-of-eyeprolog.md) remains the single
|
|
10
|
+
implementation reference. This file is an audit index: it identifies each
|
|
11
|
+
explicitly implementation-defined decision in Part 1, states the EyeProlog
|
|
12
|
+
choice, and points to the implementation boundary that realizes it. Repeated
|
|
13
|
+
references to the same decision are folded into one row. Requirements that the
|
|
14
|
+
standard calls **implementation dependent** are listed separately because ISO
|
|
15
|
+
5.4 does not require their documentation in the same way.
|
|
16
|
+
|
|
17
|
+
Status values are:
|
|
18
|
+
|
|
19
|
+
- **defined** — the current behavior is implemented and stated here;
|
|
20
|
+
- **not applicable** — the standard decision is conditional and the condition
|
|
21
|
+
is false for EyeProlog's selected profile;
|
|
22
|
+
- **audit gap** — the current code behavior is stated, but strict-mode
|
|
23
|
+
conformance still needs a correction or a narrower profile before this row
|
|
24
|
+
can support a full conformance claim.
|
|
25
|
+
|
|
26
|
+
## Explicit implementation-defined decisions
|
|
27
|
+
|
|
28
|
+
| Clause | Decision completed by ISO 5.4 documentation | EyeProlog choice | Status / implementation evidence |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| 5.5.11 | Reserved atoms and the effect of instantiating a variable to one | EyeProlog reserves no Prolog atom under 5.5.11. Atoms with implementation-looking names remain ordinary terms unless a particular predicate interprets them. | **defined** — term representation and built-ins in `src/term.js`, `src/iso.js`. |
|
|
31
|
+
| 6.5 | Processor character set (PCS) | The unquoted ISO lexical classes are the Part 1 ASCII characters implemented by `src/parser.js`. Quoted character data additionally accepts Unicode scalar values. | **audit gap** — the Unicode quoted-character extension is currently also accepted by `--iso-strict`; strict extension rejection still needs a narrower PCS rule or a documented conforming classification. |
|
|
32
|
+
| 6.5 | Classification of additional/extended PCS characters | Non-ASCII scalar values are not accepted as unquoted small-letter, capital-letter, graphic, solo, layout, or meta characters; they are accepted only inside quoted character data. | **audit gap** — same strict-mode boundary as the preceding row. |
|
|
33
|
+
| 6.6 | Collating-sequence integers | Character codes are Unicode scalar values. Atom comparison uses ECMAScript string lexicographic order; on the ISO ASCII repertoire this is code-point order and satisfies the required monotonic ranges. | **defined** — `src/term.js` (`compareTerms`), `src/iso.js` character-code predicates. |
|
|
34
|
+
| 6.6 | Collating values of control escapes and extended characters | Control escapes and character-code predicates use Unicode scalar values. Atom ordering is ECMAScript string order; for non-BMP one-char atoms that order is based on UTF-16 code units rather than scalar values. | **audit gap** — the ISO ASCII repertoire is conforming, but the extended-character collating rule still needs one coherent documented integer/order mapping in strict mode. |
|
|
35
|
+
| 7.1.2.2 | Mapping between a character code and bytes | Text file streams decode and encode UTF-8. Binary streams expose bytes 0..255 directly. | **defined** — `src/io.js`. |
|
|
36
|
+
| 7.1.4.1 | Set `C` of characters represented by one-char atoms | Character predicates accept Unicode scalar values U+0000..U+10FFFF excluding surrogate code points. | **defined** — `src/iso.js` character-code validation. |
|
|
37
|
+
| 7.4.2.4 | Whether `op/3` directives affect other Prolog texts or execution | An `op/3` directive changes parsing of subsequent text loaded into the same `Program`; the resulting operator table is also used by execution-time term I/O. Separately created `Program` objects are independent. | **defined** — `src/parser.js`, `src/program.js`, `src/iso.js`. |
|
|
38
|
+
| 7.4.2.5 | Whether directive-created `Convc` affects other text/execution | Directive mappings are copied into the solver's execution-time `charConversions` map. The source tokenizer itself does not currently apply `char_conversion/2` to later unquoted source characters. | **audit gap** — `src/program.js`, `src/solver.js`; source-preparation conversion remains to be aligned with 7.11.2.1. |
|
|
39
|
+
| 7.4.2.6 | Order of `initialization/1` goals | Initialization goals run once, in source/inclusion order, before requested goals; each must obtain a first solution. | **defined** — `Program.initializations`, `Solver.runInitializations()`. |
|
|
40
|
+
| 7.4.2.7 | Ground term designating a Prolog text for `include/1` | A source designation is an atom interpreted as a file path; relative paths resolve from the including file's directory (or the current working directory for unanchored input). | **defined** — `src/program.js` (`readIncludedSource`). |
|
|
41
|
+
| 7.4.2.8 | Ground term designating a Prolog text for `ensure_loaded/1` | Same atom/file-path designation as `include/1`. | **defined** — `src/program.js`. |
|
|
42
|
+
| 7.4.2.8 | Position at which an ensured text is included | The first `ensure_loaded/1` expands the text in place at the directive; later requests for the same resolved path are ignored. | **defined** — `src/program.js` (`ensured` set and in-place builder loading). |
|
|
43
|
+
| 7.4.2.9 | Whether `set_prolog_flag/2` directives affect other texts/execution | Parser-relevant `double_quotes` changes following source text in the same parse; recorded flag directives initialize the solver used for execution. Separately created programs/solvers are independent. | **defined** — `src/parser.js`, `src/program.js`, `src/solver.js`. |
|
|
44
|
+
| 7.5.1 | Means by which the processor is asked to prepare Prolog text | Text is prepared through the CLI/REPL, the JavaScript `Program.parse`/`run` API, source files/URLs, and `include/1`/`ensure_loaded/1`. | **defined** — Chapter 40 and `src/cli.js`, `src/index.js`, `src/program.js`. |
|
|
45
|
+
| 7.5.1 | Effects of directive-driven reordering, addition, or removal of clauses during preparation | Includes are expanded in place; declarations annotate the affected procedure; clauses otherwise retain source order. No directive silently reorders ordinary clauses. | **defined** — streaming builder in `src/program.js`. |
|
|
46
|
+
| 7.7.1 | External form of a negative answer | The interactive top level prints `false.`. Non-interactive `run()`/CLI corpus execution emits no answer line for a failed goal. | **defined** — Chapter 40, `src/repl.js`, `src/execute.js`. |
|
|
47
|
+
| 7.7.1 | External form of a positive answer | The REPL prints `true.` for a solution without visible bindings or `Name = Term` bindings; the file/API runner emits each resolved ground goal as a Prolog term followed by `.`. | **defined** — Chapter 40, `src/repl.js`, `src/execute.js`. |
|
|
48
|
+
| 7.7.3 | Method by which a user delivers a goal | REPL queries, CLI `--goal`, `%% goal:` host comments, and the JavaScript `goal` option are supported host interfaces. | **defined** — Chapter 40. |
|
|
49
|
+
| 7.10.1 | Additional source/sink possibilities | Node runtimes support local files plus the predefined standard streams; embedding supplies `user_input` text and a `user_output` callback. URL loading is a source-loading facility, not an ISO stream opened by `open/4`. | **defined** — `src/io.js`, `src/cli.js`, `src/index.js`. |
|
|
50
|
+
| 7.10.1 | Ground term designating a source/sink to `open/4` | An atom is interpreted as a local file-system path. | **defined** — `src/iso.js`, `src/io.js`. |
|
|
51
|
+
| 7.10.2.6 | Record-based/non-record-based text stream support | EyeProlog exposes non-record-based text streams. | **defined** — `src/io.js`. |
|
|
52
|
+
| 7.10.2.6 | Alteration of spaces at line ends | None. EyeProlog preserves text-stream characters; it does not trim or pad line endings. | **defined** — `src/io.js`. |
|
|
53
|
+
| 7.10.2.6 | Whether the last line is followed by newline / close adds one | Closing a text output stream writes exactly the accumulated content and does not synthesize a final newline. | **defined** — `StreamManager.close()`. |
|
|
54
|
+
| 7.10.2.6 | Effect of outputting control characters | The Unicode character is appended unchanged to a text stream (subject to the host sink's ordinary string handling). | **defined** — `StreamManager.writeUnit()`. |
|
|
55
|
+
| 7.10.2.7 | Number of zero bytes that may be appended on binary re-input | Zero. Binary file output is written and read byte-for-byte. | **defined** — `src/io.js`. |
|
|
56
|
+
| 7.10.2.8 | Whether a source/sink can be arbitrarily repositioned | File streams are repositionable only when opened with `reposition(true)`; standard streams are not repositionable. | **defined** — `src/io.js`, `set_stream_position/2` in `src/iso.js`. |
|
|
57
|
+
| 7.10.2.9 | Terms denoting end/past-end stream positions when repositionable | Stream positions are non-negative integer offsets; `position(N)` is also accepted by `set_stream_position/2`. End/past-end state is separately exposed by `end_of_stream/1`. | **defined** — `streamProperties()` and `setStreamPositionBuiltin()` in `src/iso.js`. |
|
|
58
|
+
| 7.10.2.11 | Default `eof_action` | Newly opened file streams default to `error`. The predefined standard streams use `reset`. | **defined** — `src/io.js`. |
|
|
59
|
+
| 7.10.2.13 | `eof_action(Action)` property when the stream uses its default action | Reports the same selected action: `error` for ordinary opened files and `reset` for the predefined standard streams. | **defined** — `streamProperties()` in `src/iso.js`, defaults in `src/io.js`. |
|
|
60
|
+
| 7.10.2.11 | Whether `reposition(false)` streams may nevertheless be repositioned | No. `set_stream_position/2` raises a permission error unless the stream was created with `reposition(true)`. | **defined** — `src/iso.js`. |
|
|
61
|
+
| 7.11.1.1 | Default `bounded` flag | `false`: EyeProlog's Prolog integer model uses arbitrary-precision `BigInt`, subject to host resources. | **defined** — `defaultPrologFlags()` in `src/solver.js`. |
|
|
62
|
+
| 7.11.1.2 | Default `max_integer` when `bounded=true` | The bounded-profile default is not applicable because EyeProlog selects `bounded=false`. However, EyeProlog currently exposes the sentinel atom `unbounded` through `current_prolog_flag/2` instead of making the `max_integer` query fail as 7.11.1.1 prescribes for an unbounded processor. | **audit gap** — `src/solver.js`, `current_prolog_flag/2`. |
|
|
63
|
+
| 7.11.1.3 | Default `min_integer` when `bounded=true` | The bounded-profile default is not applicable because EyeProlog selects `bounded=false`. However, EyeProlog currently exposes the sentinel atom `unbounded` through `current_prolog_flag/2` instead of making the `min_integer` query fail as 7.11.1.1 prescribes for an unbounded processor. | **audit gap** — `src/solver.js`, `current_prolog_flag/2`. |
|
|
64
|
+
| 7.11.1.4 | Default `integer_rounding_function` flag | `toward_zero`; `//` uses truncation toward zero. `div` is provided separately with downward/floor division semantics. | **defined** — `src/solver.js`, `src/iso.js`. |
|
|
65
|
+
| 9.1.3.1 | Integer division rounding function `rndI` | Truncation toward zero, matching the `integer_rounding_function=toward_zero` flag. | **defined** — BigInt division for `//` in `src/iso.js`. |
|
|
66
|
+
| 7.11.2.1 | Whether preparation-time `Convc` affects execution-time `Convc` | Yes: mappings recorded by `char_conversion/2` directives initialize the solver map. Source-token conversion itself has the audit gap noted at 7.4.2.5. | **defined / audit note** — `src/solver.js`. |
|
|
67
|
+
| 7.11.2.2 | Effect when `debug=on` | The flag is accepted and stored; it does not change goal semantics or enable a debugger. | **defined** — `src/solver.js`; no semantic branch depends on `debug`. |
|
|
68
|
+
| 7.11.2.3 | Default `max_arity` | `unbounded` in the Prolog model, subject to host memory and practical JavaScript array/index limits. | **defined** — `src/solver.js`; relevant guards report representation/resource errors. |
|
|
69
|
+
| 7.11.2.5 | Default `double_quotes` | `chars`. | **defined** — `src/solver.js`, parser flag state. |
|
|
70
|
+
| 7.12.1 | Second argument of `error/2` | The default context term is the atom `eyeprolog`. A few implementation-specific diagnostics may deliberately supply a more specific context term. | **defined** — `formalErrorTerm()` in `src/iso.js`. |
|
|
71
|
+
| 7.12.2(f) | Implementation-defined representation limits | Character and character-code operations use Unicode scalar limits; arity/integer values are modeled as unbounded but may hit host/resource limits. Float input overflow uses the implementation-specific `max_float`/`min_float` representation names documented by the STC-oriented tests. | **defined** — parser/ISO numeric and character guards. |
|
|
72
|
+
| 8.17.1 | Implementation-defined flag value ranges | Strict mode exposes only Part 1 core flags and their standard value sets. Normal mode additionally exposes EyeProlog's `occurs_check` flag; `max_integer`/`min_integer` use the `unbounded` sentinel described above. | **defined** — strict registry/flag filtering in `src/solver.js`. |
|
|
73
|
+
| 8.17.3 | Other effects of `halt/0` | Terminates EyeProlog execution and returns host/process status `0`; it produces no Prolog solution. | **defined** — `HaltSignal`, `haltBuiltin()`, CLI/runner handling. |
|
|
74
|
+
| 8.17.4 | Meaning/effects of `halt(Status)` | Integer `Status` is converted to the host process/runner halt code; it produces no Prolog solution. | **defined** — `haltBuiltin()`, `src/execute.js`, `src/cli.js`. |
|
|
75
|
+
| 9.1.4.1 | Floating-point rounding function `rndF` | Floating values and operations use ECMAScript `Number` (IEEE-754 binary64) and the host's specified binary64 arithmetic/conversions. | **defined** — `src/iso.js`, `src/number-value.js`. |
|
|
76
|
+
| 9.1.4.2 | Floating-point result function, including tiny non-zero arithmetic results | For arithmetic operation results that underflow to zero from non-zero operands, EyeProlog chooses the exceptional value `underflow`, exposed as `evaluation_error(underflow)`. Float token/`number_chars/2` input is a separate conversion path and finite input underflow rounds to `0.0`. | **defined** — `evaluateOperation()` and parser/number conversion; executable issue-56 regression below. |
|
|
77
|
+
| 9.1.4.3 | Approximate-addition function | ECMAScript binary64 addition is used; subtraction is implemented through the corresponding host operation and all finite results remain binary64 values. | **defined** — `evaluateOperation()` in `src/iso.js`. |
|
|
78
|
+
| 9.4 | Representation of negative integers for bitwise operations | BigInt's unbounded signed binary semantics are used, equivalent to an infinite two's-complement sign extension for bitwise operations. | **defined** — `src/iso.js` BigInt bitwise operators. |
|
|
79
|
+
| 9.4.1 | Right shift of negative integers and unusual shift counts | `>>` is arithmetic/sign-propagating. A negative count reverses direction according to JavaScript BigInt shift semantics; there is no finite integer bit-size ceiling in the Prolog model. | **defined** — `a >> b` in `src/iso.js`. |
|
|
80
|
+
| 9.4.2 | Left shift of negative integers and unusual shift counts | `<<` uses BigInt signed shift semantics; a negative count reverses direction. Resource exhaustion remains possible for very large results. | **defined** — `a << b` in `src/iso.js`. |
|
|
81
|
+
| 9.4.3 | Bitwise AND with negative operands | BigInt infinite-two's-complement semantics. | **defined** — `a & b`. |
|
|
82
|
+
| 9.4.4 | Bitwise OR with negative operands | BigInt infinite-two's-complement semantics. | **defined** — `a \| b`. |
|
|
83
|
+
| 9.4.5 | Bitwise complement | BigInt complement, i.e. `~N = -N-1`. | **defined** — `~a`. |
|
|
84
|
+
| Cor.2 9.4.6 | `xor/2` with negative operands | BigInt infinite-two's-complement semantics. | **defined** — `a ^ b`. |
|
|
85
|
+
|
|
86
|
+
### Why issue #56's two float results differ
|
|
87
|
+
|
|
88
|
+
The arithmetic expression and the float token go through different specified
|
|
89
|
+
layers. Clause 9.1.4 defines arithmetic operations in terms of the
|
|
90
|
+
implementation-defined floating rounding/result functions, and EyeProlog's
|
|
91
|
+
chosen `resultF` policy reports underflow for a non-zero arithmetic result that
|
|
92
|
+
falls below the normal range and rounds to zero. By contrast, reading the token
|
|
93
|
+
`0.1e-999` is an input conversion; the 1995 text does not precisely define the
|
|
94
|
+
rounding of an inexact float token, a gap also called out in the later
|
|
95
|
+
[WG17/STC item #40](https://www.complang.tuwien.ac.at/ulrich/iso-prolog/stc#40).
|
|
96
|
+
EyeProlog's documented input policy is therefore to accept finite token
|
|
97
|
+
underflow as `0.0` while arithmetic underflow remains an evaluation error.
|
|
98
|
+
|
|
99
|
+
The regression suite contains an issue-56 case that checks both observations,
|
|
100
|
+
and the existing `stc/float_underflow_input` conformance case covers the related
|
|
101
|
+
input-conversion policy.
|
|
102
|
+
|
|
103
|
+
## Implementation-specific features required to be documented by 5.4
|
|
104
|
+
|
|
105
|
+
Part 1 clause 5.5 permits extensions only as implementation-specific features.
|
|
106
|
+
Corrigendum 3 additionally makes extra option names explicit implementation-
|
|
107
|
+
specific features. EyeProlog's normal profile provides the following extension
|
|
108
|
+
families; `--iso-strict` is intended to remove their Part 1 interpretation.
|
|
109
|
+
|
|
110
|
+
| Part 1 extension hook | EyeProlog normal-profile feature | Strict-core disposition |
|
|
111
|
+
| --- | --- | --- |
|
|
112
|
+
| 5.5.1 Syntax | Part 2 modules, Part 3 grammar-rule expansion, and embedded quad syntax | Module directives are rejected; grammar rules remain ordinary `-->/2` terms rather than being expanded; quad syntax is rejected. Unicode quoted-character handling is the open PCS audit item above. |
|
|
113
|
+
| 5.5.2 Predefined operators | Part 3 `|` and EyeProlog's labelable infix `(?-)/2`; CLP(Z) operators when that library is imported | Only the Part 1 operator table is predefined; a conforming `op/3` may still add permitted operators. |
|
|
114
|
+
| 5.5.3 Character-conversion mapping | No non-identity initial `Convc` extension | Identity initial mapping. |
|
|
115
|
+
| 5.5.4 Types | No additional runtime Prolog term type is exposed by the core solver | Only variable, integer, float, atom, and compound term ordering participates in strict mode. |
|
|
116
|
+
| 5.5.5 Directives | `module/2`, `use_module/1-2`, `meta_predicate/1` and normal-profile library behavior | Rejected as implementation-specific Part 1 directives. |
|
|
117
|
+
| 5.5.6 Side effects | Host output/statistics, library-specific state, proof/statistics collection | The strict registry excludes library adapters; ordinary Part 1 I/O/database/flag/operator side effects remain. |
|
|
118
|
+
| 5.5.7 Control constructs | `tnot/1` and normal-profile execution optimizations | `tnot/1` is absent; automatic tabling/recursion guards are disabled. |
|
|
119
|
+
| 5.5.8 Flags | `occurs_check` | Absent in strict mode. |
|
|
120
|
+
| 5.5.9 Built-in predicates | EyeProlog libraries, CLP(Z), statistics, Part 3 `phrase/2-3`, and interop autoloaded predicates | Strict registry contains only the Part 1 + Corrigenda core registry. |
|
|
121
|
+
| 5.5.10 Evaluable functors | Library/runtime extensions when registered outside the strict core | Strict arithmetic registry is the Part 1 + Corrigenda set. |
|
|
122
|
+
| 5.5.11 Reserved atoms | None | None. |
|
|
123
|
+
| Cor.3 5.5.12 Options | Extra library/host options may exist outside core option lists | Strict core accepts the standard option names implemented for Part 1; invalid options follow Corrigendum 3 validation. |
|
|
124
|
+
|
|
125
|
+
Part 2 and Part 3 are separately standardized profiles when EyeProlog is run in
|
|
126
|
+
its normal mode; the table above describes them as extensions only relative to
|
|
127
|
+
the Part 1 strict-core boundary.
|
|
128
|
+
|
|
129
|
+
## Important implementation-dependent behavior (not the 5.4 mandatory table)
|
|
130
|
+
|
|
131
|
+
For portability work, EyeProlog also documents these choices even though the
|
|
132
|
+
1995 text labels them implementation **dependent**, not implementation defined:
|
|
133
|
+
|
|
134
|
+
- distinct variables are ordered by first encounter within the operation that
|
|
135
|
+
needs a stable ordering;
|
|
136
|
+
- expression arguments are evaluated left-to-right by the JavaScript evaluator;
|
|
137
|
+
- generated variable names use EyeProlog's stable `_A`, `_B`, ... style within
|
|
138
|
+
a write operation/top-level query;
|
|
139
|
+
- resource and syntax-error detail atoms are EyeProlog implementation details;
|
|
140
|
+
- the order of `current_prolog_flag/2` solutions is the insertion order of the
|
|
141
|
+
flag registry.
|
|
142
|
+
|
|
143
|
+
These rows are intentionally separate so that the ISO 5.4 checklist does not
|
|
144
|
+
blur the standard's distinction between *implementation defined* (documented),
|
|
145
|
+
*implementation dependent* (need not be documented), and *implementation
|
|
146
|
+
specific* (an extension that must be documented for a conforming processor).
|
|
@@ -28,12 +28,13 @@ uninstantiation errors, and corrected `catch/3` behavior (Cor.2); and option
|
|
|
28
28
|
validation, variable-name traversal/output, canonical list output, and negative
|
|
29
29
|
integer powers (Cor.3).
|
|
30
30
|
|
|
31
|
-
Implementation-defined choices are
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
Implementation-defined and implementation-specific choices are indexed
|
|
32
|
+
clause-by-clause in [ISO-IMPLEMENTATION-DEFINED.md](ISO-IMPLEMENTATION-DEFINED.md),
|
|
33
|
+
with *The Art of EyeProlog* remaining the implementation reference. In
|
|
34
|
+
particular, the index records the unbounded integer model, `double_quotes=chars`,
|
|
35
|
+
`//` rounding toward zero, the ECMAScript binary64 float policy (including the
|
|
36
|
+
9.1.4.2 arithmetic-underflow choice), stream/character decisions, and the
|
|
37
|
+
normal-profile extension boundary.
|
|
37
38
|
|
|
38
39
|
This is an executable conformance matrix, not a certification issued by an
|
|
39
40
|
independent standards body. Release gating runs the ISO cases and the dedicated
|
package/test/run-regression.mjs
CHANGED
|
@@ -739,6 +739,14 @@ c4 ?- call((!;1)).
|
|
|
739
739
|
assertEqual(result.stderr, '', 'stderr');
|
|
740
740
|
},
|
|
741
741
|
},
|
|
742
|
+
{
|
|
743
|
+
name: 'arithmetic underflow choice differs from float-token input underflow (issue #56)',
|
|
744
|
+
run: () => {
|
|
745
|
+
const result = run('', { goal: 'catch((N is 0.1*10** -999), error(evaluation_error(underflow), _), N = underflow)' });
|
|
746
|
+
assertEqual(result.stdout, 'catch(underflow is 0.1 * 10 ** -999, error(evaluation_error(underflow), eyeprolog), underflow = underflow).\n', 'operation underflow');
|
|
747
|
+
assertEqual(run('', { goal: 'N = 0.1e-999' }).stdout, '0.0 = 0.0.\n', 'float-token input underflow');
|
|
748
|
+
},
|
|
749
|
+
},
|
|
742
750
|
{
|
|
743
751
|
name: 'float literals reject overflow and normalize underflow (issue #54)',
|
|
744
752
|
run: () => {
|
|
@@ -1520,7 +1528,7 @@ c4 ?- call((!;1)).
|
|
|
1520
1528
|
},
|
|
1521
1529
|
},
|
|
1522
1530
|
{
|
|
1523
|
-
name: 'Trealla-style DCG hand-off autoloads time/1 and
|
|
1531
|
+
name: 'Trealla-style DCG hand-off autoloads time/1 and ... //0 without quadratic occurs checks (issue #49)',
|
|
1524
1532
|
run: () => {
|
|
1525
1533
|
const engineUrl = new URL('../src/index.js', import.meta.url).href;
|
|
1526
1534
|
const script = `
|
|
@@ -1593,7 +1601,7 @@ c4 ?- call((!;1)).
|
|
|
1593
1601
|
},
|
|
1594
1602
|
},
|
|
1595
1603
|
{
|
|
1596
|
-
name: 'REPL applies conservative autoloading to interactive time/1 and consulted
|
|
1604
|
+
name: 'REPL applies conservative autoloading to interactive time/1 and consulted ... //0',
|
|
1597
1605
|
run: () => {
|
|
1598
1606
|
const filename = path.join(tmp, `issue49-handoff-${tmpCounter++}.pl`);
|
|
1599
1607
|
fs.writeFileSync(filename, 'a --> ..., epsilon.\nepsilon --> [].\n');
|
|
@@ -3400,6 +3408,33 @@ function documentationSyncCases() {
|
|
|
3400
3408
|
name: 'documentation uses EyeProlog source style',
|
|
3401
3409
|
run: () => assertArrayEqual(documentationSourceStyleIssues(), [], 'documentation source style'),
|
|
3402
3410
|
},
|
|
3411
|
+
{
|
|
3412
|
+
name: 'DCG nonterminal indicator prose uses valid ... //0 spacing (issue #49)',
|
|
3413
|
+
run: () => {
|
|
3414
|
+
for (const filename of ['README.md', 'the-art-of-eyeprolog.md', 'src/standard-library.js', 'src/solver.js']) {
|
|
3415
|
+
const text = fs.readFileSync(path.join(packageRoot, filename), 'utf8');
|
|
3416
|
+
assertNotIncludes(text, '...' + '//0', `${filename} invalid compact nonterminal indicator`);
|
|
3417
|
+
}
|
|
3418
|
+
},
|
|
3419
|
+
},
|
|
3420
|
+
{
|
|
3421
|
+
name: 'ISO 5.4 decision index inventories implementation-defined choices (issue #56)',
|
|
3422
|
+
run: () => {
|
|
3423
|
+
const filename = path.join(testRoot, 'conformance', 'ISO-IMPLEMENTATION-DEFINED.md');
|
|
3424
|
+
const text = fs.readFileSync(filename, 'utf8');
|
|
3425
|
+
for (const clause of [
|
|
3426
|
+
'5.5.11', '6.5', '6.6', '7.1.2.2', '7.1.4.1', '7.4.2.4', '7.4.2.5',
|
|
3427
|
+
'7.4.2.6', '7.4.2.7', '7.4.2.8', '7.4.2.9', '7.5.1', '7.7.1', '7.7.3',
|
|
3428
|
+
'7.10.1', '7.10.2.6', '7.10.2.7', '7.10.2.8', '7.10.2.9', '7.10.2.11',
|
|
3429
|
+
'7.10.2.13', '7.11.1.1', '7.11.1.2', '7.11.1.3', '7.11.1.4', '7.11.2.1',
|
|
3430
|
+
'7.11.2.2', '7.11.2.3', '7.11.2.5', '7.12.1', '7.12.2(f)', '8.17.1',
|
|
3431
|
+
'8.17.3', '8.17.4', '9.1.3.1', '9.1.4.1', '9.1.4.2', '9.1.4.3', '9.4',
|
|
3432
|
+
'9.4.1', '9.4.2', '9.4.3', '9.4.4', '9.4.5', 'Cor.2 9.4.6',
|
|
3433
|
+
]) assertIncludes(text, `| ${clause} |`, `ISO 5.4 clause ${clause}`);
|
|
3434
|
+
assertIncludes(text, 'Why issue #56', 'issue #56 explanation');
|
|
3435
|
+
assertIncludes(text, 'Implementation-specific features required to be documented by 5.4', '5.5 extension inventory');
|
|
3436
|
+
},
|
|
3437
|
+
},
|
|
3403
3438
|
{
|
|
3404
3439
|
name: 'book is the single implementation reference',
|
|
3405
3440
|
run: () => assertArrayEqual(bookReferenceDocumentationIssues(), [], 'book reference documentation'),
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -5668,7 +5668,7 @@ round-tripping. The checked answers are in
|
|
|
5668
5668
|
|
|
5669
5669
|
#### Deep sequence hand-off
|
|
5670
5670
|
|
|
5671
|
-
`library(iso_ext)` provides the common
|
|
5671
|
+
`library(iso_ext)` provides the common `... //0` helper, which describes an
|
|
5672
5672
|
arbitrary number of input elements. It is not part of ISO Part 3, but it is a
|
|
5673
5673
|
useful interoperability and stress-test relation. A compact hand-off test is:
|
|
5674
5674
|
|
|
@@ -5677,7 +5677,7 @@ a --> ..., epsilon.
|
|
|
5677
5677
|
epsilon --> [].
|
|
5678
5678
|
```
|
|
5679
5679
|
|
|
5680
|
-
Here the remaining sequence is repeatedly passed from
|
|
5680
|
+
Here the remaining sequence is repeatedly passed from `... //0` to another
|
|
5681
5681
|
nonterminal. For a finite compact list, EyeProlog can scan the arbitrary
|
|
5682
5682
|
sequence iteratively instead of consuming one ordinary solver depth level per
|
|
5683
5683
|
list cell. If the continuation is structurally proven to be a zero-width
|
|
@@ -6207,7 +6207,7 @@ The current interoperability profile recognizes these library roles:
|
|
|
6207
6207
|
| Library | Role in the interoperability profile |
|
|
6208
6208
|
| --- | --- |
|
|
6209
6209
|
| `library(lists)` | Common list module. A conservative subset of its exports is in the shared predicate profile. |
|
|
6210
|
-
| `library(iso_ext)` | Common extension-module name. `call_nth/2`, `time/1`, and the
|
|
6210
|
+
| `library(iso_ext)` | Common extension-module name. `call_nth/2`, `time/1`, and the `... //0` arbitrary-sequence helper are conservatively autoloaded for cross-engine source. |
|
|
6211
6211
|
| `library(lambda)` | Scryer-aligned higher-order notation. It is imported explicitly because loading it also installs the `+\` operator. |
|
|
6212
6212
|
| `library(prologue)` | EyeProlog compatibility module, not a common interop library name. `between/3` is nevertheless autoloaded from it so portable source need not name this EyeProlog-specific provider. |
|
|
6213
6213
|
|
|
@@ -6234,7 +6234,7 @@ recovery headroom so finite-heap exhaustion remains a catchable
|
|
|
6234
6234
|
EyeProlog API belongs to the shared profile. `call_nth/2`, `time/1`, and
|
|
6235
6235
|
`.../2` are mapped there. `time/1` measures each solution of a meta-call and
|
|
6236
6236
|
prints elapsed time, EyeProlog inference count, and MLips in Trealla-style form,
|
|
6237
|
-
for example `% Time elapsed 0.832s, 65551 Inferences, 0.079 MLips`;
|
|
6237
|
+
for example `% Time elapsed 0.832s, 65551 Inferences, 0.079 MLips`; `... //0`
|
|
6238
6238
|
describes an arbitrary number of input elements. Together they let the
|
|
6239
6239
|
Trealla/Scryer DCG hand-off benchmark run in EyeProlog without source changes
|
|
6240
6240
|
(assuming the usual list library is already imported in an interactive
|
|
@@ -7416,6 +7416,10 @@ Part 1 conformance audit. It distinguishes implemented/tested families from
|
|
|
7416
7416
|
requirements whose normative `shall` clauses, option combinations, or error
|
|
7417
7417
|
precedence still need one-by-one closure. `test/conformance/ISO-MATRIX.md`
|
|
7418
7418
|
maps language families to representative executable cases.
|
|
7419
|
+
`test/conformance/ISO-IMPLEMENTATION-DEFINED.md` is the ISO 5.4 decision
|
|
7420
|
+
index: it enumerates the Part 1 implementation-defined decisions, the
|
|
7421
|
+
implementation-specific extension families, and any remaining strict-mode audit
|
|
7422
|
+
gaps without turning draft WG17/STC proposals into the licensed baseline.
|
|
7419
7423
|
`test/conformance/WG17-SYNTAX-STATUS.md` separately traces the vendored active
|
|
7420
7424
|
upstream syntax cases. Reviewed cases can pin exact strict-reader outcomes, while
|
|
7421
7425
|
newly upgraded cases execute directly against the upstream Codex expectation.
|