Convert from RDF "type qualified literal" to Prolog atom

I’m trying to understand how to convert between normal Prolog atoms and the “type qualified literal” in RDF:

?- rdf_assert(number, is, 1).
true.

?- rdf_assert(number, is, 'foo').
true.

?- rdf(number, is, X).
X = 1^^'http://www.w3.org/2001/XMLSchema#integer' ;
X = foo.

I’m looking for a predicate that will take the values of X above and convert them to the original atom values. Since strings don’t appear to be type qualified like integers are, I can’t do something simple like:

?- rdf(number, is, N^^URI).
N = 1,
URI = 'http://www.w3.org/2001/XMLSchema#integer'.

because it won’t unfy with strings. Here’s a made up example of what I’m looking for:

?- rdf(number, is, Qualified), convert(Atom, Qualified).
X = 1;
X = foo.

Is there such a predicate somewhere?

If you double post or post something similar else where please note it, e.g.

Convert from RDF “type qualified literal” to Prolog atom in SWI Prolog

Thanks. :slightly_smiling_face:

1 Like

Oh, sure! Found this forum after stack overflow and thought it might be more directed here. Also, I expanded the question a bit here from that original post since I’ve had now had some experience with how the RDF store handles strings

I don’t really understand what you are after, but possibly rdf_lexical_form/2 is a step in the right direction. The same section has some other candidates.

Sorry if I was unclear, maybe this will clear it up:

I am trying to store and retrieve rdf triples as simple Prolog atoms (i.e. a single atom like foo or 1, not X^^Y). The rdf/3 predicate retrieves them with extra type information so I am trying to write my own, let’s call it myRdf/3. Here’s an example of how it would work:

?- rdf_assert(number, is, 1).
true.

?- rdf_assert(number, is, ‘foo’).
true.

?- myRdf(number, is, X).
X = 1
X = foo.

I have two issues I’ve hit trying to do this:

  1. I can’t find a predicate in the system that will convert a “type qualified literal” like 1^^'http://www.w3.org/2001/XMLSchema#integer' into a Prolog atom. rdf_lexical_form/2 and rdf_canonical_literal/2 will convert in one direction only:

    ?- rdf_lexical_form(1, X).
    X = “1”^^‘http://www.w3.org/2001/XMLSchema#integer’.

    ?- rdf_lexical_form(X, “1”^^‘http://www.w3.org/2001/XMLSchema#integer’).
    false.

    ?- rdf_canonical_literal(1, X).
    X = 1^^‘http://www.w3.org/2001/XMLSchema#integer’.

    ?- rdf_canonical_literal(X, 1^^‘http://www.w3.org/2001/XMLSchema#integer’).
    ERROR: Arguments are not sufficiently instantiated

  2. The rdf_assert/3 predicates seem to be converting the third term (at least) from a normal Prolog atom into a type qualified form for storage, but not consistently. For example:

    • 1 is converted into 1^^'http://www.w3.org/2001/XMLSchema#integer'
    • 'foo' is converted into foo. To be consistent I would have expected 'foo' to be converted into foo^^'http://www.w3.org/2001/XMLSchema#string'

So I’ve ended up writing a convertTerm/2 predicate to do the conversion like this:

convertTerm(X^^_, X).
convertTerm(X, X). % Needed since strings don't have type information

Which feels a little hacky to me since it seems like just stripping off the type information isn’t going to work in all cases.

I figured there must be a built-in predicate that just does the inverse of whatever rdf_assert/3 is doing to the atoms you pass it.

Am I just missing something?

Not sure. Using the old library(semweb/rdf_db) gets you a bit closer (I think). This is an RDF library though, so it implements the typed RDF 1.1 view on the world. Why not simply use assert/retract to the Prolog DB if you want something else? Once upon a time the RDF library was much faster. Prolog got JIT clause indexing though and now beats the RDF library easily in performance and usability. Plain Prolog does (in most scenarios) use more memory though.

@jan I am bit puzzled by the last statement. Are you suggesting that it may be worthwhile to convert RDF data directly to a Prolog data structure (i.e. bypass the RDF libs altogether)? In that case we’ll be losing out on some of the goodies provided by the RDF libs (but we’ll get the full power of Prolog in return).

Yes. Just using the Prolog DB does a pretty good job on RDF these days. Yes, you loose some goodies, but not too much. Surely a pure Prolog (re)implementation of if the RDF libraries is feasible these days. It will probably outperform the C version and could be much more flexible, for example by making external data visible as RDF dynamically. It probably could also exploit tabling to provide both more complete and faster reasoning. The main disadvantages are a higher memory usage, reducing the scalability and it will also be hard to beat loading the binary triple format.

These are compelling reasons (especially the tabling, as RDF queries tend to be a lot of the same). What memory increase would you expect to happen? I suppose, porting the RDF core libs (the part in C) to Prolog is they way to go. The RDF-libs still have value IMO, and, with the recent tabling enhancements, one may even dream of an OWL reasoner (I understood tabling would be needed for this). I am not sure if I am up to the job, but what would it take to the port the core libs to Prolog (I would assume it to be rather straight forward, but I am probably naive in my thinking)

I didn’t use assert and retract because I needed a transactional data store that can make changes to the database that are visible to subsequent predicates but only commits those changes on success, unlike (my understanding of) assert and retract. (Also as a side note almost all of the data in my program is stored as triples so that was a nice fit, but mostly a secondary win)

The RDF rdf_transaction/1 predicate and store semantics have so far been perfect from that respect. Are there assert/retract variants that support transactions using the same semantics as rdf_transaction/1?

No. That probably will get there someday, but quite likely not very soon. A lot of the stuff that needed to make this possible is already in place.

I don’t know. It probably also depends heavily on the index requirements you have. I think it would require rethinking the entire RDF infrastructure, although a lot of the good stuff such as the parsers and serializers and the RDF literal representation can be reused.

You know about TRILL? I think this actually doesn’t use tabling. Thea also contains transformation of OWL to a (tabled) Prolog program.