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