Access to Lisp Functions from Pilog

This how-to aims at showing with a short example how a Lisp only function can be accessed from Pilog. It illustrates the last part of the Pilog documentation in which says that "Pilog can be called from Lisp and vice versa".

To illustrate this, let's say that you have those two facts in a Pilog database:
      (be age (Paul 19) )
      (be age (Kate 17) )
and that you want to find the person under 18.

In full Prolog you may have written something like this:

underage(X) :- age(X,Y), Y < 18.

however a direct translation into Pilog like the following rule:

      (be underage (@X)
        (age @X @Y)
        (< @Y 18) )

doesn't work, and the query:

(? (underage @X) )

yields to NIL instead of the expected result @X=Kate.

The reason is that < (less than) is not a Pilog function but a Lisp only one in PicoLisp.

In order to embed a Lisp expression in Pilog, you must use ^ operator. It causes the rest of the expression to be taken as Lisp. Then, inside the Lisp code you can in turn access Pilog-bindings with the -> function.

Hence, in our case, a working translation of the Prolog rule above is:

      (be underage (@X)
        (age @X @Y)
        (^ @ (< (-> @Y) 18)) )

In (^ @ (< (-> @Y) 18)), @ is an anonymous variable used to get the result. If you need to access the result you can bind it to a defined variable like in (^ @B (+ (-> @A) 7)) where @B is now bound to @A + 7.

You may prefer to define your own Pilog predicate in this particular case. Let's say that to avoid confusion, you want to create a Pilog predicate call less_than to mimic the Lisp function <:

      (be less_than (@A @B)
        (^ @ (< (-> @A) (-> @B) )))

Then the Pilog rule becomes:

      (be underage (@X)
        (age @X @Y)
        (less_than @Y 18) )

and now:

(? (underage @X) )

yields to:


which is the expected result.

*This how to is the result of a discussion on the mailing list during november 2016 started here

09apr17    viKid