# One Shot Prolog

We are going to play with an idea how to implement prolog programs using one shot continuation or simply where we allow a stack-code unit to be attached and detached to the active stack at will.

So the building blocks are that each predicate, $$f$$, is defined as a vector or struct contains the elements

$$f = [UnitsCache,Constr]$$

The idea is that we cache the used stack spaces and reuse them in stead of tearing up and tearing down stacks all the time.

Now getting a unit is done with the 'get-unit' function and the semantics are

(define (get-unit f)
(let ((l (unit-cache-ref f)))
(when (null? l)
(set! l (list ((get-unit-constructor f)))))

(let ((unit (car l)))
;; Add an item on the stack so that at unwinding the constructed
;; unit will be cached
(register unit f)

unit)))


Now to start a unit from the beginning it will use the unit's stack and start the code at the code starting point sending the arguments to the unit e.g.

(start cc-unit arg ...)


For predicates, minimally the arguments are $$p,cc,a \ldots$$, where $$p$$ is the fail unit e.g. we return to it as it located on the chain of stack and is a return point. $$cc$$ is the continuation of the algorithm and is a unit that needs to established.

Now in order to start a unit we have the "start" function and in order to return we have the "return" function e.g.

(return p-unit)


This will return to the start of the unit. Finally we have the "self" command it will make a unit that is using the self stack on both sides. Then the "goto-forward-point" command will initiate the self command so that it will return directly with false and later with a non false value. we use it in a "and" construct as

(let ((cc* (self)))
;; when one calls (start s pp) this will return pp else at init false
(aif pp (goto-forward-point cc*)
;; Second clause
(let ((ug (get-unit g)))
(start ug pp cc))

;; First clause
(let ((uf (get-unit f)))
(start uf p cc*))))


And similar for "or" we have

(let ((fr (newframe)))
(let ((uf (get-unit f)))
(start uf uf cc))
(unwind fr)
(let ((ug (get-unit g)))
(start ug p cc))))


The frame is a stack point in the prolog control stack that enables one to undo variable bindings and other constructs like "dynamic wind" operations and put a used unit on the cache.

It is possible to create the same logic with lambdas and this is done in guile-log but a problem with that is that the compilation time is huge. Also a complexity are that to make the units concept working one need to modify guile itself.