Need help and/or examples of using WOQL AST directly in Prolog

There are examples, tutorials, and support for using JSON-LD, JavaScript (WOQL.js), and Python, but the only example I could find of using WOQL AST directly is this one here. That’s a shame because using WOQL AST directly in Prolog seems to me to be the most elegant and concise way of using Terminus.

Here’s what I’ve done so far:

  1. Installed and launched the Terminus docker image using quickstart.
  2. Created a database called ‘test’ and followed the bike share data tutorial
  3. Attached to a Prolog console by using ./terminus-quickstart/terminus-container attach or docker attach terminus-server
  4. Confirmed I can connect to my local test database in the Prolog console: connect('http://localhost:6363/test', DB).
  5. Confirmed that a very simple and small WOQL.js query returns multiple rows of data: WOQL.select("v:Start").and(WOQL.triple("v:Journey", "start_station", "v:Start")).
  6. Tried to run the same query in the attached Prolog console: connect('http://localhost:6363/test', DB), ask(DB, select([Start], (t(_ , start_station, Start)))).

This is where I get stuck. This query in Prolog and all variations I could come up with always return ‘false’.

Could someone help me fix my query?

General tips and advice for using Terminus within Prolog also appreciated.

1 Like

Unfortunately we don’t really have a documented interface for using WOQL in Prolog. However TerminusDB uses it extensively internally to do a range of things so there are lots of examples litered througout the codebase.

The queries in the Prolog AST require prefixes to be used, so probably the predicate is not quite right.

To see what triples exist try:

connect(URL, DB), ask(DB, t(X,P,Y)).

We intend to document this eventually. If you want to see examples just do a search for ask on github in terminusdb/terminus-server.

2 Likes

That works, thank you!!!

I’m really excited that I can now replicate the query in the bike share data tutorial:

connect('http://localhost:6363/test', DB),
ask(DB, (
    t(Journey, rdf/type, scm/'Journey'),
    t(Journey, scm/start_station, Start),
    t(Start, rdfs/label, StartLabel),
    t(Journey, scm/end_station, End),
    t(End, rdfs/label, EndLabel),
    t(Journey, scm/journey_bicycle, Bike)
)).

I’ll try to document my Prolog exploration in a tutorial.

2 Likes

Thanks @aram would be great - always keen to have things for prologers!

1 Like

Thanks @luke for the encouragement!

I’ve noticed that Terminus uses Prolog for its unit tests, but WOQL AST is not tested directly. Instead, Prolog dicts seem to be converted to JSON-LD and passed to the API interface.

Maybe @gavin could clarify which mode of Prolog development he envisions in the long term:

  1. Use Prolog AST directly via ask(DB, query).
  2. Pull the following reoccurring code block into a Prolog module(terminus) and use the API from Prolog just like any other language. Convert all unit tests to use the new module.
with_output_to(
    string(Payload),
    json_write(current_output, Message, [])
),

Args = ['--user', Auth,'-d',Payload,'-X','POST','-H','Content-Type: application/json', URI],

report_curl_command(Args),
curl_json(Args,Term),
nl,json_write_dict(current_output,Term,[]),
2 Likes

Yeah, #1 is the interface currently. The downside is that you can only query terminus locally. This will continue to be available into the future, although we may need to change some of the internal AST names to regularise them.

#2 is what we’d like to see so that people can use prolog remotely. No need to do it if you’re local though!

2 Likes

Hi: just to advise I’ve started some work on trying to write a swipl woql client module. Its not yet complete :slight_smile: It does not re-use any of the existing swipl server code, but is standalone, just using the standard swipl libaries. Its style of usage is similar to the existing python woql module. To give a flavour:

server_url(“http://localhost:6363”).
db(“Swipl”).
user(“root”).
key(“root”).

run() :-
server_url(Server),
user(User),
key(Key),
db(DB),

Client = client{}.create(Server, User, Key),
client:connect(Client, Result1),
client:deleteDatabase(Client, DB, Result2),
client:createDatabase(Client, DB, “My first swipl DB!”, Result3),

Q = woql{}.query().doctype(“PersonType”).label(“Person”).description(“Somebody”).execute(Client).

I’ll keep working away at it, post updates here, and push a first release onto github once I’m comfortable with it…

2 Likes

An update, just to mark work (still) in progress…

I have my prototype swipl woql support in a first version now - it can reproduce everything that I have in my first Python Jupyter tutorial: ie create/delete database, create simple schema with properties and labels, populate data with when/inserts/idgen/add_triple/add_quads, query data with triple/and/or/not/greater/lesser, and delete_triple. I also added some support to parse the query response and tidy it up (swipl doesn’t have Python dataframes, but still…).

I’m moving on to add support now for reading data from external .csv files…

1 Like

I released the first version of my swipl binding to WOQL and TerminusDB earlier this afternoon.

See https://github.com/Chrisjhorn/terminusDB/blob/master/README.md

3 Likes

Great stuff Chris, I’m playing with it now.

We have regularised our API server responses to give back a valid JSON-LD object, which has broken a few things in the tutorial, but I’ll make a pull request to get that stuff working again. The changes are rather cosmetic.

I’ll try to use it in anger soon.