All Manuals > KnowledgeWorks and Prolog User Guide > Appendix A: Common Prolog

A.6 Calling Prolog From Lisp

There are several entry points provided for calling Prolog from Lisp. The main interface function is called logic and has numerous options. The basic form is:

(logic <goal>
       :return-type <return-type> 
       :all <all-type> 
       :bag-exp <bag-exp>)

The keyword arguments are interpreted as follows:

:return-type describes what to do with a solution when one is found. Possible values of :return-type are:

:display
Display variable bindings and prompt user (the option used by the read-query-print loop).
:fill
Instantiate the goal expression and return it.
:bag
Instantiate <bag-exp> and return it.
:alist

Return an alist of variables and bindings.

The default is :fill.

:all tells what to do with multiple solutions. Possible values of :all are:

nil
Return the first solution.
:values
Return multiple solutions as multiple values.
:list
Return a list of the solutions.

:bag-exp is an expression that should be instantiated with the bindings from a solution. This is only meaningful if :return-type is :bag.

A.6.1 Examples

(logic '(color ?x) :return-type :display) 

writes:

?X = RED<wait for input>
(logic '(color ?x) :return-type :fill) 

returns:

(COLOR RED)
T
(logic '(color ?x) :return-type :alist) 

returns:

((?X . RED))
T
(logic '(color ?x) :all :list) 

returns:

((COLOR RED) (COLOR BLUE) (COLOR GREEN))
T
(logic '(color ?x)
       :return-type :bag
       :bag-exp '(?x is a color)
       :all :values)

returns:

(RED IS A COLOR)
(BLUE IS A COLOR)
(GREEN IS A COLOR)

A.6.2 Interface Functions

There are three additional ways to call logic, which are described in this section.

A.6.2.1 any, findall and findallset

Three simple interface functions call logic. They are any, findall, and findallset. Each takes two arguments: a result expression to instantiate and a goal expression. any returns the first solution found. findall returns all solutions. findallset returns all solutions deleting duplicates.

Assuming the definitions for fact and color from the previous examples.

|(any '(?x is the factorial of 5) '(fact 5 ?x))

returns:

|
|(120 IS THE FACTORIAL OF 5)
|
|(findall '(?x is a color) '(color ?x)) 

returns:

|
|((RED IS A COLOR) (BLUE IS A COLOR) 
  (GREEN IS A COLOR))
|
|(findall '?y '(or (= ?y 5) (= ?y 5))) 

returns:

|
|(5 5)
|
|(findallset '?y '(or (= ?y 5) (= ?y 5)))

returns:

|
|(5)

findall and findallset will hang if a goal expression generates an infinite solution set.

More powerful all solution predicates (bagof and setof) are available from within Common Prolog.

A.6.2.2 deflogfun

A different interface is available for predicates which will be called often from Lisp. The macro deflogfun may be used to generate normal Lisp functions that run with precompiled goals.

(deflogfun break-up (y) (append ?a ?b y) (?a ?b))

then:

(break-up '(foo bar baz))

returns:

(NIL (FOO BAR BAZ))
T
(break-up '(foo bar baz) :all :values) 

returns:

(NIL (FOO BAR BAZ))
((FOO) (BAR BAZ))
((FOO BAR) (BAZ))
((FOO BAR BAZ) NIL)
(break-up '(foo bar baz) :all :list) 

returns:

((NIL (FOO BAR BAZ)) 
 ((FOO) (BAR BAZ)) 
 ((FOO BAR) (BAZ))
 ((FOO BAR BAZ) NIL))
T

The generated function works like the Lisp functions any and findall, returning solutions to a prolog expression.

The form:

(deflogfun name args sample-expr return-expr)

defines a Lisp function called name, whose lambda list is the list args. The function will also take a keyword argument :all. If the function is called with :all nil (the default), then it returns the first solution, like any. If the function is called with :all t, then it returns a list of all the solutions, like findall. If the function is called with :all :values, then it returns multiple values, with one value per solution.

The sample-expr is like the second argument to any, that is, it is the prolog query expression. The return-expr is like the first argument to clog:any, that is, it defines how the result will be formed from the results of the query. If any of the symbols mention in args appears in sample-expr or return-expr, then its value is substituted. All other symbols in sample-expr and return-expr remain unchanged.

A.6.2.3 with-prolog

A final interface mechanism is with-prolog, which allows you to embed prolog into an arbitrary lisp function. Lisp variables are referenced in Prolog using "?.<name>".

(defun palindromep (x)
  (with-prolog
    (append ?a (?b . ?c) ?.x) ; note "?.x" reference
    (or (reverse ?a ?c)
        (reverse ?a (?b . ?c)))))
 
(palindromep '(yes no maybe)) 

returns:

NIL
 
(palindromep '(yes no maybe no yes))

returns:

T

The body of a with-prolog returns t if it succeeds and a non-local exit is not executed. It returns nil on failure.


KnowledgeWorks and Prolog User Guide (Windows version) - 01 Dec 2021 19:36:05