eyemind 0.1.35 → 0.1.37

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/SPEC.md CHANGED
@@ -2,216 +2,230 @@
2
2
 
3
3
  ```text
4
4
  Title: The eyemind Rule Language and Proof Format
5
- Version: eyemind 0.1.35
6
- Status: Informational
7
- Author: Jos De Roo, KNoWS office of IDLab, Ghent University - imec
8
- Repository: https://github.com/eyereasoner/eyemind
5
+ Version: eyemind 0.1.37
9
6
  ```
10
7
 
11
- ## Abstract
12
-
13
- eyemind is a rule language written in JavaScript, with forward and backward
14
- reasoning, and a proof format whose documents a separate checker verifies
15
- against the program that produced them. This document specifies the terms
16
- the language reasons over, how a program is stated in JavaScript, its semantics
17
- and conclusions, the canonical text in which terms, conclusions, proofs and
18
- check reports are written and read back, the proof document, the eight
19
- conditions (C1-C8) a proof checker establishes, the check report, and the
20
- command line.
21
-
22
- ## Status of This Memo
23
-
24
- This document is not an Internet Standards Track specification. It describes
25
- the language and formats as implemented by eyemind 0.1.35, for readers who want
26
- to write programs, produce or consume proofs and reports, or implement a
27
- compatible reasoner or checker. Where this document and the implementation
28
- disagree, that is a defect in one of them.
8
+ This document specifies the syntax and meaning of eyemind programs and data
9
+ documents, their observable evaluation, and the conditions for checking a
10
+ proof.
29
11
 
30
12
  ## Table of Contents
31
13
 
