I'm compiling Shen prolog directly to an SWI prolog backend and converting data back and forth via its FFI.
Since Shen prolog allows nested calls to regular Shen functions within its expressions, I'm lifting some of the nested calls into administrative normal form before compiling to SWI prolog. Higher order calls with prolog functions need to be kept as unevaluated prolog terms, so they can get passed to SWI's 'call' at some point.
I hit a bit of a snag with Shen Prolog's call, fork, and findall due to the way they use higher order predicates, and how they rely on closures and the fact that Shen prolog functions have extra hidden parameters, which ends up changing the evaluation order.
For example, (findall V (three (push1 V)) X) doesn't follow applicative order, since the call to 'three' is wrapped in lambda. It's unclear what the best way to deal with this is. At the moment, the call to 'push1' is being lifted out of the findall due to ANF. Can I just leave it like that, or do I have to simulate the lazy evaluation in all higher order uses of prolog predicates?
(defprolog three
[1|1] <--;
[1|2] <--;
[1|3] <--;)
(define push1
X -> (cons 1 X))
(defprolog test-find2
X <-- (findall V (three (push1 V)) X);)
Produces:
[findall V [lambda Y6448
[lambda Y6449
[lambda Y6450
[lambda Y6451
[three [push1 [shen.deref V V6453]]
Y6448 Y6449 Y6450 Y6451]]]]]
V6452 V6453 V6454 V6455 V6456]