tur/logic
mzero
(mzero :int)
-- Backtracking monad (inlined) ─────────────────────────────────────────────
0 (null pointer, empty solution list).
mreturn
(mreturn [x] :int)
wrap a single substitution as a successful result.
| x | substitution pointer (:int) |
A singleton solution list (:int).
mplus
(mplus [xs ys] :int)
concatenate two solution lists.
| xs | first solution list (:int) | |
| ys | second solution list (:int) |
A new list with all solutions from xs followed by those from ys (:int).
mbind
(mbind [ma fn] :int)
apply a fat-closure continuation to each solution and concatenate.
| ma | solution list (:int) | |
| fn | fat closure of type (UState -> list UState) |
Concatenated solutions (:int).
bt-length
(bt-length [xs] :int)
count the number of solutions in a result list.
| xs | solution list (:int) |
Number of solutions (:int).
term-int
(term-int [n] :int)
-- Term constructors ────────────────────────────────────────────────────────
| n | integer value |
Pointer to a term with tag=0, data1=n (:int). (term-int 42) ; => tagged term pointer for integer 42
term-var
(term-var [id] :int)
construct a logic variable term with the given id.
| id | unique variable identifier (:int) |
Pointer to a term with tag=1, data1=id (:int). (term-var (lvar-next)) ; => fresh logic variable
term-pair
(term-pair [a b] :int)
construct a logic pair term from two sub-terms.
| a | first sub-term pointer (:int) | |
| b | second sub-term pointer (:int) |
Pointer to a term with tag=2, data1=a, data2=b (:int). (term-pair (term-int 1) (term-int 2)) ; => pair term (1 . 2)
term-nil
(term-nil :int)
construct the nil/empty logic term.
Pointer to a term with tag=3 (:int). (term-nil) ; => nil term
term-tag
(term-tag [t] :int)
-- Term accessors ───────────────────────────────────────────────────────────
| t | term pointer (:int) |
0=INT, 1=VAR, 2=PAIR, 3=NIL (:int).
term-int-val
(term-int-val [t] :int)
read the integer value from an INT term.
| t | term pointer with tag=0 (:int) |
The integer value stored in data1 (:int).
term-var-id
(term-var-id [t] :int)
read the variable id from a VAR term.
| t | term pointer with tag=1 (:int) |
The variable id stored in data1 (:int).
term-pair-fst
(term-pair-fst [t] :int)
read the first sub-term pointer from a PAIR term.
| t | term pointer with tag=2 (:int) |
data1 (first sub-term pointer) (:int).
term-pair-snd
(term-pair-snd [t] :int)
read the second sub-term pointer from a PAIR term.
| t | term pointer with tag=2 (:int) |
data2 (second sub-term pointer) (:int).
lvar-next
(lvar-next :int)
-- Fresh variable counter ───────────────────────────────────────────────────
A fresh monotonically increasing integer id (:int). (term-var (lvar-next)) ; => a unique logic variable
subs-empty
(subs-empty :int)
-- Substitution operations ──────────────────────────────────────────────────
0 (null pointer representing an empty alist) (:int).
logic-walk
(logic-walk [t subs] :int)
follow variable bindings in a substitution until ground.
| t | term pointer to walk (:int) | |
| subs | substitution alist pointer (:int) |
The fully walked term pointer (ground or unbound variable) (:int). (logic-walk (term-var 0) subs) ; => bound term or the variable itself
logic-unify
(logic-unify [t1 t2 subs] :int)
structurally unify two terms, extending the substitution.
| t1 | first term pointer (:int) | |
| t2 | second term pointer (:int) | |
| subs | current substitution alist (:int) |
Extended substitution on success, or -1 on unification failure (:int). (logic-unify (term-var 0) (term-int 5) (subs-empty)) ; => subs with x0=5
apply-fat
(apply-fat [f arg] :int)
-- Fat-closure application ──────────────────────────────────────────────────
| f | fat closure pointer (:int) | |
| arg | argument to pass (:int) |
Return value of the closure (:int).
apply-goal
(apply-goal [g state] :int)
call a goal fat closure with a substitution (UState).
| g | goal fat closure pointer (:int) | |
| state | current substitution (:int) |
Solution list (list of substitutions) (:int).
unify-goal-impl
(unify-goal-impl [lt1 lt2 state] :int)
-- Goal constructors ────────────────────────────────────────────────────────
lequal
(lequal [t1 t2] :ptr<void>)
goal that unifies two terms (miniKanren ==).
| t1 | first term pointer (:int) | |
| t2 | second term pointer (:int) |
A goal (:ptr<void>) that succeeds iff t1 and t2 unify. (run-logic 1 (lequal (term-int 5) (term-int 5))) ; => one solution
succeed-impl
(succeed-impl [dummy state] :int)
implementation helper for the succeed goal.
succeed
(succeed :ptr<void>)
goal that always succeeds without changing the substitution.
A goal (:ptr<void>) that adds the current state unchanged to the solutions. (run-logic 1 (succeed)) ; => one solution (empty substitution)
fail-impl
(fail-impl [dummy state] :int)
implementation helper for the fail goal.
fail
(fail :ptr<void>)
goal that always fails, producing no solutions.
A goal (:ptr<void>) that produces an empty solution list. (run-logic 1 (fail)) ; => empty list
conjoined-inner
(conjoined-inner [lg22 s] :int)
helper to apply the second goal in a conjunction.
conjoined-impl
(conjoined-impl [lg1 lg2 state] :int)
implementation helper for conjunction.
conjoined
(conjoined [g1 g2] :ptr<void>)
goal that applies g1 then g2 to each result (conjunction).
| g1 | first goal (:ptr<void>) | |
| g2 | second goal (:ptr<void>) |
A goal that succeeds only when both g1 and g2 succeed (:ptr<void>). (run-logic 1 (conjoined (lequal x (term-int 1)) (succeed))) ; => [x=1]
disjoined-impl
(disjoined-impl [lg1 lg2 state] :int)
implementation helper for disjunction.
disjoined
(disjoined [g1 g2] :ptr<void>)
goal that combines results from g1 and g2 (disjunction).
| g1 | first goal (:ptr<void>) | |
| g2 | second goal (:ptr<void>) |
A goal whose solutions are the interleaved results of g1 and g2 (:ptr<void>). (run-logic 2 (disjoined (lequal x (term-int 1)) (lequal x (term-int 2)))) ; => [x=1, x=2]
fresh-impl
(fresh-impl [lf state] :int)
implementation helper for fresh variable introduction.
fresh
(fresh [f] :ptr<void>)
create a new logic variable and pass it to a goal-building function.
| f | fat closure of type (term -> goal) |
A goal (:ptr<void>) that introduces a fresh variable and runs (f var). (run-logic 1 (fresh (fn [x] (lequal x (term-int 7))))) ; => [x=7]
take-n
(take-n [n lst] :int)
-- Runner ───────────────────────────────────────────────────────────────────
| n | maximum number of solutions (:int) | |
| lst | solution list (:int) |
A truncated solution list of length at most n (:int).
run-logic
(run-logic [n g] :int)
run a goal with an empty substitution and return up to n results.
| n | maximum number of solutions (:int) | |
| g | goal to run (:ptr<void>) |
A list of at most n substitutions (solution list) (:int). (run-logic 1 (fresh (fn [x] (lequal x (term-int 3))))) ; => one solution
first-state
(first-state [results] :int)
-- Result helpers ───────────────────────────────────────────────────────────
| results | solution list from run-logic (:int) |
The first substitution pointer, or 0 if the list is empty (:int).
reify-walk
(reify-walk [t results] :int)
walk a term through the first result's substitution.
| t | term pointer to reify (:int) | |
| results | solution list from run-logic (:int) |
The walked term pointer (ground or unbound variable) (:int). (reify-walk my-var (run-logic 1 my-goal)) ; => ground term or variable