tur/logic

stdlib/logic.tur
defn

mzero

(mzero :int)

-- Backtracking monad (inlined) ─────────────────────────────────────────────

0 (null pointer, empty solution list).

defn

mreturn

(mreturn [x] :int)

wrap a single substitution as a successful result.

xsubstitution pointer (:int)

A singleton solution list (:int).

defn

mplus

(mplus [xs ys] :int)

concatenate two solution lists.

xsfirst solution list (:int)
yssecond solution list (:int)

A new list with all solutions from xs followed by those from ys (:int).

defn

mbind

(mbind [ma fn] :int)

apply a fat-closure continuation to each solution and concatenate.

masolution list (:int)
fnfat closure of type (UState -> list UState)

Concatenated solutions (:int).

defn

bt-length

(bt-length [xs] :int)

count the number of solutions in a result list.

xssolution list (:int)

Number of solutions (:int).

defn

term-int

(term-int [n] :int)

-- Term constructors ────────────────────────────────────────────────────────

ninteger value
Pointer to a term with tag=0, data1=n (:int).

  (term-int 42)  ; => tagged term pointer for integer 42
defn

term-var

(term-var [id] :int)

construct a logic variable term with the given id.

idunique variable identifier (:int)
Pointer to a term with tag=1, data1=id (:int).

  (term-var (lvar-next))  ; => fresh logic variable
defn

term-pair

(term-pair [a b] :int)

construct a logic pair term from two sub-terms.

afirst sub-term pointer (:int)
bsecond 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)
defn

term-nil

(term-nil :int)

construct the nil/empty logic term.

Pointer to a term with tag=3 (:int).

  (term-nil)  ; => nil term
defn

term-tag

(term-tag [t] :int)

-- Term accessors ───────────────────────────────────────────────────────────

tterm pointer (:int)

0=INT, 1=VAR, 2=PAIR, 3=NIL (:int).

defn

term-int-val

(term-int-val [t] :int)

read the integer value from an INT term.

tterm pointer with tag=0 (:int)

The integer value stored in data1 (:int).

defn

term-var-id

(term-var-id [t] :int)

read the variable id from a VAR term.

tterm pointer with tag=1 (:int)

The variable id stored in data1 (:int).

defn

term-pair-fst

(term-pair-fst [t] :int)

read the first sub-term pointer from a PAIR term.

tterm pointer with tag=2 (:int)

data1 (first sub-term pointer) (:int).

defn

term-pair-snd

(term-pair-snd [t] :int)

read the second sub-term pointer from a PAIR term.

tterm pointer with tag=2 (:int)

data2 (second sub-term pointer) (:int).

defn

lvar-next

(lvar-next :int)

-- Fresh variable counter ───────────────────────────────────────────────────

A fresh monotonically increasing integer id (:int).

  (term-var (lvar-next))  ; => a unique logic variable
defn

subs-empty

(subs-empty :int)

-- Substitution operations ──────────────────────────────────────────────────

0 (null pointer representing an empty alist) (:int).

defn

logic-walk

(logic-walk [t subs] :int)

follow variable bindings in a substitution until ground.

tterm pointer to walk (:int)
subssubstitution 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
defn

logic-unify

(logic-unify [t1 t2 subs] :int)

structurally unify two terms, extending the substitution.

t1first term pointer (:int)
t2second term pointer (:int)
subscurrent 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
defn

apply-fat

(apply-fat [f arg] :int)

-- Fat-closure application ──────────────────────────────────────────────────

ffat closure pointer (:int)
argargument to pass (:int)

Return value of the closure (:int).

defn

apply-goal

(apply-goal [g state] :int)

call a goal fat closure with a substitution (UState).

ggoal fat closure pointer (:int)
statecurrent substitution (:int)

Solution list (list of substitutions) (:int).

defn

unify-goal-impl

(unify-goal-impl [lt1 lt2 state] :int)

-- Goal constructors ────────────────────────────────────────────────────────

defn

lequal

(lequal [t1 t2] :ptr<void>)

goal that unifies two terms (miniKanren ==).

t1first term pointer (:int)
t2second 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
defn

succeed-impl

(succeed-impl [dummy state] :int)

implementation helper for the succeed goal.

defn

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)
defn

fail-impl

(fail-impl [dummy state] :int)

implementation helper for the fail goal.

defn

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
defn

conjoined-inner

(conjoined-inner [lg22 s] :int)

helper to apply the second goal in a conjunction.

defn

conjoined-impl

(conjoined-impl [lg1 lg2 state] :int)

implementation helper for conjunction.

defn

conjoined

(conjoined [g1 g2] :ptr<void>)

goal that applies g1 then g2 to each result (conjunction).

g1first goal (:ptr<void>)
g2second 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]
defn

disjoined-impl

(disjoined-impl [lg1 lg2 state] :int)

implementation helper for disjunction.

defn

disjoined

(disjoined [g1 g2] :ptr<void>)

goal that combines results from g1 and g2 (disjunction).

g1first goal (:ptr<void>)
g2second 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]
defn

fresh-impl

(fresh-impl [lf state] :int)

implementation helper for fresh variable introduction.

defn

fresh

(fresh [f] :ptr<void>)

create a new logic variable and pass it to a goal-building function.

ffat 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]
defn

take-n

(take-n [n lst] :int)

-- Runner ───────────────────────────────────────────────────────────────────

nmaximum number of solutions (:int)
lstsolution list (:int)

A truncated solution list of length at most n (:int).

defn

run-logic

(run-logic [n g] :int)

run a goal with an empty substitution and return up to n results.

nmaximum number of solutions (:int)
ggoal 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
defn

first-state

(first-state [results] :int)

-- Result helpers ───────────────────────────────────────────────────────────

resultssolution list from run-logic (:int)

The first substitution pointer, or 0 if the list is empty (:int).

defn

reify-walk

(reify-walk [t results] :int)

walk a term through the first result's substitution.

tterm pointer to reify (:int)
resultssolution 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