This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
I have a question for @mauricio.szabo and/or the people who tried out https://gitlab.com/mauricioszabo/spock. How did you install the JPL library? Did you need a specific version?
I ask this because after linking the version bundled in swi
(> 8.0.0 as the readme suggests) in resources
:
/home/carlo/code/clojure/swiOmg/resources λ ls -al
lrwxrwxrwx 1 carlo users 83 Jul 17 16:08 jpl.jar -> /nix/store/i8wyyyl0hcp1hmnhi63sa092vb66ixp4-swi-prolog-8.3.29/lib/swipl/lib/jpl.jar
lrwxrwxrwx 1 carlo users 98 Jul 17 16:29 libjpl.so -> /nix/store/i8wyyyl0hcp1hmnhi63sa092vb66ixp4-swi-prolog-8.3.29/lib/swipl/lib/x86_64-linux/libjpl.so
and including that path in my deps.edn
file:
{:paths ["resources"]
:deps
{link.szabo.mauricio/spock {:mvn/version "0.1.1-SNAPSHOT"}}}
If I evaluate this in a repl:
(ns core
(:require [spock.swi :as spock]))
I get the error:
2. Unhandled clojure.lang.Compiler$CompilerException
Error compiling spock/swi.clj at (1:1)
#:clojure.error{:phase :execution, :line 1, :column 1, :source "spock/swi.clj"}
...
1. Caused by java.lang.ClassNotFoundException
org.jpl7.Atom
Hi, author here: it needs a somewhat recent version of JPL / SWI. What's the result of swipl --version
?
Hey @mauricio.szabo, thanks for looking into this. So, the swipl version is:
/home/carlo/code/prolog λ swipl --version
SWI-Prolog version 8.3.29 for x86_64-linux
and I invoke the repl with the correct -J-D
invocation (I see that the java library path is set to resources/
.
I also used the version of JPL
that come included in the swipl
installation.Ok, I did look at my machine, and mine is 8.4.3. I'm on Linux, installed SWI with the official PPA - packages name are swi-prolog
and swi-prolog-java
Also tried ls -l resources
on my root path, and it returned this:
... jpl.jar -> /usr/share/java/jpl.jar
... libjpl.so -> /usr/lib/x86_64-linux-gnu/jni/libjpl.so
(removed the permissions and date to get in a single line)
My project.clj
also includes the following paths:
:resource-paths ["resources/jpl.jar"]
:jvm-opts [~(str "-Djava.library.path=resources/:" (System/getProperty "java.library.path"))]
Can you check if both are present? Please notice that I only got things working by linking the native libraries on the resources
path, not by copying them - not sure why
Yes they are both present, I included an ls
in my original post, looks like:
/home/carlo/code/clojure/swiOmg/resources λ ls -al
jpl.jar -> /nix/store/i8wyyyl0hcp1hmnhi63sa092vb66ixp4-swi-prolog-8.3.29/lib/swipl/lib/jpl.jar
libjpl.so -> /nix/store/i8wyyyl0hcp1hmnhi63sa092vb66ixp4-swi-prolog-8.3.29/lib/swipl/lib/x86_64-linux/libjpl.so
I'm using deps.edn
so the paths look a bit different from the project.clj
you linked. Idea, do you have the sample project that works for you somewhere on gitlab?
Wait, it seems to work now, because you have this:
:resource-paths ["resources/jpl.jar"]
and I only did the paths as
:paths ["resources/"]
while translatingWow, wonderful! Mind if you can do a PR for the README, to add support for deps.edn
?
By the way, I'm almost done adding support for ClojureScript too :rolling_on_the_floor_laughing:
I'll absolutely do that, and also include the fix for with-rules
. I intend also to check out the instructions for cljs (although I'm a bit scared for the non auto-loading libraries part)
also, a bit of a surface question: I wonder why you chose this as the representation of a rule:
(ancestor [:x :y] [(parent :x :z)
(ancestor :z :y)])
instead of e.g.
((ancestor :x :y) [(parent :x :z) (ancestor :z :y)])
which keeps the symmetry of argument syntaxUnfortunately, no. There seems to be no way to fix that, honestly, because the way WASM works. It may be possible to fix it if we recompile the SWI WASM to include the Node.JS filesystem option, but then it'll only autoload in Node (and that's probably the target that people don't want to use it anyway - specially considering we can avoid all that by calling SWIPL directly with the command line and avoid all WASM)
right, could we just autoload the common modules that swi autoloads by grabbing the sources, so that the user doesn't have to do that himself?
also, another question (sorry!): in the clj version, is a new process spawned every time I do a query, or is there a pl server that I'm asking questions to?
> also, a bit of a surface question Honestly, I don't remember 😅. But things changed quite a lot, and honestly if I could time-travel on the past, I would remove 100% of these weird things and just do the following, for example:
[(parent child dad)
(parent child mom)
(:- (ancestor :x :y) (and parent :x z) (ancestor :z :y)))]
the syntax you just posted is also perfect, glad that's supported (and should probably be mentioned in the README)
Yeah, I'm not a good documenter, unfortunately 😞
Also, clj
uses the rules for JPL. If I'm not mistaken, JPL spawns a SWIPL "server" and uses a thread pool to handle queries
Ah, don't think that's true, and I can do a PR for this particular instance, if you want it
in fact I read that JPL also has a mechanism for async queries that enable going back and forth between prolog and the java process
ok, I'll do the PRs in ~1h, and then try to get the cljs version running and I'll probably post more questions
I usually use only lists
because I use member
a lot
I see, thank you. In the meatime, I was trying to get precise with the alternative syntax you mentioned. What's wrong with:
(def example
'[(parent child dad)
(parent child mom)
(:- (ancestor :x :y) (and (parent :x z) (ancestor :z :y)))])
(with-open [rules (spock/with-rules example)]
(spock/solve {:rules rules} '(ancestor :anc :desc)))
Oh, wait, maybe I have a bug somewhere? Let me check...
I checked the code yesterday (am not at my PC now) and I only saw the path that interprets the syntax in the tutorial. Maybe you have the other one stowed in a branch?
Not even that, I ended up thinking about this syntax but did not implement it
Well, good news, the library is still young enough that it could be added. Also, I was thinking about two issues yesterday related to notation. The first is, using :- as prefix like in traditional lisp syntax we lose the possibility to express directives, i.e. headless implications that are used when instructing the compiler, like in
:- use_module(library(lists)).
It's not even the case that we always have one syntactic construct as the head: in extensions like CHR, you can have conjunctions as the first part of the rule (but the operators there are ==>
and <=>
instead of :-
The second thing is that we could seize the chance and propose a better syntax for the anonymous predicates used as part of higher order predicates (usually done with the yall
library) so that we're not forced to write the infix version of
maplist({Postfix}/[In,Out]>>atom_concat(In,Postfix,Out),
ListIn, ListOut).
Given these issues and analogue ones (DCGs, using constraint arithmetic by default etc) I wonder if we shouldn't open to the user the possibility of deciding how the interpretation is done.
By the way, how do you import a prolog library in clj right now?I honestly haven't though about all these cases 😄. For example, I'm relying on auto-import of libraries for now...
I would really like a syntax for higher order predicates that mimics the anonymous function literal in clojure (and we could do that with an ad hoc treatment of fn*
Maybe it could be a good idea to allow for some form or eval-string
in SWI
Honestly, I would like to change this notation I'm using. It ended up being confused and ended up being TWO notations (one form rules/etc and one for queries)
For example, I remember now why I did not implement the :-
-> basically, it changes semantics of EVERYTHING
Currently, a prolog struct like foo(a, b)
is represented as (foo a b)
in Clojure
So the "normal" way of representing rules should be (foo a b), *not*
(foo [a b])`
So, foo(A, B) :- bar(A, Z), bar (Z, B)
should become (:- (foo :a :b) (and (bar :a :z) (bar :z :b)))
And that is a huge breaking change 😞
Is this library already in production in a way that a breaking chance in syntax is not advisable?
I have no idea, honestly.
I'm kinda willing to make a spock.swi-old
and keep all the current code there