Сравнение литералов RDF в AllegroGraph Prolog в Common Lisp

Я пытаюсь сравнить объекты двух троек в базе знаний. Я подключил базу знаний через клиент ACL (Allegro CL Enterprise edition 9.0) и написал следующий код:

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

Моя база знаний включает следующие триплеты

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

Я пытаюсь сравнить ?threshold со значением "60" и ?NameMatch со значением "70"^^xsd:double и ожидаю результат "true". Как я могу это сделать?


person user3061324    schedule 03.12.2013    source источник
comment
Почему вы пометили этот пролог?   -  person false    schedule 03.12.2013
comment
@false: вероятно, потому, что он использует встроенный Пролог в Лиспе для Базы Знаний.   -  person Rainer Joswig    schedule 03.12.2013
comment
@RainerJoswig: Определенно выходит за рамки тега.   -  person false    schedule 03.12.2013
comment
@ user3061324: вы уверены, что оператор IF и переменные верны...?   -  person Rainer Joswig    schedule 03.12.2013
comment
@false: почему? Встроенный Пролог - это не Пролог? ?var - это логические переменные.   -  person Rainer Joswig    schedule 03.12.2013


Ответы (1)


В данных RDF все, что не является пустыми узлами или IRI, является литералом. Литералы могут быть простым литералом (строка без дополнительной информации), строкой с языковым тегом или лексической формой (частью строки) с типом данных (IRI).

В ваших данных литерал с лексической формой "70" имеет тип данных, который вы подвергли цензуре, но я предполагаю, что он должен быть xsd:double. То есть значение равно "70"^^xsd:double, что является числом двойной точности с плавающей запятой 70. Ваше другое литеральное значение "60" — это просто литерал. Сравнивать эти два значения на самом деле не имеет смысла, так как одно из них является числом, а другое — строкой.

Однако у вас есть два варианта:

  1. Вы можете выполнить сравнение строк с простым литералом "60" и лексической формой "70"^^xsd:double, и в этом случае вы должны использовать string< или string-lessp, в зависимости от от того, хотите ли вы учитывать регистр или нет (поскольку это строки цифровых символов, это, вероятно, не имеет значения).
  2. Вы можете предположить, что простой литерал "60" имеет лексическую форму, допустимую для xsd:double, выполнить соответствующее преобразование, а затем сравнить "60"^^xsd:double и "70"^^xsd:double как числа с <.

Я бы посоветовал вам, если возможно, очистить ваши данные (но это может быть не вариант, если они поступают откуда-то еще), чтобы вы могли выполнить числовое сравнение с <, как в (2), но без необходимости делать преобразование во время сравнения.

В дополнение к этим проблемам с RDF, ваш код на Лиспе также имеет некоторые проблемы. if принимает три аргумента (третий не является обязательным). Первое — это тестовое условие, а второе и третье — формы, которые оцениваются в зависимости от того, является ли первое значение истинным или нет. В вашем коде if получает только один аргумент:

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

Это попытка вызвать >= с одним аргументом, и это

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

который будет вызовом функции с именем ?NameMatch с тремя аргументами (?threshold, "true" и "false"). Что вы, вероятно, хотите здесь:

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

(Конечно, вам может понадобиться изменить тест, как описано выше.)

person Joshua Taylor    schedule 03.12.2013
comment
Большое спасибо Джошуа за ваш ответ. Мои оба значения набираются дважды. Я обнаружил проблему, так как теперь я конвертирую значение с помощью функции upi-value в клиенте ACL. Теперь это не дает ошибки, но не показывает TRUE - person user3061324; 04.12.2013
comment
@user3061324 user3061324 Что возвращает upi->value для этих значений? Что вы используете для сравнения полученных значений? - person Joshua Taylor; 04.12.2013
comment
Я изменил двойное число на целое число, и оно возвращает 80 и 60. Однако это не дает истинного результата. - person user3061324; 05.12.2013