Comparing RDF literals in AllegroGraph Prolog in Common Lisp

201 views Asked by At

I am trying to compare the objects of two triples in a knowledgebase. I have connected the knowledgebase through ACL client (Allegro CL Enterprise edition 9.0) and written the following code:

(select (?s ?threshold ?NameMatch)
    (q- ?s !mynamespace:hasNameMatch ?NameMatch)
    (q- !mynamespace:hasNameMatch !mynamespace:hasThresholdValue ?threshold)
    (setq return (if (>= (?NameMatch ?threshold "true" "false")))     
   (pprint ret))  

My Knowledgebase includes the following triples

Subject             Predicate             Object
ns:hasAddressMatch  ns:hasThresholdValue  "60"
<../729277>         :hasNameMatch         "70"^^xsd:double

I am trying to compare the ?threshold with value "60" and ?NameMatch with value "70"^^xsd:double, and I expect the result "true". How can I do this?

1

There are 1 answers

3
Joshua Taylor On BEST ANSWER

In RDF data, things that aren't blank nodes or IRIs are literals. Literals may be a plain literal (a string with no additional information), a string with a language tag, or a lexical form (string part) with a datatype (an IRI).

In your data, the literal with lexical form "70" has a datatype which you've censored, but I assume is supposed to be xsd:double. I.e., the value is "70"^^xsd:double, which is the double precision floating point number 70. Your other literal value "60" is just a plain literal. It doesn't really make sense to compare those two values, since one is a number and one is a string.

You have two options though:

  1. You could do a string comparison with the plain literal "60" and the lexical form of "70"^^xsd:double, in which case you'd use string< or string-lessp, depending on whether you want case sensitivity or not (since these are strings of digit characters, it probably doesn't matter).
  2. You could assume that the plain literal "60" has a lexical form that's legal for an xsd:double, do the appropriate conversion, and then compare "60"^^xsd:double and "70"^^xsd:double as numbers with <.

I'd suggest that, if possible, you clean up your data (but this might not be an option if it's coming from somewhere else) so that you can do a numeric comparison with < as in (2), but without needing to do the conversion at comparison time.

In addition to those RDF concerns, your Lisp code also has some issues. if takes three arguments (the third is optional, though). The first is a test condition, and the second and third are forms that get evaluated depending on whether the first evalutes to true or not. In your code, if is only getting one argument:

(if (>= (?NameMatch ?threshold "true" "false")))
    -------------------------------------------

This is trying to call >= with one argument, and that's the

(?NameMatch ?threshold "true" "false")

which would be a function call to the function named ?NameMatch with three arguments (?threshold, "true" and "false"). What you probably want here is:

(if (>= ?NameMatch ?threshold) "true" "false")

(Of course, you may still need to modify the test as described above.)