No matching definitions.

tur/logic

stdlib/logic.tur

miniKanren-style logic programming (unification, goals, streams).

Since: Phase B1

defdata

Term

(defdata Term :copy (TInt) (TVar) (TPair) (TNil))
defdata

Subst

(defdata Subst :copy (SNil) (SBind))
defdata

UnifyResult

(defdata UnifyResult :copy (UFail) (UOk))
defdata

Lookup

(defdata Lookup :copy (LMissing) (LFound))
defdata

Stream

(defdata Stream :copy (StNil) (StCons) (StInc) (fn))
defn

st-force

(st-force [th : (fn [])

run a delayed stream one step.

defn

st-pull

(st-pull [xs : Stream] :)

force a stream until it is mature (StNil or StCons).

xsa possibly-delayed stream

The same stream forced to StNil or StCons.

Since: lazy-streams

defopaque

Goal

(Goal [A] :ptr<void>))

a kind-(* -> *) handle over a miniKanren goal `Subst -> Stream`;

Since: stdlib-hkt-consolidation T3

defn

st-append

(st-append [xs : Stream ys : Stream] :)

-- Solution stream (list / backtracking monad) ─────────────────────────────

defn

st-append-dfs

(st-append-dfs [xs : Stream ys : Stream] :)

concatenate two solution streams DEPTH-FIRST.

xsfirst solution stream
yssecond solution stream

xs's solutions, then ys's.

(st-length (st-append-dfs (mreturn s) (mreturn s)))  ; => 2

Since: lazy-streams

defn

st-bind

(st-bind [xs : Stream f : (fn [Subst])

concatMap: apply f to each state and concatenate the streams.

defn

st-length

(st-length [xs : Stream] :)

count the states in a solution stream.

defn

st-take

(st-take [n : int xs : Stream] :)

keep at most n states from the front of a solution stream.

defn

mzero

(mzero :)

the empty solution stream (no solutions).

An empty Stream.

defn

mreturn

(mreturn [s : Subst] :)

wrap a single substitution as a one-solution stream.

sthe search state (Subst)

A singleton Stream containing s.

defn

mplus

(mplus [xs : Stream ys : Stream] :)

concatenate (union) two solution streams.

xsfirst solution stream
yssecond solution stream

A Stream with all of xs's solutions followed by all of ys's.

defn

mbind

(mbind [ma : Stream fn : (fn [Subst])

apply a `Subst -> Stream` continuation to each solution and

maa solution stream
fna `Subst -> Stream` callback

The concatenated solution stream.

defn

bt-length

(bt-length [xs : Stream] :)

count the number of solutions in a solution stream.

xssolution stream

Number of solutions.

defn

term-int

(term-int [n : int] :)

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

ninteger value

A TInt term.

(term-int 42)  ; => integer term 42
defn

term-var

(term-var [id : int] :)

construct a logic variable term with the given id.

idunique variable identifier

A TVar term.

(term-var 0)  ; => logic variable 0
defn

term-pair

(term-pair [a : Term b : Term] :)

construct a logic pair term from two sub-terms.

afirst sub-term
bsecond sub-term

A TPair term.

(term-pair (term-int 1) (term-int 2))  ; => pair term (1 . 2)
defn

term-nil

(term-nil :)

construct the nil/empty logic term.

A TNil term.

(term-nil)  ; => nil term
defn

term-int-val

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

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

ta Term

The integer payload of a TInt, or 0 for any other term.

defn

term-var-id

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

read the variable id from a VAR term (0 otherwise).

ta Term

The id of a TVar, or 0 for any other term.

defn

term-pair-fst

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

read the first sub-term of a PAIR term (TNil otherwise).

ta Term

The first component of a TPair, or TNil for any other term.

defn

term-pair-snd

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

read the second sub-term of a PAIR term (TNil otherwise).

ta Term

The second component of a TPair, or TNil for any other term.

defn

subs-empty

(subs-empty :)

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

An empty Subst with next fresh-var id 0.

defn

subst-next

(subst-next [s : Subst] :)

read the next unused fresh-variable id from the base of a

defn

subst-set-next

(subst-set-next [s : Subst n : int] :)

set the fresh-variable counter at the base of a

defn

subst-lookup

(subst-lookup [vid : int subs : Subst] :)

find the term bound to var-id in a substitution.

defn

logic-walk

(logic-walk [t : Term subs : Subst] :)

follow variable bindings in a substitution until ground.

tthe term to walk
substhe substitution

The fully walked term (a ground term or an unbound variable).

(logic-walk (term-var 0) subs)  ; => bound term or the variable itself
defn

unify-walked

(unify-walked [a : Term b : Term subs : Subst] :)

structural unification of two already-walked terms.

defn

logic-unify

(logic-unify [t1 : Term t2 : Term subs : Subst] :)

structurally unify two terms, extending the substitution.

t1first term
t2second term
subscurrent substitution

(UOk subs') on success, or (UFail) on unification failure.

(logic-unify (term-var 0) (term-int 5) (subs-empty))  ; => (UOk {x0=5})
defn

apply-goal

(apply-goal [g : (Goal int) state : Subst] :)

-- Goal application ─────────────────────────────────────────────────────────

ga goal
statethe current search state (Subst)

The solution Stream.

defn

unify-goal-impl

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

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

defn

lequal

(lequal [t1 : Term t2 : Term] :)

goal that unifies two terms (miniKanren ==).

t1first term
t2second term

A goal (Goal int) that succeeds iff t1 and t2 unify.

(run-logic 1 (lequal (term-int 5) (term-int 5)))  ; => one solution
defn

succeed

(succeed :)

goal that always succeeds without changing the substitution.

A goal (Goal int) that adds the current state unchanged to the solutions.

(run-logic 1 (succeed))  ; => one solution
defn

fail

(fail :)

goal that always fails, producing no solutions.

A goal (Goal int) that produces an empty solution stream.

(run-logic 1 (fail))  ; => empty stream
defn

conjoined-impl

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

implementation helper for conjunction.

defn

conjoined-raw

(conjoined-raw [g1 : (Goal int) g2 : (Goal int)] :)

worker behind conjoined / Monad bind sequencing.

defn

conjoined

(conjoined [A B])

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

g1first goal (Goal A)
g2second goal (Goal B)

A goal (Goal B) that succeeds only when both g1 and g2 succeed.

(run-logic 1 (conjoined (lequal x (term-int 1)) (succeed)))  ; => [x=1]

Since: Phase B1

defn

disjoined-impl

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

implementation helper for disjunction.

defn

disjoined-raw

(disjoined-raw [g1 : (Goal int) g2 : (Goal int)] :)

worker behind disjoined / Alternative alt-or.

defn

disjoined

(disjoined [A])

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

g1first goal (Goal A)
g2second goal (Goal A)

A goal (Goal A) whose solutions are the union of g1's and g2's.

(run-logic 2 (disjoined (lequal x (term-int 1)) (lequal x (term-int 2))))
  ; => [x=1, x=2]

Since: Phase B1

defn

fresh-impl

(fresh-impl [^fat lf : (fn [Term])

implementation helper for fresh variable introduction.

defn

fresh

(fresh [^fat f : (fn [Term])

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

fa (Term -> Goal) callback

A goal (Goal int) that introduces a fresh variable and runs (f var).

(run-logic 1 (fresh (fn [x] (lequal x (term-int 7)))))  ; => [x=7]
defmacro

zzz

(zzz [g])

delay a goal so a recursive relation can be written at all.

ga goal EXPRESSION, not evaluated until the stream is pulled

A goal that yields an immature stream.

(run-logic 1 (zzz (nats)))   ; terminates

Since: lazy-streams

defn

disjoined-dfs-impl

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

disjunction that searches DEPTH-FIRST.

g1first goal
g2second goal

A goal yielding g1's solutions then g2's.

(run-logic 1 (disjoined-dfs (lequal x (term-int 1)) (lequal x (term-int 2))))

Since: lazy-streams

defn

disjoined-dfs

(disjoined-dfs [A])
defn

run-logic

(run-logic [A])

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

nmaximum number of solutions
ggoal to run (Goal A)

A Stream of at most n solution states.

(run-logic 1 (fresh (fn [x] (lequal x (term-int 3)))))  ; => one solution
defn

stream-empty?

(stream-empty? [xs : Stream] :)

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

defn

first-state

(first-state [results : Stream] :)

extract the first solution substitution from a run-logic

resultssolution stream from run-logic

The first Subst, or the empty substitution if the stream is empty.

defn

reify-walk

(reify-walk [t : Term results : Stream] :)

walk a term through the first solution's substitution.

tthe term to reify
resultssolution stream from run-logic

The walked term (ground term or unbound variable); t itself if there are no solutions.

(reify-walk my-var (run-logic 1 my-goal))  ; => ground term or variable
defn

bind-goal-raw

(bind-goal-raw [g : (Goal int) k : fn] :)

-- HKT typeclass instances (stdlib-hkt-consolidation T3) ────────────────────

defn

fmap-goal-raw

(fmap-goal-raw [g : (Goal int) f : (fn [Subst])

worker: map a callback over each solution state.

definstance

Functor[Goal]

(definstance Functor [Goal])

map a function over each solution state.

Since: stdlib-hkt-consolidation T3

definstance

Applicative[Goal]

(definstance Applicative [Goal])

pure is the always-succeeding goal (state preserved);

Since: stdlib-hkt-consolidation T3

definstance

Monad[Goal]

(definstance Monad [Goal])

bind is conjunction: run the goal, then feed each resulting

(do-m _ (lequal x (term-int 1)) (lequal y (term-int 2)))

Since: stdlib-hkt-consolidation T3

definstance

Alternative[Goal]

(definstance Alternative [Goal])

empty is the failing goal; alt-or is disjunction (the

(alt-or (lequal x (term-int 1)) (lequal x (term-int 2)))

Since: stdlib-hkt-consolidation T3