3 Second Edition
| (require typed/miniKanren/amb/trs2) | package: ambKanren |
This module implements the language of the second edition of The Reasoned Schemer (Friedman, Byrd, Kiselyov, and Hemann, MIT Press, 2018) on top of amb, without streams.
3.1 Implementation Basis
The interface (run, defrel, fresh, conde, conda, condu, project) and the definitions of walk, unify, ifte, once, and reification follow the official code of the second edition. What changes is the representation of goals:
| second edition |
| typed/miniKanren/amb/trs2 | |
goal |
|
| ||
|
| a choice made by amb | ||
|
| function composition | ||
suspension |
|
| suspend: a choice point sent to the back of the frontier |
The second edition can switch away from a branch that never produces an answer, because defrel suspends every call to a relation and append-inf swaps its two streams at each suspension. Here, defrel calls suspend, which lets the computations already waiting in amb’s frontier run first:
3.1.1 Order of Answers
The two implementations produce the same answers but schedule suspended computations differently. append-inf swaps a suspended stream only with the other side of the disjunction it belongs to, so the search is a tree of binary interleavings in which deeper disjunctions receive exponentially smaller shares. suspend sends the computation to the back of a single, global frontier, which is closer to breadth-first search.
As a result, answers can come in a different order from the book, and the first n answers returned by run can differ even when all answers eventually appear. Of the 285 examples of chapters 1 to 9 of the book, 15 differ in this way: 9 return the same answers in a different order, and 6 return different answers for a bounded run; the book’s answers do appear when more answers are requested. The global frontier also keeps more partial computations alive, so programs that search deeply, such as the arithmetic relations of chapter 8, are noticeably slower than with streams.
3.2 Types
type
type
type
3.3 Running Programs
syntax
(run* q goal ...)
3.4 Goals and Relations
syntax
(fresh (x ...) goal ...)
syntax
(conde [goal ...+] ...)
syntax
(conda [goal ...+] ...+)
syntax
(condu [goal ...+] ...+)
syntax
(project (x ...) goal ...)
syntax
(disj goal ...)
syntax
(conj goal ...)
procedure
g1 : Goal g2 : Goal
procedure
g1 : Goal g2 : Goal
3.5 Substitutions and Unification
value
procedure
v : Term s : Substitution
procedure
v : Term s : Substitution
procedure
x : Var v : Term s : Substitution
procedure
(ext-s x v s) → Substitution
x : Var v : Term s : Substitution
procedure
(unify u v s) → Substitution
u : Term v : Term s : Substitution
procedure
(reify-name n) → Symbol
n : Index
procedure
(reify-s v r) → Substitution
v : Term r : Substitution
procedure
(reify v) → (→ Substitution Term)
v : Term