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 https://software-lab.de/doc/ref.html#pilog 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:
@X=Kate
which is the expected result.
*This how to is the result of a discussion on the mailing list during november 2016 started here http://www.mail-archive.com/picolisp@software-lab.de/msg06381.html.
https://picolisp.com/wiki/?accesstolispfunctionfrompilog
09apr17 | viKid |