32
- 1. [Introduction](#1-introduction)
33
- 2. [Conventions and Terminology](#2-conventions-and-terminology)
34
- 3. [Terms](#3-terms)
35
- 4. [Programs](#4-programs)
36
- 5. [Goals, Controls and Primitives](#5-goals-controls-and-primitives)
37
- 6. [Arithmetic](#6-arithmetic)
38
- 7. [Reasoning](#7-reasoning)
39
- 8. [Canonical Text](#8-canonical-text)
40
- 9. [Reading Documents](#9-reading-documents)
41
- 10. [Proof Documents](#10-proof-documents)
42
- 11. [Proof Checking](#11-proof-checking)
43
- 12. [Check Reports](#12-check-reports)
44
- 13. [Unused Clauses](#13-unused-clauses)
45
- 14. [Command Line](#14-command-line)
46
- 15. [Security Considerations](#15-security-considerations)
47
- 16. [Conformance](#16-conformance)
48
- 17. [Semantics](#17-semantics)
49
- 1. [Herbrand interpretation](#171-herbrand-interpretation)
50
- 2. [Variables and witnesses](#172-variables-and-witnesses)
51
- 3. [Positive least model](#173-positive-least-model)
52
- 4. [Negation and collection](#174-negation-and-collection)
53
- 5. [Sets, solutions and operational behavior](#175-sets-solutions-and-operational-behavior)
54
- 6. [Termination and proofs](#176-termination-and-proofs)
55
-
14
+ - [1. Scope and Conventions](#1-scope-and-conventions)
15
+ - [1.1 Scope](#11-scope)
16
+ - [1.2 Requirements and notation](#12-requirements-and-notation)
17
+ - [1.3 Terminology](#13-terminology)
18
+ - [2. Terms](#2-terms)
19
+ - [2.1 Kinds of terms](#21-kinds-of-terms)
20
+ - [2.2 Lists](#22-lists)
21
+ - [2.3 Identity and unification](#23-identity-and-unification)
22
+ - [2.4 Standard order](#24-standard-order)
23
+ - [3. Program Syntax](#3-program-syntax)
24
+ - [3.1 Scripts](#31-scripts)
25
+ - [3.2 Names](#32-names)
26
+ - [3.3 Term construction](#33-term-construction)
27
+ - [3.4 Statements](#34-statements)
28
+ - [3.5 Clause constraints and numbering](#35-clause-constraints-and-numbering)
29
+ - [4. Goals and Primitives](#4-goals-and-primitives)
30
+ - [4.1 Goal syntax](#41-goal-syntax)
31
+ - [4.2 Controls](#42-controls)
32
+ - [4.3 Primitives](#43-primitives)
33
+ - [5. Arithmetic](#5-arithmetic)
34
+ - [5.1 Expressions](#51-expressions)
35
+ - [5.2 Functions and arities](#52-functions-and-arities)
36
+ - [5.3 Numeric results](#53-numeric-results)
37
+ - [5.4 Arithmetic errors and limits](#54-arithmetic-errors-and-limits)
38
+ - [6. Rule Structure](#6-rule-structure)
39
+ - [6.1 Dependencies and stratification](#61-dependencies-and-stratification)
40
+ - [6.2 Inline rule templates](#62-inline-rule-templates)
41
+ - [6.3 Source rule inspection](#63-source-rule-inspection)
42
+ - [7. Semantics](#7-semantics)
43
+ - [7.1 Herbrand interpretation](#71-herbrand-interpretation)
44
+ - [7.2 Variables and witnesses](#72-variables-and-witnesses)
45
+ - [7.3 Positive least model](#73-positive-least-model)
46
+ - [7.4 Negation and collection](#74-negation-and-collection)
47
+ - [7.5 Sets and operational behavior](#75-sets-and-operational-behavior)
48
+ - [7.6 Termination and proof claims](#76-termination-and-proof-claims)
49
+ - [8. Evaluation and Conclusions](#8-evaluation-and-conclusions)
50
+ - [8.1 Goal search](#81-goal-search)
51
+ - [8.2 Forward evaluation and witnesses](#82-forward-evaluation-and-witnesses)
52
+ - [8.3 Resource bounds](#83-resource-bounds)
53
+ - [8.4 External goals](#84-external-goals)
54
+ - [8.5 Contradictions](#85-contradictions)
55
+ - [8.6 Reported conclusions](#86-reported-conclusions)
56
+ - [8.7 Proof generation](#87-proof-generation)
57
+ - [9. Document Syntax and Canonical Text](#9-document-syntax-and-canonical-text)
58
+ - [9.1 Accepted document syntax](#91-accepted-document-syntax)
59
+ - [9.2 Canonical atoms, numbers, variables and lists](#92-canonical-atoms-numbers-variables-and-lists)
60
+ - [9.3 Canonical compounds](#93-canonical-compounds)
61
+ - [9.4 Variable scope in output](#94-variable-scope-in-output)
62
+ - [10. Proof Documents](#10-proof-documents)
63
+ - [10.1 Structure](#101-structure)
64
+ - [10.2 Clause displays](#102-clause-displays)
65
+ - [10.3 Steps](#103-steps)
66
+ - [11. Proof Checking](#11-proof-checking)
67
+ - [11.1 Reading the document](#111-reading-the-document)
68
+ - [11.2 C1 Resolution](#112-c1-resolution)
69
+ - [11.3 C2 Well-foundedness](#113-c2-well-foundedness)
70
+ - [11.4 C3 Justification](#114-c3-justification)
71
+ - [11.5 C4 Coverage](#115-c4-coverage)
72
+ - [11.6 C5 Re-decision](#116-c5-re-decision)
73
+ - [11.7 C6 Boundary consistency](#117-c6-boundary-consistency)
74
+ - [11.8 C7 Relevance](#118-c7-relevance)
75
+ - [11.9 C8 Witness integrity](#119-c8-witness-integrity)
76
+ - [11.10 Counts and validity](#1110-counts-and-validity)
77
+ - [11.11 Scope of a valid proof](#1111-scope-of-a-valid-proof)
78
+ - [12. Check Reports](#12-check-reports)
79
+ - [12.1 JSON form](#121-json-form)
80
+ - [13. Command-Line Interface](#13-command-line-interface)
81
+ - [13.1 Invocation and options](#131-invocation-and-options)
82
+ - [13.2 Unused clauses](#132-unused-clauses)
83
+ - [14. Conformance](#14-conformance)
84
+ - [15. Security](#15-security)
56
85
  - [Appendix A. Document Grammar](#appendix-a-document-grammar)
57
86
  - [Appendix B. Example](#appendix-b-example)
58
87
 
59
88
  ---
60
89
 
61
- ## 1. Introduction
90
+ ## 1. Scope and Conventions
62
91
 
63
- An eyemind program states facts and rules. Forward rules are applied until no
64
- new conclusion follows; backward rules are applied when a goal asks for them.
65
- Every conclusion can be accompanied by a proof: a document that names, for
66
- each step, the program clause or primitive that justifies it. A checker that
67
- never consults the reasoner verifies such a document against the program and
68
- reports, condition by condition, what it established and what it had to take
69
- on trust.
92
+ ### 1.1 Scope
70
93
 
94
+ This specification defines eyemind's terms, program syntax, semantics,
95
+ evaluation, document formats, proof checking and command-line interface.
71
96
  Programs are JavaScript scripts. Conclusions, proofs and check reports are
72
- JavaScript expressions, one per line, which a reader turns back into terms
73
- without executing them. One language thus states the rules, computes with
74
- them, and holds every result.
97
+ data documents whose expressions MUST be read without execution.
75
98
 
76
- ## 2. Conventions and Terminology
99
+ The JavaScript library API, browser interface, installation and release
100
+ procedures are outside this specification.
101
+
102
+ ### 1.2 Requirements and notation
77
103
 
78
104
  The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
79
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this document
80
- are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and
81
- only when, they appear in all capitals.
82
-
83
- - **Term**: a value the language reasons over (Section 3).
84
- - **Clause**: a fact, a forward rule or a backward rule (Section 4).
85
- - **Goal**: a term solved by resolution or by a primitive (Section 5).
86
- - **Substitution**: a mapping from variable names to terms.
87
- - **Instance**: a term obtained from another by applying a substitution.
88
- - **Identical**: two terms are identical when their canonical texts
89
- (Section 8) are equal; variables are identical only to themselves.
105
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" are to be
106
+ interpreted as described in BCP 14 (RFC 2119, RFC 8174) when they appear in
107
+ all capitals.
108
+
109
+ In syntax descriptions, `T` denotes a term, `G` a goal, `Body` a premise and
110
+ `Head` a conclusion. Subscripts distinguish arguments; `T1, ..., Tn` means
111
+ comma-separated arguments, not a literal ellipsis. The token `...` is literal
112
+ only in list-tail syntax such as `[Head, ...Tail]`. Code blocks marked `js`
113
+ show actual syntax. `name/arity` identifies a predicate or constructor by
114
+ its name and number of arguments.
115
+
116
+ ### 1.3 Terminology
117
+
118
+ - **Clause**: a fact, a forward rule or a backward rule.
119
+ - **Substitution**: an assignment of terms to variables.
120
+ - **Instance**: the result of applying a substitution to a term or clause.
90
121
  - **Ground**: containing no variable.
91
- - **Conclusion**: a term a run reports (Section 7.6).
92
- - **Document**: text holding a sequence of expressions (Sections 9-12).
93
- - **Reasoner**: an implementation of Sections 3-10, which checks its own
94
- proofs as Section 11 describes.
95
- - **Checker**: an implementation of Sections 9, 11 and 12.
122
+ - **Identical**: equal by canonical text (Section 9), with each variable
123
+ identical only to itself.
124
+ - **Renamed apart**: with fresh variables, preserving all sharing within
125
+ the renamed terms and avoiding capture of other variables.
126
+ - **Conclusion**: a term reported by a run (Section 8.6).
127
+ - **Document**: a sequence of expressions in the data syntax of Section 9.
128
+ - **Reasoner**: a processor that evaluates programs and checks its generated
129
+ proofs before returning them.
130
+ - **Checker**: a processor that verifies proof documents against a supplied
131
+ program, without using reasoning to fill missing derivations.
132
+
133
+ ## 2. Terms
96
134
 
97
- ## 3. Terms
135
+ ### 2.1 Kinds of terms
98
136
 
99
- A term is one of:
137
+ A term is one of the following. The examples use document syntax; program
138
+ construction is defined separately in Section 3.3.
100
139
 
101
- | Kind | Representation | Example |
140
+ | Kind | Meaning | Examples |
102
141
  | --- | --- | --- |
103
- | Atom | a JavaScript string | `'socrates'`, `'[]'` |
104
- | Integer | a JavaScript `BigInt`, of unbounded size | `42`, `-7` |
105
- | Float | a JavaScript number that is a float, an IEEE-754 binary64 value | `0.5`, `1e+22`, `2.0` |
106
- | Variable | a name | `X`, `_Rest` |
107
- | Compound | a name (an atom) and one or more argument terms | `parent('alice', 'bob')` |
108
-
109
- A compound term is identified by its name and its arity, the number of its
110
- arguments, written `name/arity`. An atom used as a goal has arity 0.
111
-
112
- **Lists.** The empty list is the atom `'[]'`. A non-empty list is the
113
- compound `'.'(Head, Tail)`. A list whose final tail is not `'[]'` is an open
114
- list. Character text is a list of one-character atoms.
115
-
116
- **Numbers.** Integers and floats are distinct: `1` and `1.0` MUST NOT unify.
117
- Floats MUST be finite; no operation produces an infinity or a NaN as a term
118
- (Section 6). Nonfinite JavaScript values and float literals that overflow,
119
- such as `1e999`, MUST be rejected in programs, goals and documents. Booleans,
120
- `null` and `undefined` are not terms.
121
-
122
- **Unification** is syntactic unification on finite trees. It MUST apply the
123
- occurs check: binding a variable to a term that contains it fails. Atoms unify
124
- when their texts are equal; numbers when they are of the same kind and equal;
125
- compounds when their names and arities are equal and their arguments unify
126
- pairwise.
127
-
128
- **Standard order.** Terms are totally ordered as: variables, then numbers,
129
- then atoms, then compounds. Numbers are ordered by value, compared exactly
130
- across integers and floats; a float precedes an integer of equal value.
131
- Atoms are ordered by the code points of their characters. Compounds are
132
- ordered by arity, then name, then arguments from left to right. Distinct
133
- variables are ordered by the code points of their names, so the order is the
134
- same in every comparison. The names of renamed-apart variables (Section 7.1)
135
- are implementation-specific, so a program SHOULD NOT depend on the relative
136
- order of two distinct unbound variables.
137
-
138
- The floats `0.0` and `-0.0` unify and compare equal, but are not identical:
139
- their canonical texts differ (Sections 2 and 8.1). This distinction also
140
- applies when they occur inside compounds or lists. A lone UTF-16 surrogate
141
- in a JavaScript string is ordered by its own code point; a valid surrogate
142
- pair denotes one supplementary code point.
143
-
144
- ## 4. Programs
145
-
146
- ### 4.1 Program scripts
147
-
148
- A program is a JavaScript script, run in sloppy mode with every name it does
149
- not declare resolved as Section 4.3 says. It needs no import. Running the
150
- script states the program's clauses in the order the calls are made; `fact`
151
- MAY state several clauses in one call (Section 4.2). Several scripts MAY be
152
- loaded as one program; their clauses are then numbered in the order the
153
- scripts are run.
154
-
155
- A program is given exactly the names needed to state it: the statements of
156
- Section 4.2, `forward`, `backward`, `preds`, `vars`, `struct`, the controls and primitives of
157
- Section 5, the atom `fail`, and `eyemind`, the library, with which a program
158
- can build and run another program and read and write documents
159
- (`eyemind.build`, `eyemind.run`, `eyemind.checkProof`, `eyemind.checkReport`,
160
- `eyemind.verdictText`, `eyemind.readTerm`, `eyemind.readTerms`, `eyemind.write`).
161
-
162
- ### 4.2 Statements
163
-
164
- | Statement | Clause stated |
142
+ | Atom | Character text. | `'socrates'`, `'human'` |
143
+ | Integer | An exact integer of unbounded size. | `42`, `-7` |
144
+ | Float | A finite IEEE-754 binary64 value. | `0.5`, `2.0`, `1e+22` |
145
+ | Variable | A named logical variable. | `X`, `_Rest` |
146
+ | Compound | An atom naming a constructor and one or more argument terms. | `parent('alice', 'bob')` |
147
+
148
+ An atom used as a predicate has arity 0. A compound's name and arity identify
149
+ its constructor. Integers and floats are distinct: `1` and `1.0` MUST NOT
150
+ unify. Booleans, `null`, `undefined`, infinities and NaN are not terms.
151
+ Nonfinite numeric values MUST be rejected.
152
+
153
+ ### 2.2 Lists
154
+
155
+ Lists use bracket syntax:
156
+
157
+ | Form | Meaning |
165
158
  | --- | --- |
166
- | `fact(T1, T2, ...)` | One fact per argument. |
167
- | `implies(Premise, Conclusion)` | A forward rule: the premise's goals are its body and the conclusion its head, or its heads when the conclusion is an array of them. |
168
- | `implied_by(Conclusion, Premise)` | A backward rule: the conclusion is its head and the premise's goals are its body. |
169
- | `query(G1, G2, ...)` | A forward rule with the head `'true'` and the body `G1, G2, ...`: it reports its body's instances (Section 7.2). At least one goal is REQUIRED. |
170
- | `contradiction(G1, G2, ...)` | A forward rule with the head `'false'` and the body `G1, G2, ...`: it halts the run (Section 7.2). At least one goal is REQUIRED. |
171
- | `facts_from(path)` or `facts_from({text: ...})` | One fact per expression of a document (Section 9). |
172
-
173
- A premise is a goal or an array of goals, their conjunction (Section 5.1). A
174
- body goal that is a conjunction is split into its conjuncts; the clause body
175
- is the resulting sequence of goals.
176
-
177
- `implies` and `implied_by` take exactly two arguments. Each call also returns
178
- a rule value; when that value is embedded in another statement of the same
179
- program build, the call contributes a template instead of a standalone clause
180
- (Section 4.6). An ignored or unembedded return value keeps its standalone
181
- clause.
182
-
183
- Clauses are numbered from 1 in the order they are stated, omitting embedded
184
- rule calls. Each clause records
185
- the line of the program on which the statement stating it begins; the facts
186
- of `facts_from` record the line of that call.
187
-
188
- `facts_from` is how a program takes in data that is not a program: a document
189
- of plain expressions, one per line, such as the conclusions, proof or check
190
- report of another run, or data from a source that is not trusted. The
191
- document is read as Section 9 describes and is never executed, so it can only
192
- ever state facts. A data file written as a program instead (`fact(...)`
193
- statements) would run as JavaScript code.
159
+ | `[]` | Empty list. |
160
+ | `[T1, ..., Tn]` | List of `n` elements, for `n >= 1`. |
161
+ | `[Head, ...Tail]` | One element followed by a tail. The comma before `...` is required. |
162
+ | `[T1, ..., Tn, ...Tail]` | Several elements followed by a tail. |
194
163
 
195
- A clause MUST be rejected when:
164
+ For example, `[1, 2]` and `[1, ...[2]]` denote the same list. A **proper
165
+ list** ends in `[]`. A tail left as a variable gives an **open list**;
166
+ a non-list tail gives an **improper list**. Only the final item may be a
167
+ spread tail. In document syntax, `[...Tail]` denotes `Tail` itself.
168
+ Program spread expressions also follow Section 3.3.
169
+
170
+ The empty list is the atom whose text is `[]`, so `'[]'` denotes the same
171
+ term. A non-empty list has the compound structure exposed by `functor` and
172
+ `univ`: name `'.'`, arity 2, and arguments head and tail. This describes
173
+ term structure, not an alternative written list syntax. A character list
174
+ contains one-character atoms.
175
+
176
+ A non-empty proper list in a goal position denotes conjunction instead
177
+ (Section 4.1). A list inside an ordinary argument remains list data.
178
+
179
+ ### 2.3 Identity and unification
180
+
181
+ Unification is syntactic matching on finite trees. It MUST apply the occurs
182
+ check: binding a variable to a term containing that variable fails. Atoms
183
+ unify when their texts are equal; numbers when they have the same kind and
184
+ value; compounds when their names and arities agree and their arguments
185
+ unify pairwise. Lists unify by their heads and tails.
196
186
 
197
- - a head is not an atom or a compound;
198
- - a head is `step/4` or `clause/2`, which are reserved for proof documents,
199
- or explicitly states `activated/2`, reserved for template activations;
200
- - a head is a primitive (Section 5.2) or a control (Section 5.1), except the
201
- head `'true'` of a query and `'false'` of a contradiction; in particular a
202
- conclusion of `implies` is never `'true'` or `'false'`;
203
- - a body goal is not a variable, an atom or a compound, or is an empty array.
187
+ The floats `0.0` and `-0.0` unify and compare equal, but their canonical
188
+ texts differ, so they are not identical. This distinction also applies
189
+ inside compounds and lists. Asserting a relation between two terms does not
190
+ make the terms identical.
204
191
 
205
- ### 4.3 Names a program does not define
192
+ ### 2.4 Standard order
206
193
 
207
- A name a program uses without declaring it (with `const`, `let`, `var`,
208
- `function` or `class`, or by assigning to it) is supplied as follows:
194
+ Terms are totally ordered: variables, numbers, atoms, then compounds.
195
+ Numbers are ordered by value, compared exactly across integers and floats;
196
+ a float precedes an integer of equal value. Atoms are ordered by Unicode
197
+ code point. Compounds are ordered by arity, then name, then arguments from
198
+ left to right. Lists follow their compound structure (Section 2.2).
209
199
 
210
- 1. a name the program is given (Section 4.1) has that meaning;
200
+ Variables are ordered by the code points of their names. Fresh variables
201
+ introduced by renaming apart have unspecified names, so programs SHOULD NOT
202
+ depend on their relative order. A lone UTF-16 surrogate is ordered by its
203
+ own code point; a valid surrogate pair denotes one supplementary code point.
204
+
205
+ ## 3. Program Syntax
206
+
207
+ ### 3.1 Scripts
208
+
209
+ A program consists of one or more non-strict JavaScript scripts. Each script
210
+ may use JavaScript declarations, expressions, functions and control flow to
211
+ construct its clauses. No import is required for the statements and term
212
+ constructors defined here. Clauses are stated in the order their statement
213
+ calls occur; multiple input scripts are processed in input order.
214
+
215
+ The supplied names are the statements of Section 3.4, `forward`, `backward`,
216
+ `preds`, `vars`, `struct`, the controls and primitives of Section 4, the
217
+ atom `fail`, and the library name `eyemind`. Library operations are outside
218
+ this specification. Other names are resolved as Section 3.2 specifies.
219
+
220
+ ### 3.2 Names
221
+
222
+ A name a script does not declare or assign is resolved as follows:
223
+
224
+ 1. a supplied name (Section 3.1) has that meaning;
211
225
  2. the JavaScript globals `Math`, `JSON`, `BigInt`, `Infinity`, `NaN`,
212
226
  `undefined`, `console`, `globalThis`, `parseInt`, `parseFloat`, `isNaN`
213
227
  and `isFinite` keep their meaning;
214
- 3. any other name beginning with an uppercase letter or `_` is the variable of
228
+ 3. any other name beginning with an ASCII uppercase letter or `_` is the variable of
215
229
  that name, so that `Date`, `Map` or `Object` are variables as logic
216
230
  programs name them (`globalThis.Date` still reaches the global);
217
231
  4. any other name is the predicate of that name: calling it with arguments
@@ -224,96 +238,369 @@ with a lowercase letter: `const [p, q] = preds('p q')` and
224
238
  `const [X, Y] = vars('X Y')`, where one name gives the predicate or variable
225
239
  itself rather than an array.
226
240
 
241
+ `preds` and `vars` take a string of names separated by spaces or commas.
242
+ Each name MUST be an ASCII identifier and MUST NOT be a reserved JavaScript
243
+ word. `preds` MUST also reject control and primitive names and the reserved
244
+ names `step`, `clause`, `activated`, `forward`, `backward`, `struct`,
245
+ `implies` and `implied_by`.
246
+
227
247
  A top-level expression statement that calls a predicate supplied by rule 4,
228
248
  such as a misspelled `fcat(p(1))`, states nothing; a loader MUST report it as
229
249
  an error rather than ignore it.
230
250
 
231
- ### 4.4 Terms in a program
232
-
233
- Within a program, a JavaScript string is an atom and a `BigInt` an integer. A
234
- finite JavaScript number is an integer when it is integral and a float
235
- otherwise: `2` and `2.0` are both the integer 2, and `float(2)` is the float
236
- 2.0. An integer beyond 2^53 is written as a `BigInt` literal, such as
237
- `9007199254740993n`, since a number literal would already have rounded it. An
238
- array is a list, and `[H, ...T]` the list with head `H` and tail `T`.
239
- `struct('name', A1, ...)` builds a compound with any name, and
240
- `struct('name')` the atom. Every occurrence of `_` in a clause is a distinct
241
- variable, an **anonymous variable**: the occurrences are named `_0`, `_1`,
242
- ... in the order of the clause's text, skipping names the clause already
243
- uses, and clause displays and bindings (Section 10) show these names. A
244
- program SHOULD NOT name its own variables `_` followed by digits, which
245
- Section 5.1 treats as anonymous.
246
-
247
- In a goal position, an array is the conjunction of its items: a statement's
248
- goal, the argument of `and`, `or`, `not`, `call` and `once`, and the goal of
249
- `findall`, and either part of a rule template (Section 4.6). Anywhere else an
250
- array is a list.
251
-
252
- Operators do not build terms. Variables, compounds and predicates have no
253
- JavaScript primitive value, so an operator applied to one, such as `X + 1` or
254
- `X > 1`, MUST raise an error that says what to write instead: `add(X, 1)`,
255
- `gt(X, 1)`. An operator applied only to plain JavaScript values is
256
- JavaScript's own: `3 + 4` is the integer 7, and `1 < 2` is the JavaScript
257
- `true`, which is not a term, so stating it is an error.
258
-
259
- ### 4.5 Stratification
251
+ ### 3.3 Term construction
252
+
253
+ Program expressions construct terms as follows. This is distinct from
254
+ reading a data document (Section 9.1).
255
+
256
+ | Program expression | Term constructed |
257
+ | --- | --- |
258
+ | A JavaScript string, such as `'alice'` | Atom. |
259
+ | A `BigInt` literal, such as `42n` | Exact integer. |
260
+ | An integral finite number, such as `2` or `2.0` | Integer. |
261
+ | A non-integral finite number, such as `0.5` | Float. |
262
+ | `float(N)`, where `N` is a finite JavaScript number | Float, including an integral value or signed zero. |
263
+ | An implicit variable name, such as `X` | Variable (Section 3.2). |
264
+ | `p(T1, ..., Tn)`, with `n >= 1` | Compound named `p`, when `p` is a predicate constructor. |
265
+ | `p` or `p()` | Atom `p`, when `p` is a predicate constructor. |
266
+ | `struct(Name, T1, ..., Tn)` | Compound with the atom name `Name`; `struct(Name)` gives the atom. |
267
+ | `[]`, `[T1, ..., Tn]`, `[Head, ...Tail]` | Lists (Section 2.2). |
268
+
269
+ Thus `2.0` in a program is an integer; use `float(2)` for the float `2.0`.
270
+ Use a `BigInt` literal for an integer outside JavaScript's exact number
271
+ range, for example `9007199254740993n`. Numeric expressions are evaluated by
272
+ JavaScript before conversion to terms.
273
+
274
+ The first argument of `struct` MUST be a JavaScript string.
275
+
276
+ In `[Head, ...Tail]`, a logical variable or compound used as `Tail` supplies
277
+ the tail term, and a JavaScript array supplies its elements. Spreading a
278
+ JavaScript string uses JavaScript's character iteration; it does not supply
279
+ an atom tail. To construct an arbitrary atom or numeric tail in a program,
280
+ use `struct('.', Head, Tail)`. Documents use the bracket-tail syntax for any
281
+ tail term without executing a JavaScript spread.
282
+
283
+ Each occurrence of `_` in a clause is a distinct anonymous variable.
284
+ Anonymous occurrences are named `_0`, `_1`, ... in textual order, skipping
285
+ names already used in the clause. Clause displays and proof bindings use
286
+ these names. Programs SHOULD NOT give their own variables names consisting
287
+ of `_` followed by digits, which negation treats as anonymous.
288
+
289
+ Operators do not construct logical terms. An operator applied to a variable,
290
+ compound or predicate constructor, such as `X + 1` or `X > 1`, MUST raise
291
+ an error identifying the term form to write: `add(X, 1)` or `gt(X, 1)`.
292
+ Operators on ordinary JavaScript values keep their JavaScript meaning:
293
+ `3 + 4` gives the integer 7, but `1 < 2` gives a boolean, which is not a term.
294
+
295
+ ### 3.4 Statements
296
+
297
+ The basic statement forms are:
298
+
299
+ | Form | Meaning |
300
+ | --- | --- |
301
+ | `fact(T)` | State one fact with head `T` and no body. |
302
+ | `implies(Body, Head)` | State a forward rule. `Body` is a goal or a non-empty array of goals; `Head` is one head or a non-empty array of heads. |
303
+ | `implied_by(Head, Body)` | State a backward rule with one head. `Body` is a goal or a non-empty array of goals. |
304
+ | `query(G)` | Report the successful instances of `G`. An array denotes one conjunction. |
305
+ | `contradiction(G)` | Halt with conclusion `'false'` when `G` succeeds. An array denotes one conjunction. |
306
+ | `facts_from(Path)` | Read a document from a path and state one fact per expression. |
307
+ | `facts_from({text: Text})` | Read a document from a string and state one fact per expression. |
308
+
309
+ `implies` and `implied_by` require exactly two arguments. The variadic forms
310
+ of `fact`, `query` and `contradiction` are also defined:
311
+
312
+ ```js
313
+ fact(p('a'), p('b')) // Two facts: fact(p('a')); fact(p('b')).
314
+ query(p(X), q(X)) // One query: query([p(X), q(X)]).
315
+ contradiction(p(X), q(X)) // One conjunction that triggers a contradiction.
316
+ ```
317
+
318
+ `fact(T1, ..., Tn)` states `n` independent facts in argument order;
319
+ `fact()` states none. `query(G1, ..., Gn)` and
320
+ `contradiction(G1, ..., Gn)` require `n >= 1` and form one conjunctive body,
321
+ not separate queries or contradictions. `query()` and `contradiction()`
322
+ MUST be rejected. For example:
323
+
324
+ ```js
325
+ fact(parent('alice', 'bob'))
326
+ fact(parent('bob', 'carol'))
327
+ implies([parent(X, Y), parent(Y, Z)], grandparent(X, Z))
328
+ query(grandparent(X, Z))
329
+ ```
330
+
331
+ Queries are forward rules with head `'true'`; contradictions are forward
332
+ rules with head `'false'`. Their reporting and halting behavior is defined
333
+ in Section 8. `implies` and `implied_by` also return rule values. A value
334
+ embedded in another statement contributes a template or inspection pattern
335
+ as Section 6 specifies, instead of a separate clause.
336
+
337
+ `facts_from` input MUST be read using Section 9.1 and MUST NOT be executed.
338
+ It only states facts. A path requires file access; a text string does not.
339
+
340
+ ### 3.5 Clause constraints and numbering
341
+
342
+ After embedded rule calls have been excluded (Section 6.2), clauses are
343
+ numbered from 1 in statement order. A multi-argument `fact` contributes one
344
+ numbered clause per argument. Each clause records the source line where its
345
+ statement call begins; facts read by `facts_from` use that call's line.
346
+
347
+ A clause MUST be rejected when:
348
+
349
+ - a head is not an atom or compound;
350
+ - a head uses `step/4` or `clause/2`, reserved for proof documents, or
351
+ explicitly states `activated/2`, reserved for template activations;
352
+ - a head is a primitive or control, except the head `'true'` of a query or
353
+ `'false'` of a contradiction; `implies` MUST NOT conclude either atom;
354
+ - a body goal is neither a variable, atom nor compound, or is an empty or
355
+ non-proper list in a goal position.
356
+
357
+ Conjunctive bodies are flattened to their ordered goals. Conjunctive forward
358
+ heads retain their order. Only a forward rule may have several heads;
359
+ backward templates with several heads are expanded as Section 6.2 defines.
360
+ Reserved template and inspection forms are permitted only in the positions
361
+ specified in Section 6.
362
+
363
+ ## 4. Goals and Primitives
364
+
365
+ ### 4.1 Goal syntax
366
+
367
+ A goal is an atom, a compound, a variable to be bound to a callable term,
368
+ or a non-empty proper array of goals denoting their conjunction. A number,
369
+ an empty array or an open or improper list is not a goal.
370
+
371
+ Array-to-conjunction notation applies in these positions:
372
+
373
+ - a rule body and each argument of `query` or `contradiction`;
374
+ - each argument of `and`, `or`, `not`, `call` and `once`;
375
+ - the second argument of `findall`;
376
+ - both arguments of a rule template or source inspection pattern.
377
+
378
+ It also applies to a forward head, where the conjunction means several
379
+ conclusions. Elsewhere an array denotes list data. For example:
380
+
381
+ ```js
382
+ query([p(X), q(X)]) // Conjunction of two goals.
383
+ query(p([X, Y])) // One goal with a list argument.
384
+ implies(p(X), [q(X), r(X)]) // Two heads.
385
+ ```
386
+
387
+ The control meanings apply in goal contexts. Arithmetic terms with the
388
+ names `and`, `or` and `not` instead have the meanings of Section 5.
389
+
390
+ Unbound callable variables and forward dependencies are restricted by
391
+ Section 6.1. A goal whose name and arity identify neither a control,
392
+ primitive, inspection form nor any clause head has no solution.
393
+
394
+ ### 4.2 Controls
395
+
396
+ | Control | Term | Meaning |
397
+ | --- | --- | --- |
398
+ | `and(A, B)`, `[A, B]` | `and(A, B)` | Conjunction: solve `A`, then `B`. |
399
+ | `or(A, B)` | `or(A, B)` | Disjunction: the solutions of `A`, then those of `B`. |
400
+ | `not(G)` | `not(G)` | Negation: succeeds once, binding nothing, when `G` has no solution. When the negation is solved, every variable of `G` MUST be bound except anonymous ones, which stand for any value: `not(q(X, _))` succeeds when `q(X, Y)` has no solution for any `Y`. A named unbound variable is an error. |
401
+ | `call(G)` | `call(G)` | The solutions of `G`. |
402
+ | `once(G)` | `once(G)` | The first solution of `G`. |
403
+ | `findall(T, G, L)` | `findall(T, G, L)` | Unifies `L` with the list of instances of `T`, one per solution of `G`, in order, each renamed apart. |
404
+
405
+ Anonymous variables are `_` occurrences and source variables named `_`
406
+ followed by digits (Section 3.3), including their renamed-apart copies.
407
+
408
+ The term forms in the table have exactly the displayed arities. In program
409
+ scripts, the following constructors additionally accept goal sequences:
410
+
411
+ | Constructor | Result |
412
+ | --- | --- |
413
+ | `and(G1, ..., Gn)` | Left-associated conjunction; for `n = 1`, `G1`; for `n = 0`, `'true'`. |
414
+ | `or(G1, ..., Gn)` | Left-associated disjunction; for `n = 1`, `G1`; for `n = 0`, `'fail'`. |
415
+ | `not(G1, ..., Gn)` | `not` of the conjunction, using `'true'` when `n = 0`. |
416
+ | `call(G1, ..., Gn)` | `call` of that conjunction. |
417
+ | `once(G1, ..., Gn)` | `once` of that conjunction. |
418
+
419
+ For example, `and(A, B, C)` constructs `and(and(A, B), C)` and
420
+ `not(A, B)` constructs `not(and(A, B))`. Document calls to `and` and `or`
421
+ with more than two arguments also denote left-associated chains. Other
422
+ document calls retain their stated name and arity; in particular `not(A, B)`
423
+ in a document is a compound `not/2`, not the unary control.
424
+
425
+ ### 4.3 Primitives
426
+
427
+ In a flow pattern, `+` marks an argument that MUST be bound when the goal
428
+ runs, `-` one that MUST be unbound, `?` either, and `@` one only inspected. A
429
+ primitive called outside its patterns raises an error.
430
+
431
+ | Primitive | Pattern | Meaning |
432
+ | --- | --- | --- |
433
+ | `'true'`, `'fail'`, `'false'` | | Succeeds; fails; fails. |
434
+ | `unify(?X, ?Y)` | | Unifies `X` and `Y`. |
435
+ | `not_unify(@X, @Y)` | | Succeeds, binding nothing, when `X` and `Y` do not unify. |
436
+ | `identical(@X, @Y)` | | `X` and `Y` are identical. |
437
+ | `not_identical(@X, @Y)` | | `X` and `Y` are not identical. |
438
+ | `compare(?O, @X, @Y)` | | Unifies `O` with `'<'`, `'='` or `'>'`, by the standard order. |
439
+ | `is(?V, +E)` | | Evaluates `E` (Section 5) and unifies `V` with the result. |
440
+ | `eq(+E1, +E2)`, `ne(+E1, +E2)` | | The values of `E1` and `E2` are equal, or not. |
441
+ | `lt(+E1, +E2)`, `le(+E1, +E2)`, `gt(+E1, +E2)`, `ge(+E1, +E2)` | | Compares the values of `E1` and `E2`. |
442
+ | `is_var(@X)`, `is_nonvar(@X)` | | `X` is an unbound variable, or is not. |
443
+ | `is_ground(@X)` | | `X` contains no unbound variable. |
444
+ | `is_atom(@X)`, `is_number(@X)` | | `X` is an atom, or a number. |
445
+ | `is_int(@X)`, `is_float(@X)` | | `X` is an integer, or a float. |
446
+ | `is_compound(@X)` | | `X` is a compound; a non-empty list is one. |
447
+ | `functor` | `functor(+T, ?N, ?A)`, `functor(-T, +N, +A)` | Name and arity of `T`, or `T` built with fresh variable arguments. When constructing, `A` MUST be an integer from 0 to 1024. |
448
+ | `arg` | `arg(+N, +T, ?A)` | `A` is the `N`th argument of `T`, counting from 1. |
449
+ | `univ` | `univ(+T, ?L)`, `univ(-T, +L)` | `L` is the list of `T`'s name and arguments. |
450
+ | `atom_chars` | `atom_chars(+A, ?L)`, `atom_chars(-A, +L)` | `L` is the list of `A`'s characters as atoms. |
451
+ | `atom_codes` | `atom_codes(+A, ?L)`, `atom_codes(-A, +L)` | `L` is the list of `A`'s character code points. |
452
+ | `atom_length` | `atom_length(+A, ?N)` | `N` is the number of characters of `A`. |
453
+ | `number_chars` | `number_chars(?N, +L)`, `number_chars(+N, -L)` | A bound `L` is read as a number: an optional sign and decimal digits give an integer, and with a fraction or an exponent a float, as in `'007'`, `'-21.5'`, `'.5'` and `'1E3'`; other text fails. Otherwise `L` spells `N` in its canonical text (Section 9.2). |
454
+ | `atom_concat` | `atom_concat(+A, +B, ?AB)`, `atom_concat(?A, ?B, +AB)` | `AB` is `A` followed by `B`; with `AB` given, every split, shortest `A` first. |
455
+
456
+ A character is a Unicode code point. Every primitive except `atom_concat` has
457
+ at most one solution. Primitives MUST be pure: their solutions depend only on
458
+ their arguments. A primitive given an argument of the wrong kind for its
459
+ patterns raises an error, as `atom_length(123, N)` does; one given arguments
460
+ of the right kinds that has no solution fails, as `arg(5, f(1), A)` does.
461
+
462
+ All primitives take exactly the displayed number of arguments. `functor`
463
+ and `univ` expose list structure as specified in Section 2.2; use bracket
464
+ syntax when writing lists.
465
+
466
+ ## 5. Arithmetic
467
+
468
+ ### 5.1 Expressions
469
+
470
+ An arithmetic expression is a number, a variable bound to an expression,
471
+ one of the atoms `'pi'`, `'e'`, `'tau'`, or a function term from Section 5.2.
472
+ The constants denote binary64 approximations of pi, e and twice pi.
473
+ Arguments of a function term are evaluated recursively. An unbound variable,
474
+ an unknown function, an unsupported arity or any other atom is an error.
475
+
476
+ Arithmetic is evaluated only where required by a primitive such as `is`,
477
+ `eq` or `lt`. Elsewhere `add(1, 2)` is a compound term, not the number 3.
478
+ Comparisons are goals (Section 4.3), not arithmetic expressions.
479
+
480
+ ### 5.2 Functions and arities
481
+
482
+ The arity column gives the exact accepted number of arguments, or an
483
+ inclusive range. Function names are written as calls, for example
484
+ `add(X, 1)` and `round(X, 2)`.
485
+
486
+ | Names | Arity | Meaning |
487
+ | --- | --- | --- |
488
+ | `add`, `sub`, `mul` | 2 | Addition, subtraction, multiplication. |
489
+ | `div`, `floordiv`, `mod` | 2 | True division, floor division, floor remainder. |
490
+ | `pow` | 2 | Exponentiation. |
491
+ | `shl`, `shr`, `xor`, `and`, `or` | 2 | Integer shifts and bitwise operations. Shift counts must be nonnegative integers. |
492
+ | `not` | 1 | Integer bitwise inversion. |
493
+ | `neg`, `pos` | 1 | Numeric negation, identity. |
494
+ | `abs` | 1 | Absolute value. |
495
+ | `min`, `max` | 2 or more | Least or greatest argument. |
496
+ | `round` | 1 or 2 | Round half to even, optionally to an integer decimal-place count. |
497
+ | `int`, `trunc`, `floor`, `ceil` | 1 | Integer conversion: toward zero, toward zero, down, up. |
498
+ | `float` | 1 | Conversion to binary64. |
499
+ | `sqrt`, `isqrt` | 1 | Square root as a float; floor square root of a nonnegative integer. |
500
+ | `exp`, `log2`, `log10` | 1 | Exponential, base-2 logarithm, base-10 logarithm. |
501
+ | `log` | 1 or 2 | Natural logarithm, or logarithm with the second argument as base. |
502
+ | `sin`, `cos`, `tan`, `asin`, `acos`, `atan` | 1 | Trigonometric functions and inverses; angles are in radians. |
503
+ | `atan2` | 2 | Angle from its ordinate and abscissa, in that order. |
504
+ | `sinh`, `cosh`, `tanh` | 1 | Hyperbolic functions. |
505
+ | `hypot` | 1 or more | Euclidean norm. |
506
+ | `degrees`, `radians` | 1 | Conversion from radians to degrees, or degrees to radians. |
507
+ | `fmod`, `copysign` | 2 | Float remainder with the dividend's sign; magnitude of the first argument with the second's sign. |
508
+ | `gcd`, `lcm` | 1 or more | Nonnegative integer greatest common divisor or least common multiple. |
509
+
510
+ A zero-argument call denotes an atom, not a function term; only the three
511
+ constant atoms of Section 5.1 are arithmetic values. A `float(N)` applied
512
+ directly to a JavaScript number in a script constructs a float immediately
513
+ (Section 3.3).
514
+
515
+ ### 5.3 Numeric results
516
+
517
+ Integer arithmetic is exact and unbounded. Integer operands give an integer
518
+ result except for `div`, a negative exponent in `pow`, and functions defined
519
+ to return a float. Mixed `add`, `sub`, `mul`, `div`, `floordiv`, `mod` and
520
+ `pow` give a float. Integer-conversion functions return integers; `min` and
521
+ `max` return the selected operand with its original kind. No operation
522
+ implicitly makes an integer and a float unify.
523
+
524
+ `floordiv` rounds down and `mod` has the divisor's sign:
525
+ `floordiv(-7, 3)` is -3 and `mod(-7, 3)` is 2. `div` of integers rounds
526
+ their exact quotient once to the nearest binary64 value, with halfway cases
527
+ rounded to even, including in the subnormal range. Underflow to zero keeps
528
+ the sign. `round(X)` gives an integer; `round(X, Digits)` rounds to the
529
+ specified number of decimal places. Float spelling is defined in Section 9.2.
530
+
531
+ Numeric comparison is exact across integers and floats. Bitwise operations
532
+ use unbounded two's-complement integers.
533
+
534
+ ### 5.4 Arithmetic errors and limits
535
+
536
+ An evaluation MUST raise an error, rather than produce a value, on a division
537
+ or modulo by zero, a domain error (such as `sqrt(-1)` or `log(0)`), a bitwise
538
+ operation, `gcd` or `lcm` on a float, a negative shift count, when the result
539
+ is not a finite real number,
540
+ or when a power or left shift would need more than 2^26 bits: for a power of
541
+ integers `pow(A, B)` with `B > 0` and `abs(A) > 1`, when `B` times the bit
542
+ length of `A` exceeds 2^26; for a shift `shl(A, B)` of integers, when `B`
543
+ exceeds 2^26.
544
+
545
+ ## 6. Rule Structure
546
+
547
+ ### 6.1 Dependencies and stratification
260
548
 
261
549
  A body goal depends on a clause when the goal, renamed apart, unifies with
262
550
  one of the clause's heads. The dependency is **closed** when the goal occurs
263
- inside a negation or as the goal of a collection (Section 5.1), and **open**
551
+ inside a negation or as the goal of a collection (Section 4.2), and **open**
264
552
  otherwise. Each clause has a rank: the least assignment such that a clause's
265
553
  rank is at least the rank of every clause it depends on, plus one for a closed
266
- dependency. Forward rules run in order of rank (Section 7.2).
554
+ dependency. Forward rules run in order of rank (Section 8.2).
267
555
 
268
556
  A program MUST be rejected when:
269
557
 
270
- - no such assignment exists ("unstratified negation or collection
271
- dependency"), that is, a closed dependency lies on a cycle;
558
+ - no such assignment exists, because a closed dependency lies on a cycle;
272
559
  - a forward rule can reach, through dependencies, a clause with a body goal
273
- that is a variable ("forward dependencies require statically named calls").
560
+ that is a variable.
274
561
 
275
562
  Because dependencies compare whole terms, two relations sharing a predicate
276
563
  name MAY have different ranks.
277
564
 
278
- ### 4.6 Inline rule templates
565
+ ### 6.2 Inline rule templates
279
566
 
280
567
  Nested `implies(Body, Head)` and `implied_by(Head, Body)` calls construct rule
281
568
  templates. A rule value in a conclusion MUST occur as a top-level conjunct of
282
569
  an `implies` conclusion; in a body, `implies` and `implied_by` are inspection
283
- goals (Section 4.7). A rule value anywhere else in a clause, such as an
570
+ goals (Section 6.3). A rule value anywhere else in a clause, such as an
284
571
  argument of an ordinary head or goal, or the template or result of `findall`,
285
- MUST be rejected. The
286
- conclusion MAY combine ordinary heads and several templates. Each template's
572
+ MUST be rejected. The conclusion MAY combine ordinary heads and several
573
+ templates. Each template's
287
574
  body and head MAY themselves be conjunctions, written as arrays. A backward
288
575
  template with several heads defines one backward clause per head, sharing
289
576
  the same activation and body. Empty and open lists are not goals or heads.
290
577
 
291
- JavaScript evaluates inner calls first. When a statement embeds the rule
292
- value returned by an earlier call in the same program build, the earlier
293
- call's standalone registration MUST be removed before clause numbering and
294
- validation. This applies through arrays, helpers and stored values. A value
295
- MAY be reused in several generators; none of those uses restores its
296
- standalone registration. Separate program builds collect their registrations
297
- independently, even when a rule value is passed between them. Anonymous
298
- variables are named within each enclosing clause, so anonymous variables of
299
- the template cannot capture unrelated anonymous variables of the generator.
578
+ A rule call embedded in another statement of the same program contributes
579
+ only its rule value, not a standalone clause. This exclusion precedes clause
580
+ numbering and validation. This applies through arrays, helpers and stored
581
+ values. A value MAY be reused in several generators; it contributes no
582
+ standalone clause in that program. Separate programs apply this rule
583
+ independently. Anonymous variables are named within each enclosing clause,
584
+ so a template's anonymous variables cannot capture unrelated anonymous
585
+ variables of the generator.
300
586
 
301
587
  The pure constructors `forward(Body, Head)` and `backward(Head, Body)` also
302
- construct templates with the same lowering and scope. They do not themselves
303
- register clauses.
588
+ construct templates with the same expansion and scope. They state no clauses
589
+ unless embedded in a generating statement.
304
590
 
305
591
  A template variable is **captured** when it also occurs in the generating
306
592
  clause's body or in an ordinary sibling head. The other variables are local
307
593
  to that template: they are universally quantified within the generated rule,
308
594
  except for head-only variables of a forward template, which receive witnesses
309
- as Section 7.2 describes. Variables shared only between sibling templates are
595
+ as Section 8.2 describes. Variables shared only between sibling templates are
310
596
  local to each. Every call in a template body, including calls inside controls,
311
597
  MUST be statically named; a variable in a term's argument is permitted, but a
312
598
  variable used as a goal is not. A forward template MAY conclude further inline
313
599
  templates. A backward template MUST NOT conclude templates.
314
600
 
315
- Templates are lowered before validation, indexing and stratification. Starting
316
- with all stated clauses, in clause order, replace each template conjunct,
601
+ Template expansion is part of the language and precedes validation and
602
+ stratification. Starting with all stated clauses, in clause order, replace
603
+ each template conjunct,
317
604
  left to right, with `activated(N, Captures)`. `Captures` is a list of its
318
605
  captured variables in order of first occurrence in the template as written;
319
606
  `N` is the number of the first clause appended for it. Append a forward or
@@ -323,26 +610,26 @@ head conjunction; a backward template appends one clause per head in order.
323
610
  Continue processing the appended clauses in order, lowering any nested
324
611
  templates the same way. Original clause numbers are kept; appended clauses
325
612
  are numbered consecutively after them and inherit the generator's source line.
326
- Capture metadata belongs to each appended clause, including one whose head
327
- is subsequently lowered again.
613
+ Each appended clause retains its capture list, including when its head
614
+ contains another template.
328
615
 
329
616
  For example, `implies(cat(X), implies(dog(Y), test('yes')))` as the only
330
- stated clause becomes these two clauses:
617
+ stated clause gives these expanded clause displays:
331
618
 
332
619
  ```js
333
- implies(cat(X), activated(2, []))
334
- implies([activated(2, []), dog(Y)], test('yes'))
620
+ clause(1, implies(cat(X), activated(2, [])))
621
+ clause(2, implies([activated(2, []), dog(Y)], test('yes')))
335
622
  ```
336
623
 
337
624
  `Y` stays local to the second clause. Its activation is required even though
338
625
  the template does not capture `X`. A generator with several solutions but
339
- identical captures enables the same rule instance. No arbitrary rule term is
340
- installed during reasoning. All potential generated clauses and their
341
- activation dependencies participate in Section 4.5, including clauses whose
626
+ identical captures enables the same rule instance. All potential generated
627
+ clauses and their activation dependencies participate in Section 6.1,
628
+ including clauses whose
342
629
  generators never fire. A closed dependency cycle MUST therefore be rejected
343
630
  even if its template would remain inactive.
344
631
 
345
- ### 4.7 Source rule inspection
632
+ ### 6.3 Source rule inspection
346
633
 
347
634
  As goals, `implies(Body, Head)` and `implied_by(Head, Body)` match ordinary
348
635
  forward and backward source rules respectively. The fixed catalogue contains
@@ -351,21 +638,21 @@ templates and whose bodies contain no inspection goals, including inside
351
638
  controls. Facts, queries, contradictions, template generators and appended
352
639
  clauses are excluded. Inspecting rules therefore cannot inspect themselves.
353
640
  A rule value used as an inspection pattern is embedded in the inspecting
354
- statement (Section 4.6), so a stored rule value used as a pattern loses its
641
+ statement (Section 6.2), so a stored rule value used as a pattern loses its
355
642
  standalone clause and is not in the catalogue.
356
643
 
357
644
  The catalogue keeps source order. A rule's body and forward head conjunctions
358
645
  are terms `and(...)`, as normalized goals are, and inspection arguments are
359
- goal positions. Each attempt freshens the whole rule with one variable map:
360
- shared variables stay shared, and different attempts are independent. Matching
361
- can instantiate these variables. Inspection reads the rule's structure; it
646
+ goal positions. Each attempt renames the entire rule apart, preserving
647
+ shared variables. Matching can instantiate these variables. Inspection reads
648
+ the rule's structure; it
362
649
  does not solve its body or establish that its head holds.
363
650
 
364
651
  Free variables supplied by a successful inspection are scoped universal
365
652
  pattern variables. Forward conclusions preserve them, including through
366
653
  backward derivations and copied collection results. Derived patterns are
367
654
  identified up to variable renaming and freshened, together with their evidence,
368
- at every use. Unrelated unbound variables keep Section 7.2's witness behavior.
655
+ at every use. Unrelated unbound variables keep Section 8.2's witness behavior.
369
656
  When inspection variables remain free in a conclusion or its captured
370
657
  template context, that firing MUST NOT introduce head-only existential
371
658
  witnesses: it MUST fail with an error requiring the inspection variables to
@@ -375,138 +662,123 @@ Inspection uses a fixed source catalogue, so its own results do not depend on
375
662
  forward rounds. Other goals using derived patterns still participate in
376
663
  stratification. Negation and collection retain their explicit obligations.
377
664
 
378
- ## 5. Goals, Controls and Primitives
665
+ ## 7. Semantics
666
+
667
+ ### 7.1 Herbrand interpretation
668
+
669
+ Ordinary predicates have a **Herbrand interpretation**: ground terms denote
670
+ themselves, and predicates relate those terms. The **Herbrand universe**
671
+ contains the finite ground terms of Section 2, including values constructed
672
+ by arithmetic or text operations and Skolem terms. The **Herbrand base** is
673
+ the set of ordinary ground predicate applications over that universe,
674
+ including predicates of arity 0. An interpretation is a subset of the base.
675
+
676
+ Matching uses Section 2.3's unification, including its signed-zero rule.
677
+ Asserting a relation does not change term identity. Controls, primitives
678
+ and source inspection have the fixed meanings of Sections 4-6.
679
+
680
+ ### 7.2 Variables and witnesses
681
+
682
+ Variables of facts and backward clauses are universally quantified within
683
+ their clause, except for collection-local variables (Section 4.2).
684
+ `fact(p(X))` states every ground instance of `p(X)`. Resolution may return
685
+ a universal answer containing variables without enumerating its ground
686
+ instances. Template variables have the scope of Section 6.2.
687
+
688
+ An unbound variable in a forward conclusion instead receives a witness,
689
+ unless it is a scoped inspection variable (Section 6.3). For example,
690
+ `implies(person(X), has_token(X, T))` introduces an existential witness for
691
+ `T`. Section 8.2 determines its Skolem term from the rule and head context,
692
+ including captured template values. Body variables absent from that context
693
+ do not distinguish witnesses; shared head variables share a witness.
694
+
695
+ This gives the specified Skolemized reading of existential conclusions.
696
+ The original existential rule need not have a least model over its original
697
+ vocabulary. A witness is an ordinary compound in subsequent reasoning; it
698
+ does not imply the existence of a distinct real-world object.
699
+
700
+ ### 7.3 Positive least model
701
+
702
+ The positive relational fragment consists of ground facts and rules with
703
+ ordinary body calls, conjunction and disjunction, with each head variable
704
+ bound by the body. Primitives may be included when earlier goals supply
705
+ their required inputs and their solutions agree with the ground relation
706
+ under further substitution. This fragment excludes negation, collection,
707
+ `once`, inspection and tests of an unbound variable's current state.
708
+
709
+ Its meaning is the **least Herbrand model**: the smallest interpretation
710
+ containing the facts and closed under ground rule instances, with matching
711
+ as in Section 7.1. If a body holds, every head of that rule instance holds.
712
+ Existential forward rules extend this reading with the specified witnesses.
713
+ The closure can be infinite.
714
+
715
+ Forward and backward clauses both express implication in this fragment;
716
+ their directions determine evaluation. A completed ordinary goal search
717
+ returns the goal's instances that hold in the model. The model includes
718
+ source facts and consequences available only by backward search, beyond
719
+ the newly derived facts or selected answers printed by a run.
720
+
721
+ ### 7.4 Negation and collection
722
+
723
+ For stratified negation, interpret ranks in increasing order, fixing lower
724
+ strata before testing absence at a higher rank (Section 6.1). `not(G)`
725
+ holds when `G` has no solution, with the binding restrictions of Section
726
+ 4.2. This is absence relative to the program, not falsity in the world.
727
+ For relational goals this gives the stratified least-model reading.
728
+
729
+ Collection also waits for its dependencies. `findall` collects ordered
730
+ search solutions, including repeated derivations and nonground instances;
731
+ its meaning is not determined by a set of ground atoms alone. Bindings
732
+ made while solving its goal do not escape except through the copied result
733
+ list. Clause order and duplicate source clauses can affect that list.
734
+
735
+ ### 7.5 Sets and operational behavior
736
+
737
+ Derived facts and reported answers follow the duplicate-suppression rules
738
+ of Section 8. These rules do not remove alternative search derivations.
739
+ The unrestricted least-model reading alone therefore does not define every
740
+ program's answers. `once` selects the first solution, and tests such as
741
+ `is_var`, `identical` and `not_unify` can observe current bindings:
379
742
 
380
- The program-dependent source inspection goals `implies/2` and `implied_by/2`
381
- are defined in Section 4.7.
382
-
383
- ### 5.1 Controls
384
-
385
- | Control | Term | Meaning |
386
- | --- | --- | --- |
387
- | `and(A, B)`, `[A, B]` | `and(A, B)` | Conjunction: solve `A`, then `B`. |
388
- | `or(A, B)` | `or(A, B)` | Disjunction: the solutions of `A`, then those of `B`. |
389
- | `not(G)` | `not(G)` | Negation: succeeds once, binding nothing, when `G` has no solution. When the negation is solved, every variable of `G` MUST be bound except anonymous ones, which stand for any value: `not(q(X, _))` succeeds when `q(X, Y)` has no solution for any `Y`. A named unbound variable is an error. |
390
- | `call(G)` | `call(G)` | The solutions of `G`. |
391
- | `once(G)` | `once(G)` | The first solution of `G`. |
392
- | `findall(T, G, L)` | `findall(T, G, L)` | Unifies `L` with the list of instances of `T`, one per solution of `G`, in order, each renamed apart. |
393
-
394
- A variable is anonymous when its name, up to any `#` a renaming apart
395
- (Section 7.1) adds, is `_` followed by digits (Section 4.4), or is one a
396
- reader made for a `_` (Section 9).
397
-
398
- Conjunction and disjunction are binary. In a program, `and` and `or` with
399
- more than two goals build the chain from the left, `and(A, B, C)` being
400
- `and(and(A, B), C)`, and `or` with one goal is that goal. `not`, `call` and
401
- `once` with several goals take their conjunction. A goal text (Section 9)
402
- reads `and` and `or` with more than two arguments the same way.
403
-
404
- ### 5.2 Primitives
405
-
406
- In a flow pattern, `+` marks an argument that MUST be bound when the goal
407
- runs, `-` one that MUST be unbound, `?` either, and `@` one only inspected. A
408
- primitive called outside its patterns raises an error.
409
-
410
- | Primitive | Pattern | Meaning |
411
- | --- | --- | --- |
412
- | `'true'`, `'fail'`, `'false'` | | Succeeds; fails; fails. |
413
- | `unify(?X, ?Y)` | | Unifies `X` and `Y`. |
414
- | `not_unify(@X, @Y)` | | Succeeds, binding nothing, when `X` and `Y` do not unify. |
415
- | `identical(@X, @Y)` | | `X` and `Y` are identical. |
416
- | `not_identical(@X, @Y)` | | `X` and `Y` are not identical. |
417
- | `compare(?O, @X, @Y)` | | Unifies `O` with `'<'`, `'='` or `'>'`, by the standard order. |
418
- | `is(?V, +E)` | | Evaluates `E` (Section 6) and unifies `V` with the result. |
419
- | `eq(+E1, +E2)`, `ne(+E1, +E2)` | | The values of `E1` and `E2` are equal, or not. |
420
- | `lt(+E1, +E2)`, `le(+E1, +E2)`, `gt(+E1, +E2)`, `ge(+E1, +E2)` | | Compares the values of `E1` and `E2`. |
421
- | `is_var(@X)`, `is_nonvar(@X)` | | `X` is an unbound variable, or is not. |
422
- | `is_ground(@X)` | | `X` contains no unbound variable. |
423
- | `is_atom(@X)`, `is_number(@X)` | | `X` is an atom, or a number. |
424
- | `is_int(@X)`, `is_float(@X)` | | `X` is an integer, or a float. |
425
- | `is_compound(@X)` | | `X` is a compound; a non-empty list is one. |
426
- | `functor` | `functor(+T, ?N, ?A)`, `functor(-T, +N, +A)` | Name and arity of `T`, or `T` built with fresh variable arguments. `A` MUST be between 0 and 1024. |
427
- | `arg` | `arg(+N, +T, ?A)` | `A` is the `N`th argument of `T`, counting from 1. |
428
- | `univ` | `univ(+T, ?L)`, `univ(-T, +L)` | `L` is the list of `T`'s name and arguments. |
429
- | `atom_chars` | `atom_chars(+A, ?L)`, `atom_chars(-A, +L)` | `L` is the list of `A`'s characters as atoms. |
430
- | `atom_codes` | `atom_codes(+A, ?L)`, `atom_codes(-A, +L)` | `L` is the list of `A`'s character code points. |
431
- | `atom_length` | `atom_length(+A, ?N)` | `N` is the number of characters of `A`. |
432
- | `number_chars` | `number_chars(?N, +L)`, `number_chars(+N, -L)` | A bound `L` is read as a number: an optional sign and decimal digits give an integer, and with a fraction or an exponent a float, as in `'007'`, `'-21.5'`, `'.5'` and `'1E3'`; other text fails. Otherwise `L` spells `N` in its canonical text (Section 8.1). |
433
- | `atom_concat` | `atom_concat(+A, +B, ?AB)`, `atom_concat(?A, ?B, +AB)` | `AB` is `A` followed by `B`; with `AB` given, every split, shortest `A` first. |
434
-
435
- A character is a Unicode code point. Every primitive except `atom_concat` has
436
- at most one solution. Primitives MUST be pure: their solutions depend only on
437
- their arguments. A primitive given an argument of the wrong kind for its
438
- patterns raises an error, as `atom_length(123, N)` does; one given arguments
439
- of the right kinds that has no solution fails, as `arg(5, f(1), A)` does.
743
+ ```js
744
+ fact(q('b'))
745
+ implied_by(p(X), [not_unify(X, 'a'), q(X)])
746
+ ```
440
747
 
441
- A goal whose name and arity are neither a control, a primitive nor the head
442
- of any clause has no solution.
443
-
444
- ## 6. Arithmetic
445
-
446
- An expression term is evaluated as follows:
447
-
448
- - a number is its value; the atoms `'pi'`, `'e'` and `'tau'` are π, e and
449
- 2π; a variable bound to an expression is that expression's value; an
450
- unbound variable or any other atom is an error;
451
- - `add`, `sub`, `mul`, `div`, `floordiv`, `mod`, `pow`, `shl`, `shr` and
452
- `xor` with two arguments are addition, subtraction, multiplication, true
453
- division, floor division, modulo, power, shifts and exclusive or; `and` and
454
- `or` with two arguments are bitwise and and or; `not`, `neg` and `pos` with
455
- one argument are bitwise inversion, negation and identity;
456
- - the functions `abs`, `min`, `max` (with two or more arguments), `round`
457
- (with one or two), `int`, `float`, `floor`, `ceil`, `trunc`, `sqrt`,
458
- `isqrt`, `exp`, `log` (with one or two: a value and a base), `log2`,
459
- `log10`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sinh`,
460
- `cosh`, `tanh`, `hypot`, `degrees`, `radians`, `fmod`, `copysign`, `gcd`
461
- and `lcm`.
462
-
463
- Integers are exact and unbounded. An operation on integers gives an integer,
464
- except `div`, which always gives a float, and `pow` with a negative exponent.
465
- An operation with a float operand gives a float. `floordiv` rounds toward
466
- negative infinity and `mod` takes the sign of its divisor: `floordiv(-7, 3)`
467
- is -3 and `mod(-7, 3)` is 2. `div` of two integers is the float nearest to
468
- their exact quotient. `round` rounds half to even, to an integer with one
469
- argument and to the given number of decimals with two; `int`, `floor`, `ceil`
470
- and `trunc` give integers. A float is written as Section 8.1 says.
471
-
472
- Integer true division rounds once, including in the subnormal range: the
473
- nearest float to `div(1, shl(1, 1074))` is `5e-324`. Halfway cases round to
474
- even; a result that underflows to zero keeps its sign.
748
+ The goal `p(X)` has no answer because the initial unbound `X` unifies with
749
+ `'a'`, causing `not_unify` to fail. The goal `p('b')` succeeds. Forward
750
+ rules calling such clauses can inherit their dependence on call bindings.
751
+ Section 8 defines the observable goal, clause and result order.
475
752
 
476
- An evaluation MUST raise an error, rather than produce a value, on a division
477
- or modulo by zero, a domain error (such as `sqrt(-1)` or `log(0)`), a bitwise
478
- operation or `gcd` on a float, when the result is not a finite real number,
479
- or when a power or left shift would need more than 2^26 bits: for a power of
480
- integers `pow(A, B)` with `B > 0` and `abs(A) > 1`, when `B` times the bit
481
- length of `A` exceeds 2^26; for a shift `shl(A, B)` of integers, when `B`
482
- exceeds 2^26.
753
+ ### 7.6 Termination and proof claims
483
754
 
484
- Comparisons are primitives (Section 5.2), not arithmetic functions: `lt` and
485
- the other comparisons in an expression are an error. Comparison primitives
486
- compare values exactly, including across integers and floats.
755
+ Arithmetic, term construction and witness introduction can generate an
756
+ infinite closure. A finite model does not ensure search termination:
757
+ `implied_by(p(X), p(X))` has an empty least model, but searching `p('a')`
758
+ recurs indefinitely. Exceeding a resource bound raises an error (Section
759
+ 8.3). Contradictions halt without completing the closure (Section 8.5).
760
+ A valid proof establishes only its claims subject to its trusted boundaries
761
+ (Section 11.11), not completeness of the model or the answers.
487
762
 
488
- ## 7. Reasoning
763
+ ## 8. Evaluation and Conclusions
489
764
 
490
- ### 7.1 Search
765
+ ### 8.1 Goal search
491
766
 
492
767
  Goals are solved depth-first, left to right. A goal is solved, in order:
493
768
 
494
- 1. by a control or primitive (Section 5), when it is one;
769
+ 1. by a control, primitive or source inspection (Sections 4 and 6.3), when
770
+ it is one;
495
771
  2. otherwise against the facts derived so far by forward rules with the same
496
772
  name and arity, in the order they were derived;
497
773
  3. then against the program's facts and backward rules with the same name and
498
774
  arity, in clause order, each renamed apart before it is unified with the
499
775
  goal; a rule's body is then solved in its place.
500
776
 
501
- Renaming a clause apart gives each of its variables a fresh variable whose
502
- name is the variable's name followed by `#` and an implementation-specific
503
- suffix. Such names never appear in the documents a run writes (Section 8.3).
777
+ Each clause attempt MUST rename its variables apart before unification.
504
778
 
505
- An implementation MAY index clauses, provided the order above is kept.
779
+ ### 8.2 Forward evaluation and witnesses
506
780
 
507
- ### 7.2 Forward reasoning
508
-
509
- Forward rules run stratum by stratum, in increasing rank (Section 4.5). Within
781
+ Forward rules run stratum by stratum, in increasing rank (Section 6.1). Within
510
782
  a stratum, rounds are repeated until a round adds no new fact. In a round,
511
783
  each rule in clause order is renamed apart and its body solved against the
512
784
  current state; all solutions of the body are collected first, then each is
@@ -515,7 +787,7 @@ concluded:
515
787
  - a head variable the solution leaves unbound is bound to a **Skolem term**
516
788
  `skolem(Rule, Variable, Arguments)`: `Rule` is the clause number of the
517
789
  rule, `Variable` the name of the head variable the term stands for, as the
518
- program writes it (an anonymous one as `_0`, `_1`, ..., Section 4.4), and
790
+ program writes it (an anonymous one as `_0`, `_1`, ..., Section 3.3), and
519
791
  `Arguments` the list of
520
792
  the ground values the solution gives the heads' other variables, in order
521
793
  of their first occurrence in the heads. A Skolem term is thus a function of
@@ -528,8 +800,8 @@ concluded:
528
800
  for, keeps its own name when no other term of the activation has it; the
529
801
  others take that name followed by the first of `1`, `2`, ... that is
530
802
  free, in order of first occurrence in the heads. A rule that keeps meeting new activations does
531
- not terminate (Section 7.3). Derived facts other than scoped inspection
532
- patterns (Section 4.7) are therefore ground. A
803
+ not terminate (Section 8.3). Derived facts other than scoped inspection
804
+ patterns (Section 6.3) are therefore ground. A
533
805
  checker verifies the Skolem terms of a proof (C8, Section 11.9);
534
806
  - a head `'true'` reports the instance of the rule's body, as a conjunction,
535
807
  once per distinct instance (by identity of canonical text);
@@ -538,22 +810,22 @@ concluded:
538
810
  - any other head is added as a derived fact unless an identical fact is
539
811
  already derived or is a ground fact of the program.
540
812
 
541
- When the run asks its own goals (Section 7.4), rules whose heads are all
813
+ When the run asks its own goals (Section 8.4), rules whose heads are all
542
814
  `'true'` are not run.
543
815
 
544
- For an appended forward clause of Section 4.6, prepend one element to
816
+ For an appended forward clause of Section 6.2, prepend one element to
545
817
  `Arguments`: the grounded capture list of its activation. This distinguishes
546
818
  witnesses of different captured contexts even when a head does not mention
547
819
  those values. An empty capture list still contributes one element, `[]`.
548
820
  Original clauses, including generators, use the ordinary witness convention.
549
821
 
550
- Scoped inspection variables of Section 4.7 are preserved instead of receiving
822
+ Scoped inspection variables of Section 6.3 are preserved instead of receiving
551
823
  witnesses; derived conclusions may therefore be universal patterns. Each use
552
824
  renames a pattern and its evidence apart. Such patterns are suppressed when
553
825
  an alpha-equivalent pattern was already derived. Other derived facts keep
554
826
  their ordinary ground identity convention.
555
827
 
556
- ### 7.3 Bounds
828
+ ### 8.3 Resource bounds
557
829
 
558
830
  A run is bounded by `max_depth`, the depth of nested rule bodies (default
559
831
  1000000), by `max_inferences`, the number of goals started (default
@@ -561,21 +833,20 @@ A run is bounded by `max_depth`, the depth of nested rule bodies (default
561
833
  Exceeding a bound MUST raise an error; a partial result MUST NOT be returned
562
834
  as complete.
563
835
 
564
- Each supplied bound MUST be a positive safe integer, at most
565
- 9007199254740991, so a work counter can represent it exactly.
836
+ Each supplied bound MUST be a positive integer no greater than 9007199254740991.
566
837
 
567
- ### 7.4 Goals
838
+ ### 8.4 External goals
568
839
 
569
840
  A run MAY be given goals. After forward reasoning, each goal is solved in
570
841
  turn, and each solution is reported as the instance of its goal, unless an
571
842
  instance identical up to renaming of its variables was already reported for
572
843
  this goal or an earlier one of the same run.
573
844
 
574
- ### 7.5 Halting
845
+ ### 8.5 Contradictions
575
846
 
576
847
  A run that concluded `'false'` has halt code 65; otherwise it has none.
577
848
 
578
- ### 7.6 Conclusions
849
+ ### 8.6 Reported conclusions
579
850
 
580
851
  The conclusions of a run are, in order:
581
852
 
@@ -587,17 +858,17 @@ The conclusions of a run are, in order:
587
858
  4. otherwise: every derived fact except template activations, in the order derived.
588
859
 
589
860
  An explicit goal MAY ask for an activation. Activations remain available as
590
- premises and proof steps; the library's `inferred` list omits them. The
861
+ premises and proof steps. The
591
862
  `derived` statistic counts them as facts added during reasoning.
592
863
 
593
864
  The output of a run is a comment line saying which of these the conclusions
594
- are, followed by the canonical text (Section 8) of each conclusion, one per
865
+ are, followed by the canonical text (Section 9) of each conclusion, one per
595
866
  line. The comment MUST say when the run halted, when the conclusions answer
596
867
  goals, when they answer `query()` rules, or when they are derived facts, and
597
868
  MUST say so when there are none. Comments are informative and MAY be worded
598
- differently; they are ignored when the output is read (Section 9).
869
+ differently; they are ignored when the output is read (Section 9.1).
599
870
 
600
- ### 7.7 Proof recording
871
+ ### 8.7 Proof generation
601
872
 
602
873
  When a proof is requested, each solution records how each of its goals was
603
874
  justified: by a fact or rule of the program, by a derived fact (whose own
@@ -612,96 +883,128 @@ A goal such as `is_var(X)` followed by `unify(X, 'a')`
612
883
  cannot be recorded faithfully by its final substitution, so such a run
613
884
  cannot produce a proof.
614
885
 
615
- ## 8. Canonical Text
886
+ ## 9. Document Syntax and Canonical Text
887
+
888
+ A document is data, not a program. Readers MUST use the syntax below and
889
+ MUST NOT execute any expression. Writers MUST use the canonical forms of
890
+ Sections 9.2-9.4. The grammar is given in Appendix A.
616
891
 
617
- Every term has exactly one canonical text, which is a JavaScript expression.
892
+ ### 9.1 Accepted document syntax
618
893
 
619
- ### 8.1 Atoms, numbers, variables and lists
894
+ A document is UTF-8 text containing expression statements. A statement ends
895
+ at a line feed outside brackets, a `;`, or the end of the document. Empty
896
+ statements, comments (`// ...` and `/* ... */`) and indentation are ignored.
897
+ Each term records the line where its expression begins. Writers emit one
898
+ expression per line. Readers accept exactly:
620
899
 
621
- - An atom is written between single quotes, with `\\`, `\'`, and the
622
- characters that need it escaped as `\n`, `\t`, `\r`, `\b`, `\f`, `\v`,
623
- `\0`, `\xHH` or `\uHHHH`; `'[]'` is written `[]`.
624
- - An integer is written in decimal. A float is written as the shortest
625
- decimal that reads back as the same value, with at least one digit after
626
- the point, in exponent form `1e+22` or `1e-05` when the exponent is below
627
- -4 or at least 16: `0.1`, `2.0`, `-0.0`, `1e+22`.
900
+ - a string literal between single or double quotes, with the escapes
901
+ defined below: an atom;
902
+ - a decimal integer literal with optional suffix `n`, or a finite decimal
903
+ float literal containing a point or exponent: a number;
904
+ - a name: the variable of that name, where each `_` is a new anonymous
905
+ variable (Section 4.2) and a name starting with `VAR_` is decoded
906
+ (Section 9.2), with malformed encodings rejected;
907
+ - a call of a plain name: the compound, or the atom when there are no
908
+ arguments; `struct('name', ...)` as in Section 9.3; `and` and `or` with
909
+ more than two arguments as in Section 4.2;
910
+ - an array literal: the list, where only the last item MAY be spread
911
+ (`...Tail`) and then is the tail; `[...T]` is `T`;
912
+ - an object literal `{K: V, ...}` whose keys are names or strings: the list
913
+ of `struct('=', K, V)` terms, in order;
914
+ - a minus sign applied directly to a numeric literal: the negative number;
915
+ - an expression in parentheses: that expression.
916
+
917
+ A trailing comma is allowed in a call, an array and an object. All syntax
918
+ outside these forms MUST be rejected, including operators other than a
919
+ numeric minus, property or subscript access, spread call arguments,
920
+ assignments, declarations, functions and template literals. Numeric literals
921
+ MUST be decimal without separators; integers other than `0` MUST NOT start
922
+ with `0`. Reading canonical text MUST recover the original term.
923
+
924
+ A call's name and opening `(` MUST NOT be separated by a line feed outside
925
+ a comment. The same restriction applies between a numeric minus and its
926
+ literal. Other line feeds inside brackets are layout.
927
+
928
+ Bare names are variables regardless of case: `alice` in a document is a
929
+ variable; use `'alice'` for an atom. A no-argument call such as `alice()`
930
+ also denotes the atom. `2` and `2n` denote integers, while `2.0` and `2e0`
931
+ denote floats. `float(2)` is a compound expression, not a float literal.
932
+ Array syntax denotes list data; only reading it as a goal applies the
933
+ conjunction rules of Section 4.1.
934
+
935
+ String escapes are `\\`, `\'`, `\"`, `\n`, `\r`, `\t`, `\b`, `\f`,
936
+ `\v`, `\0` (not followed by a decimal digit), `\xHH`, `\uHHHH` and
937
+ `\u{H...}` with one to six hexadecimal digits denoting a Unicode code point.
938
+ Other escapes and raw line breaks in strings MUST be rejected. Outside
939
+ strings, layout consists of spaces, tabs, carriage returns, line feeds and
940
+ the byte-order-mark character, plus comments. A line feed outside brackets
941
+ ends the current expression statement.
942
+
943
+ Names use ASCII letters, digits and `_`, beginning with a letter or `_`.
944
+ The following names are reserved, both bare and as call names:
945
+
946
+ ```text
947
+ await break case catch class const continue debugger default delete do else
948
+ enum export extends false finally for function if implements import in
949
+ instanceof interface let new null package private protected public return
950
+ static super switch this throw true try typeof var void while with yield
951
+ undefined NaN Infinity
952
+ ```
953
+
954
+ Object keys may also use these reserved names, since keys denote atom text.
955
+
956
+ ### 9.2 Canonical atoms, numbers, variables and lists
957
+
958
+ - An atom is single-quoted. Backslash and quote are escaped as `\\` and
959
+ `\'`; newline, tab, carriage return, backspace, form feed and vertical tab
960
+ as `\n`, `\t`, `\r`, `\b`, `\f` and `\v`. Other characters in
961
+ U+0000-U+001F or U+007F-U+009F, U+2028, U+2029 and lone UTF-16
962
+ surrogates use `\uHHHH` with four lowercase hexadecimal digits. Other
963
+ characters are written literally. The empty-list atom is written `[]`.
964
+ - An integer is decimal without a suffix, leading zeros or a plus sign.
965
+ A float uses the shortest significant decimal digits that recover its
966
+ binary64 value. For decimal exponents from -4 through 15, use fixed-point
967
+ form with at least one fractional digit, such as `0.1`, `2.0`, `-0.0`.
968
+ Otherwise use `e`, an explicit exponent sign and at least two exponent
969
+ digits, such as `1e+22` or `1e-05`.
628
970
  - A variable is written as its name when the name is an ASCII identifier
629
971
  (letters, digits and `_`, not starting with a digit), not a reserved word
630
972
  of JavaScript, not `_` and does not begin with `VAR_`. Any other name is
631
973
  written `VAR_` followed by the name with every ASCII letter and digit kept,
632
974
  every `_` doubled and every other character `c` replaced by `_hex_` where
633
- `hex` is the lowercase hexadecimal code point of `c`. The variable `X#12`
634
- is thus written `VAR_X_23_12`. A reader decodes such a name back
635
- (Section 9).
975
+ `hex` is the lowercase hexadecimal code point of `c`. The variable name `A-B`
976
+ is thus written `VAR_A_2d_B`. A reader decodes such a name back
977
+ (Section 9.1).
636
978
  - A list is written `[I1, I2, ...]`; an open list ends with `, ...Tail`.
637
979
 
638
- ### 8.2 Compounds
980
+ ### 9.3 Canonical compounds
639
981
 
640
982
  A compound is written `name(A1, A2, ...)` when its name is an ASCII
641
983
  identifier, not a reserved word of JavaScript and not `struct`, and
642
984
  `struct('name', A1, ...)` otherwise. Arguments are separated by `, `.
643
- There are no operators: `add(X, 1)` is written `add(X, 1)`.
644
985
 
645
986
  A chain of conjunctions or disjunctions built from the left,
646
987
  `and(and(A, B), C)`, is written as one call, `and(A, B, C)`. A compound
647
988
  `and/N` or `or/N` with more than two arguments is written with `struct`, as
648
989
  `struct('and', A, B, C)`.
649
990
 
650
- ### 8.3 Variables in written documents
991
+ ### 9.4 Variable scope in output
651
992
 
652
993
  The conclusions a run writes, its proof documents (Section 10) and check
653
- reports (Section 12) do not show the names variables have inside a run. In
994
+ reports (Section 12) use the following variable names. In
654
995
  the conclusions of a run and in a proof document, the variables are named
655
996
  `A`, `B`, ..., `Z`, `A1`, ..., `Z1`, `A2`, ... in the order the document
656
997
  first shows them, across the whole document, the conclusions written first;
657
998
  the clause displays of a proof keep the program's names. A check report
658
- names the variables of each fact anew (Section 12). The bindings an
659
- implementation reports for each answer to a goal SHOULD name its variables as
660
- the answer does.
661
-
662
- ## 9. Reading Documents
663
-
664
- A document is UTF-8 text holding a sequence of JavaScript expression
665
- statements. A statement ends at the end of its line, unless a bracket is
666
- still open, or at a `;`; comments (`// ...` and `/* ... */`), blank lines and
667
- indentation are ignored; each term records the line on which its statement
668
- begins. The documents eyemind writes hold one statement per line. A reader
669
- MUST NOT execute the text. It accepts exactly:
670
-
671
- - a string literal between single or double quotes, with JavaScript's
672
- escapes: the atom; a decimal integer literal, or one with the `BigInt`
673
- suffix `n`, or a finite decimal float literal (one with a point or an
674
- exponent): the number;
675
- - a name: the variable of that name, where each `_` is a new anonymous
676
- variable (Section 5.1) and a name starting with `VAR_` is decoded
677
- (Section 8.1), or rejected when it encodes no name;
678
- - a call of a plain name: the compound, or the atom when there are no
679
- arguments; `struct('name', ...)` as in Section 8.2; `and` and `or` with
680
- more than two arguments as in Section 5.1;
681
- - an array literal: the list, where only the last item MAY be spread
682
- (`...Tail`) and then is the tail; `[...T]` is `T`;
683
- - an object literal `{K: V, ...}` whose keys are names or strings: the list
684
- of compounds `'='(K, V)`, in order;
685
- - a minus sign applied directly to a numeric literal: the negative number;
686
- - an expression in parentheses: that expression.
687
-
688
- A trailing comma is allowed in a call, an array and an object. Anything else
689
- MUST be rejected: an operator, a property access, a subscript, a call of a
690
- call, a spread argument, a comma expression, an assignment, a template
691
- literal, a regular expression, a hexadecimal, octal or binary literal, a
692
- numeric separator, an integer literal with a leading zero, the names `true`,
693
- `false`, `null`, `undefined`, `NaN`, `Infinity` and the other reserved words,
694
- a name containing `$`, an arrow function, a declaration, a raw control
695
- character other than a tab in a string, and a nonbreaking space outside a
696
- string. Reading the canonical text of a term MUST give the term back.
999
+ names the variables of each fact anew (Section 12).
697
1000
 
698
1001
  ## 10. Proof Documents
699
1002
 
700
1003
  ### 10.1 Structure
701
1004
 
702
- A proof document is a document (Section 9) holding, in this order:
1005
+ A proof document is a document (Section 9.1) holding, in this order:
703
1006
 
704
- 1. the output of the run (Section 7.6): its comment line, then its
1007
+ 1. the output of the run (Section 8.6): its comment line, then its
705
1008
  conclusions, one per line;
706
1009
  2. an empty line;
707
1010
  3. when the proof cites any clause, a comment line introducing the clauses,
@@ -719,16 +1022,20 @@ as a claim, whatever its position.
719
1022
 
720
1023
  ### 10.2 Clause displays
721
1024
 
722
- `Display` shows clause `N` as the program states it: `fact(Head)`,
1025
+ `Display` shows clause `N` in normalized statement form: `fact(Head)`,
723
1026
  `implies(Body, Head)`, `implied_by(Head, Body)`, `query(G1, ...)` or
724
1027
  `contradiction(G1, ...)`, where `Body` is the clause's one body goal, or the
725
1028
  array of its body goals when it has several, `Head` likewise the head or the
726
1029
  array of heads, and `G1, ...` are the body goals themselves. Displays are not
727
1030
  authority: a checker MUST compare each with the program it checks against.
728
1031
 
1032
+ Each argument of a multi-argument `fact` has its own `fact(Head)` display.
1033
+ Conjunctive query and contradiction bodies are displayed as separate goal
1034
+ arguments: `query([p(X), q(X)])` has display `query(p(X), q(X))`.
1035
+
729
1036
  For a program with templates, displays show the deterministically lowered
730
- clauses of Section 4.6, including activation heads and premises. The program
731
- supplied to the checker MUST be lowered from the source as Section 4.6
1037
+ clauses of Section 6.2, including activation heads and premises. The program
1038
+ supplied to the checker MUST be lowered from the source as Section 6.2
732
1039
  requires; displays cannot authorize extra generated rules. Each use of a
733
1040
  generated clause requires its activation as the first use, with a justified
734
1041
  step of its own. All existing checks apply.
@@ -772,7 +1079,7 @@ detail and, where there is one, the term concerned.
772
1079
 
773
1080
  ### 11.1 Reading the document
774
1081
 
775
- The document MUST read (Section 9); otherwise C3 fails and the document has
1082
+ The document MUST read (Section 9.1); otherwise C3 fails and the document has
776
1083
  no claims and no steps. Each `clause(N, Display)` MUST name a clause of the
777
1084
  program whose display (Section 10.2) is identical to `Display`; otherwise C1
778
1085
  fails. Each `step` MUST have bindings that read as a list of `'='/2` pairs,
@@ -793,7 +1100,7 @@ source clause `same(X, X)` cannot justify `same('a', 'b')`.
793
1100
 
794
1101
  For a `source(N)` step, `N` MUST identify an eligible source rule of Section
795
1102
  4.7. Bindings and uses MUST both be empty. The rule's inspection term,
796
- freshened with one variable map, MUST unify with `Goal` and resolve exactly
1103
+ renamed apart, MUST unify with `Goal` and resolve exactly
797
1104
  to it without instantiating the step's own terms. This checks variable
798
1105
  sharing as well as the rule's direction and structure. The source rule is
799
1106
  read as data; its body is not derived by the checker. These steps count as
@@ -858,12 +1165,12 @@ conjuncts of uses.
858
1165
 
859
1166
  A forward rule's head MAY contain variables its body does not contain; each
860
1167
  says that something exists, and a reasoner concludes it with a Skolem term
861
- (Section 7.2). C1 alone would accept any value for such a variable, since any
1168
+ (Section 8.2). C1 alone would accept any value for such a variable, since any
862
1169
  value gives an instance of the rule, so for a `clause(N)` step citing a
863
1170
  forward rule, under the substitution of C1, each such variable `V` MUST be
864
1171
  bound to `skolem(N, Name, Args)`, where:
865
1172
 
866
- - `Name` is the name of `V` as the program writes it (Section 7.2);
1173
+ - `Name` is the name of `V` as the program writes it (Section 8.2);
867
1174
  - `Args` is the same for every such variable of the step, and is the list of
868
1175
  the values of the heads' variables, in order of their first occurrence in
869
1176
  the heads, that are ground and contain no Skolem term `skolem(N, _, Args)`:
@@ -871,12 +1178,12 @@ bound to `skolem(N, Name, Args)`, where:
871
1178
 
872
1179
  When a forward clause has any such variables, its full head under the step's
873
1180
  substitution MUST be ground. A generic inspection pattern cannot share one
874
- existential witness across all its instances (Section 4.7).
1181
+ existential witness across all its instances (Section 6.3).
875
1182
 
876
- For an appended forward clause of Section 4.6, prepend the capture list,
1183
+ For an appended forward clause of Section 6.2, prepend the capture list,
877
1184
  instantiated under the step's substitution, as one element of `Args`, as
878
- required by Section 7.2. The checker MUST compute this from the source
879
- template's capture metadata and the substitution, not from the witness term.
1185
+ required by Section 8.2. The checker MUST compute this from the source
1186
+ template's capture list and the substitution, not from the witness term.
880
1187
 
881
1188
  A variable of the head that also occurs in the body is not checked by C8,
882
1189
  even when the body leaves it unbound; its value comes from the uses, which
@@ -905,7 +1212,7 @@ steps **trusted**.
905
1212
  A proof is **valid** when no condition failed. A valid proof with trusted
906
1213
  boundaries is valid *conditional on* them.
907
1214
 
908
- ### 11.11 What a valid proof establishes
1215
+ ### 11.11 Scope of a valid proof
909
1216
 
910
1217
  A valid proof establishes that each of its claims follows from the program
911
1218
  by the recorded steps, given its trusted boundaries. It does not establish
@@ -915,7 +1222,7 @@ leave conclusions out, and a run's own proof holds exactly its conclusions.
915
1222
 
916
1223
  ## 12. Check Reports
917
1224
 
918
- A check report is a document (Section 9) beginning with the proof's claims,
1225
+ A check report is a document (Section 9.1) beginning with the proof's claims,
919
1226
  in proof order, in canonical text, one per line, followed by a blank line and
920
1227
  the following report facts, one per line:
921
1228
 
@@ -946,26 +1253,16 @@ order; then for each step, in document order, C4 for its uses and the C1, C3,
946
1253
  C5 or C8 failure of its justification; C6 for each boundary, in step order;
947
1254
  C7 for each claim, then for each step; and C2.
948
1255
 
949
- `Detail` is a short human-readable text that names what failed, often with
950
- the canonical text of a term; it is informative, and implementations MAY word
951
- it differently. eyemind's details are, by condition:
952
-
953
- | Condition | Details |
954
- | --- | --- |
955
- | C1 | `clause display differs from source`, `unknown clause ...`, `not an instance of source clause N: ...`, `not an instance of inspectable source rule N: ...` |
956
- | C2 | `cyclic derivation at ...` |
957
- | C3 | the reader's error, `step bindings must be an object and uses an array`, `duplicate justification for ...`, `invalid builtin justification`, `trusted boundaries cannot have bindings or uses`, `unknown justification ...` |
958
- | C4 | `unjustified claim ...`, `unjustified use ...` |
959
- | C5 | `primitive disagrees: ...`, `control step does not follow from its uses: ...`, `trusted boundary forbidden: absent` or `collected` |
960
- | C6 | `absence contradicted by evidence: ...`, `collected result is not a proper list: ...`, `collection misses ...: ...` |
961
- | C7 | `claim answers no goal: ...`, `step serves no claim: ...` |
962
- | C8 | `not the witness of this firing of clause N: ...` |
1256
+ `Detail` is informative text identifying what failed; its wording is not
1257
+ specified. It MUST NOT affect validity, counts or the condition reported.
963
1258
 
964
1259
  The initial answers keep the variable names of the proof. The variables of
965
1260
  each subsequent report fact are renamed `A`, `B`, ..., `Z`, `A1`, ... in order
966
- of first occurrence. A report is ordinary data: `facts_from` (Section 4.2)
1261
+ of first occurrence. A report is ordinary data: `facts_from` (Section 3.4)
967
1262
  states it as facts.
968
1263
 
1264
+ ### 12.1 JSON form
1265
+
969
1266
  The JSON form includes `answers`, an array of the initial claims' canonical
970
1267
  texts, including unverified claims when `valid` is false. It also has `valid` (boolean), `steps`,
971
1268
  `claims`, `verified`, `redecided` (the count `recomputed`), `composed`,
@@ -974,29 +1271,9 @@ texts, including unverified claims when `valid` is false. It also has `valid` (b
974
1271
  `{condition, detail, conclusion?}`) and `conditions` (a list of
975
1272
  `{id, name, covered, failed}`), where `conclusion` is a canonical text.
976
1273
 
977
- ## 13. Unused Clauses
1274
+ ## 13. Command-Line Interface
978
1275
 
979
- A clause is **unused** when no conclusion's recorded derivation cites it,
980
- unless a negation or collection in the proof could consult it and running the
981
- program without it changes the conclusions or the halt code, or fails. The clauses a
982
- negation or collection could consult are those whose heads have the name and
983
- arity of a goal it reaches through the program's bodies. Running the program
984
- without a clause leaves every other clause its number (Section 4.2), so the
985
- Skolem terms of the other rules (Section 7.2) do not change.
986
-
987
- Unused clauses are reported one per line, in clause order, as
988
- `unused(line(L), Display)`, where `L` is the clause's line (Section 4.2) and
989
- `Display` as in Section 10.2.
990
-
991
- "Unused" is relative to the recorded derivations, which are the first ones
992
- found (Section 7.7). A clause that only offers a second derivation of a
993
- conclusion, such as a duplicate rule, is unused, though leaving out the
994
- clause that offers the first one would make it used; leaving out several
995
- unused clauses together can therefore change the conclusions. A
996
- `contradiction` rule that never fires changes no conclusion and is unused,
997
- though it guards the program against data that would make it fire.
998
-
999
- ## 14. Command Line
1276
+ ### 13.1 Invocation and options
1000
1277
 
1001
1278
  ```text
1002
1279
  eyemind [OPTION ...] [FILE ...]
@@ -1009,11 +1286,11 @@ eyemind [OPTION ...] [FILE ...]
1009
1286
  | `-c`, `--prove-and-check` | Generate a proof, check the rendered proof against the input program, and print its answers and check report. |
1010
1287
  | `--check-proof FILE` | Check the proof in `FILE` (`-` for standard input) against the program and print its answers and report. |
1011
1288
  | `--json` | With either checking mode, print the report, including `answers`, as JSON. |
1012
- | `--goal GOAL` | Ask `GOAL`, read as in Section 9, where an array is a conjunction; MAY be repeated. With `--check-proof`, the goals the proof answers. |
1289
+ | `--goal GOAL` | Ask `GOAL`, read as in Section 9.1, where an array is a conjunction; MAY be repeated. With `--check-proof`, the goals the proof answers. |
1013
1290
  | `--strict-proof` | With either checking mode, forbid trusted boundaries. |
1014
- | `--unused` | Print the unused clauses (Section 13). |
1291
+ | `--unused` | Print the unused clauses (Section 13.2). |
1015
1292
  | `--stats` | Print reasoning statistics as JSON to standard error: `inferences`, the goals started, which `--max-inferences` bounds; `rounds`, the forward rounds run over all strata; and `derived`, the facts forward rules added, not counting a conclusion the program states as a fact, a query's answers or `'false'`. |
1016
- | `--max-depth N`, `--max-iterations N`, `--max-inferences N` | The bounds of Section 7.3; `N` MUST be a positive safe integer, at most 9007199254740991. |
1293
+ | `--max-depth N`, `--max-iterations N`, `--max-inferences N` | The bounds of Section 8.3; `N` MUST be a positive safe integer, at most 9007199254740991. |
1017
1294
  | `-v`, `--version` | Print the version. |
1018
1295
  | `-h`, `--help` | Print the usage, including every option and its short alias where one exists. |
1019
1296
 
@@ -1030,242 +1307,94 @@ a program, the command line MUST say how to check it instead.
1030
1307
  | 0 | Success, including a check that found the proof valid. |
1031
1308
  | 1 | An error, printed to standard error as `eyemind: message`. |
1032
1309
  | 2 | A check that found the proof not valid; the report is printed as usual. |
1033
- | 65 | The run halted (Section 7.5). |
1034
-
1035
- ## 15. Security Considerations
1036
-
1037
- A **program** is JavaScript code and runs with the privileges of whoever runs
1038
- it; only programs from trusted sources should be run. Reasoning itself calls
1039
- no code of the program: once stated, clauses are terms.
1040
-
1041
- A **document** (conclusions, proofs, reports, `facts_from` input and goals)
1042
- is untrusted data. It MUST NOT be executed. The reader of Section 9 accepts
1043
- literals, names, calls of a plain name and array and object literals, so no
1044
- document can run code, import modules or reach properties. Checking a proof
1045
- from a third party is therefore safe in the sense that it runs none of the
1046
- third party's code.
1047
-
1048
- Reasoning and checking consume time and memory. The bounds of Section 7.3,
1049
- the limit on powers and shifts in Section 6 and the limit on `functor`
1050
- arities in Section 5.2 bound some of this; a deployment that checks untrusted
1051
- proofs SHOULD additionally bound document size, nesting depth and running
1052
- time.
1053
-
1054
- A valid proof establishes that its claims follow from the program supplied
1055
- to the checker (Section 11.11). It does not establish that the program is
1056
- correct or that the claims are all its conclusions, and a proof with
1057
- obligations holds only conditional on them.
1058
-
1059
- ## 16. Conformance
1060
-
1061
- A conforming **reasoner** implements Sections 3 to 10 with the semantics of
1062
- Section 17, produces conclusions and proof documents in the canonical text,
1063
- and checks every proof
1064
- it produces as Section 11 describes. A conforming **checker** implements
1065
- Sections 9, 11 and 12 and does not depend on a reasoner. For the same
1066
- program, a conforming reasoner and checker MUST produce the same
1067
- conclusions, proof documents and reports as eyemind 0.1.35, byte for byte,
1068
- except for comments and the `Detail` texts of failures (Section 12), the internal names of
1069
- variables where Section 3 says so, and where the host's floating-point
1070
- library functions (`exp`, `log`, the trigonometric and hyperbolic functions,
1071
- `pow` of floats) differ in the last digit.
1072
-
1073
- The conformance suite in the repository's `conformance/` directory tests an
1074
- implementation against this document through its command line, case by case,
1075
- each case naming the sections it tests; `conformance/README.md` describes how
1076
- to run it against any implementation. The repository's examples, with their
1077
- saved conclusions (`examples/output/`), proofs (`examples/proof/`) and reports
1078
- (`examples/check/`), test the same on larger programs.
1079
-
1080
- ## 17. Semantics
1081
-
1082
- This section gives the model-theoretic reading of ordinary relations and its
1083
- limits. Section 7 defines the evaluation and output of every accepted program,
1084
- including controls and primitives whose behavior depends on current bindings.
1085
-
1086
- ### 17.1 Herbrand interpretation
1087
-
1088
- Ordinary predicates have a **Herbrand interpretation**: they relate terms,
1089
- and ground terms denote themselves. The **Herbrand universe** is the set of
1090
- finite ground terms built from the atoms, integers, finite floats and compound
1091
- constructors of Section 3, including lists and the Skolem terms of Section 7.2.
1092
- It includes values constructed during reasoning, even when they do not occur
1093
- literally in the source. For example, `implies(is(X, add(1, 2)), p(X))`
1094
- concludes `p(3)`.
1095
-
1096
- The **Herbrand base** is the set of ground ordinary predicate applications
1097
- over this universe, including atoms used as predicates of arity 0. A Herbrand
1098
- interpretation is a subset of this base. Controls, primitives and source rule
1099
- inspection have the interpretations of Sections 4.7, 5 and 6; their meaning
1100
- is not supplied by ordinary clauses.
1101
-
1102
- Asserting `equal('a', 'b')` adds a relation between two atoms; it does not make
1103
- them the same term. `unify` performs the finite-tree matching of Section 3,
1104
- and `is` evaluates an arithmetic expression. An ordinary argument such as
1105
- `add(1, 2)` remains a compound until an arithmetic primitive evaluates it.
1106
- Integers and floats remain distinct. Section 3's signed-zero convention also
1107
- applies: `0.0` and `-0.0` unify, although canonical identity distinguishes
1108
- them. Thus matching a ground goal against an interpretation uses unification,
1109
- while storage and output use the identity rules of Section 7.
1110
-
1111
- ### 17.2 Variables and witnesses
1112
-
1113
- Variables used only inside a collection's template and goal are local to
1114
- that search (Section 17.4); template variables have the scope of Section 4.6.
1115
- Other variables of a source fact or a backward clause are universally
1116
- quantified within that clause. For example, `fact(p(X))` states every ground
1117
- instance of `p(X)`; a backward clause with a head-only variable likewise leaves that
1118
- variable universal. Resolution uses fresh variables for each clause attempt
1119
- and MAY return an answer containing variables. It does not enumerate all
1120
- ground instances of a universal answer.
1121
-
1122
- A forward rule instead introduces a witness for each head variable left
1123
- unbound by a body solution, except for scoped inspection variables
1124
- (Section 4.7). A head-only variable has an existential reading: for each
1125
- successful body instance there exists a value making the heads hold. For
1126
- example, `implies(person(X), has_token(X, T))` supplies a witness for `T`.
1127
- Section 7.2 chooses the deterministic Skolem term for it. Witnesses depend
1128
- on the rule number and the resolved head context, including captures for an
1129
- appended template clause; body variables absent from that context do not
1130
- distinguish witnesses. Shared variables in several heads share one witness.
1131
-
1132
- This is a specified Skolemized interpretation of existential conclusions.
1133
- It does not claim that the original existential rule has a least model over
1134
- its original vocabulary, or that its witnesses denote different real-world
1135
- objects. A witness is an ordinary compound term in subsequent reasoning.
1136
- Inline templates first become the fixed clauses and activation predicates
1137
- of Section 4.6. Source inspection reads its fixed catalogue and can supply
1138
- universal patterns; it does not assert the inspected rule's head.
1139
-
1140
- ### 17.3 Positive least model
1141
-
1142
- Consider the positive relational fragment: ground facts and rules whose
1143
- bodies contain ordinary calls and conjunction or disjunction, with every
1144
- head variable bound by the body. There is no negation, collection, `once`,
1145
- source inspection or test of an unbound variable's current state. Primitives
1146
- MAY be included when earlier goals supply their required inputs and their
1147
- solutions agree with their ground interpretation under further substitution.
1148
-
1149
- For this fragment, a ground instance of a rule's body holding requires its
1150
- head, or every head of a conjunction, to hold. The meaning is the **least
1151
- Herbrand model**: the smallest interpretation containing the source facts
1152
- and closed under the rules, with matching as in Section 17.1 and primitives
1153
- interpreted as specified. Equivalently, start with the facts and repeatedly
1154
- add the heads of satisfied rule instances until no new ground atom follows;
1155
- the closure can be infinite. Existential forward rules extend this reading
1156
- with the specified Skolem witnesses rather than arbitrary witness choices.
1157
-
1158
- Forward and backward clauses express implication in this fragment. Their
1159
- directions determine how consequences are obtained: forward rules store
1160
- derived facts, while backward rules are searched on demand. A completed
1161
- search for an ordinary goal returns its instances that hold in the model.
1162
- The model includes source facts and consequences available only by backward
1163
- search; it is not just the list of materialized facts or printed conclusions
1164
- (Section 7.6).
1165
-
1166
- For example, `fact(human('socrates'))` and
1167
- `implies(human(X), mortal(X))` give a model containing
1168
- `human('socrates')` and `mortal('socrates')`. With no query or explicit goal,
1169
- only the newly derived `mortal('socrates')` is printed.
1170
-
1171
- ### 17.4 Negation and collection
1172
-
1173
- Negation and collection use the completed dependencies required by the clause
1174
- ranks of Section 4.5. The strata are interpreted in increasing order, with
1175
- lower strata fixed before a higher stratum uses their absence or solutions.
1176
- Dependencies compare whole terms, so a stratum need not contain every clause
1177
- with the same predicate name and arity.
1178
-
1179
- `not(G)` succeeds when searching `G` has no solution. Named variables must
1180
- already be bound; anonymous variables stand for any value. Thus
1181
- `not(p('a', _))` requires that no `p('a', T)` succeeds for any `T`.
1182
- This is absence relative to the program's completed dependencies, not a
1183
- claim that the relation is false in the world. For goals in the relational
1184
- fragment, this gives the stratified least-model reading; a goal containing
1185
- binding-sensitive controls or tests retains their operational meaning.
1186
-
1187
- `findall(T, G, L)` collects the search solutions of `G`, in order, including
1188
- repeated derivations, and copies each instance of `T` with fresh variables.
1189
- Bindings made inside the search do not escape except through the resulting
1190
- list. An empty search gives `[]`. This ordered collection of solutions is
1191
- not determined by a set of ground atoms alone: duplicate source clauses,
1192
- alternative derivations and clause order can affect its result even when
1193
- they leave that set unchanged.
1194
-
1195
- ### 17.5 Sets, solutions and operational behavior
1196
-
1197
- Ground forward conclusions are stored once by canonical identity, including
1198
- comparison with ground source facts. Scoped inspection patterns are stored
1199
- once up to variable renaming. Reported goal answers are also suppressed up
1200
- to variable renaming; query-rule reports follow Section 7.2. These rules do
1201
- not remove alternative derivations during backward search, so a `findall`
1202
- can contain the same term more than once. Nonground answers and inspection
1203
- patterns represent universally scoped terms, not existential witnesses.
1204
-
1205
- The unrestricted least-model reading does not specify every accepted
1206
- program's answers. `once` selects the first solution. `is_var`, `identical`,
1207
- `not_unify` and other tests can observe current bindings, and primitives can
1208
- require inputs that a ground rule instance alone would supply. For example:
1310
+ | 65 | The run halted (Section 8.5). |
1209
1311
 
1210
- ```js
1211
- fact(q('b'))
1212
- implied_by(p(X), [not_unify(X, 'a'), q(X)])
1213
- ```
1312
+ ### 13.2 Unused clauses
1214
1313
 
1215
- An explicit goal `p(X)` has no answer: the initial unbound `X` unifies with
1216
- `'a'`, so `not_unify` fails. The goal `p('b')` succeeds. A forward rule that
1217
- calls such a backward rule can inherit this dependence on call bindings.
1218
- Section 7's goal order and search strategy therefore remain part of the
1219
- meaning of these programs. Output order, first proofs and witness spellings
1220
- can also depend on clause order even in programs whose relational answer
1221
- sets agree.
1222
-
1223
- ### 17.6 Termination and proofs
1224
-
1225
- A least model need not be finite. Arithmetic, term construction and repeated
1226
- witness introduction can generate infinitely many facts. A finite model
1227
- does not ensure that depth-first backward search terminates: for example,
1228
- `implied_by(p(X), p(X))` has an empty least model but searching `p('a')`
1229
- keeps recurring. Backward search is not tabled. Successful completion without
1230
- a contradiction requires terminating searches and forward rounds that reach
1231
- a fixed point within Section 7.3's bounds. Exceeding a bound raises an error
1232
- rather than certifying completion.
1233
- A contradiction halts immediately as Section 7.5 specifies, so its output
1234
- does not claim a completed closure, and it does not entail arbitrary terms.
1235
-
1236
- A valid proof certifies its recorded claims subject to any trusted absence
1237
- or collection boundaries (Section 11.11). It does not certify that the
1238
- entire least model was computed, that all answers were returned, or that no
1239
- contradiction follows.
1314
+ A clause is **unused** when no conclusion's recorded derivation cites it,
1315
+ unless a negation or collection in the proof could consult it and its
1316
+ omission changes the conclusions or halt code, or causes an error. The clauses a
1317
+ negation or collection could consult are those whose heads have the name and
1318
+ arity of a goal it reaches through the program's bodies. Running the program
1319
+ without a clause leaves every other clause its number (Section 3.4), so the
1320
+ Skolem terms of the other rules (Section 8.2) do not change.
1240
1321
 
1241
- ---
1322
+ Unused clauses are reported one per line, in clause order, as
1323
+ `unused(line(L), Display)`, where `L` is the clause's line (Section 3.4) and
1324
+ `Display` as in Section 10.2.
1325
+
1326
+ "Unused" is relative to the recorded derivations, which are the first ones
1327
+ found (Section 8.7). A clause that only offers a second derivation of a
1328
+ conclusion, such as a duplicate rule, is unused, though leaving out the
1329
+ clause that offers the first one would make it used; leaving out several
1330
+ unused clauses together can therefore change the conclusions. A
1331
+ `contradiction` rule that never fires changes no conclusion and is unused,
1332
+ though it guards the program against data that would make it fire.
1333
+
1334
+ ## 14. Conformance
1335
+
1336
+ A conforming reasoner MUST implement the program syntax, semantics and
1337
+ evaluation of Sections 2-8 and the document and proof formats of Sections
1338
+ 9-12. It MUST check every proof it generates before returning it. A
1339
+ conforming checker MUST implement Sections 9-12 against the supplied
1340
+ program, including the clause and template rules of Sections 3 and 6,
1341
+ without invoking a reasoner to complete the certificate. The command-line
1342
+ interface of Section 13 is a separate conformance requirement.
1343
+
1344
+ Canonical term spelling, conclusion order, proof contents and report counts
1345
+ are required as specified. Comment wording and failure `Detail` text are
1346
+ informative. Fresh variable names are unspecified where Section 2.4 says
1347
+ so. Float results of `exp`, logarithms, trigonometric and hyperbolic
1348
+ functions, and `pow` with floats MAY differ in the last decimal digit.
1349
+
1350
+ The conformance cases and saved example documents exercise these
1351
+ requirements. They do not replace the definitions in this specification.
1352
+
1353
+ ## 15. Security
1354
+
1355
+ Programs execute JavaScript and require the caller's trust. Documents,
1356
+ including proofs, reports, goals and `facts_from` input, MUST be read as data
1357
+ without executing code. A deployment accepting untrusted documents SHOULD
1358
+ bound their size, nesting depth, processing time and memory, in addition to
1359
+ the reasoning bounds of Section 8.3. A valid proof establishes only the
1360
+ claims and assumptions described in Section 11.11.
1242
1361
 
1243
1362
  ## Appendix A. Document Grammar
1244
1363
 
1245
- The documents of Sections 9 to 12 use this subset of JavaScript's expression
1246
- grammar, in the ABNF style of RFC 5234, with spaces, tabs and comments
1247
- between tokens allowed, and line breaks too inside brackets.
1248
-
1249
- ```abnf
1250
- document = *( line LF ) [ line ]
1251
- line = [ expression *( ";" expression ) [ ";" ] ]
1252
- expression = string / number / "-" number / name / call / array / object
1253
- / "(" expression ")"
1254
- call = name "(" [ expression *( "," expression ) [ "," ] ] ")"
1255
- array = "[" [ items ] "]"
1256
- items = expression *( "," expression ) [ "," "..." expression ] [ "," ]
1257
- / "..." expression [ "," ]
1258
- object = "{" [ pair *( "," pair ) [ "," ] ] "}"
1259
- pair = ( name / string ) ":" expression
1260
- string = "'" *<character or escape> "'" / DQUOTE *<character or escape> DQUOTE
1261
- number = 1*DIGIT [ "n" ] / float
1262
- float = ( 1*DIGIT "." *DIGIT / "." 1*DIGIT ) [ exponent ] / 1*DIGIT exponent
1263
- exponent = ( "e" / "E" ) [ "+" / "-" ] 1*DIGIT
1264
- name = ( ALPHA / "_" ) *( ALPHA / DIGIT / "_" ) ; not a reserved word
1364
+ This grammar defines document expressions. Quoted strings are literal
1365
+ tokens; `|` gives alternatives, `[ ... ]` an optional part, `{ ... }`
1366
+ repetition, parentheses grouping, and `? ... ?` a lexical class defined in
1367
+ prose. String literals, reserved names and
1368
+ layout follow Section 9.1. Line feeds inside brackets are layout; outside
1369
+ brackets they separate statements.
1370
+
1371
+ ```ebnf
1372
+ document = { separator | expression separator }, [ expression ] ;
1373
+ separator = ";" | LF ;
1374
+ expression = string | number | "-", number | name | call | array | object
1375
+ | "(", expression, ")" ;
1376
+ call = name, "(", [ arguments ], ")" ;
1377
+ arguments = expression, { ",", expression }, [ "," ] ;
1378
+ array = "[", [ items ], "]" ;
1379
+ items = expression, { ",", expression }, [ ",", "...", expression ], [ "," ]
1380
+ | "...", expression, [ "," ] ;
1381
+ object = "{", [ pair, { ",", pair }, [ "," ] ], "}" ;
1382
+ pair = ( identifier | string ), ":", expression ;
1383
+ number = integer, [ "n" ] | float ;
1384
+ integer = "0" | nonzero, { digit } ;
1385
+ float = ( digits, ".", { digit } | ".", digits ), [ exponent ]
1386
+ | digits, exponent ;
1387
+ exponent = ( "e" | "E" ), [ "+" | "-" ], digits ;
1388
+ digits = digit, { digit } ;
1389
+ digit = "0" | nonzero ;
1390
+ nonzero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
1391
+ identifier = ( letter | "_" ), { letter | digit | "_" } ;
1392
+ letter = ? ASCII letter A-Z or a-z ? ;
1393
+ name = ? identifier excluding the reserved names of Section 9.1 ? ;
1394
+ string = ? quoted string literal as defined in Section 9.1 ? ;
1395
+ LF = ? U+000A line feed ? ;
1265
1396
  ```
1266
1397
 
1267
- An integer literal other than `0` MUST NOT begin with `0`.
1268
-
1269
1398
  ## Appendix B. Example
1270
1399
 
1271
1400
  The program `socrates.js`: