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?
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 bexsd: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:
"60"
and the lexical form of"70"^^xsd:double
, in which case you'd usestring<
orstring-lessp
, depending on whether you want case sensitivity or not (since these are strings of digit characters, it probably doesn't matter)."60"
has a lexical form that's legal for anxsd: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:This is trying to call
>=
with one argument, and that's thewhich would be a function call to the function named
?NameMatch
with three arguments (?threshold
,"true"
and"false"
). What you probably want here is:(Of course, you may still need to modify the test as described above.)