могу ли я сделать это в прологе AllegroGraph?

У меня есть файл RDF, и мне нужно извлечь из него некоторую информацию в одну строку.

Теперь я использую AllegroGraph с механизмом запросов Prolog:

(select (?result)
      (q ?a !rdfs:label ?alabel)
      (q ?b !rdfs:label ?blabel)
      (lisp ?result (string+ ?alabel " AND " ?blabel))) 

чтобы получить результаты в одной строке:

 "{a1} AND {b1}" 
 "{a1} AND {b2}" 
 "{a2} AND {b1}" 
 "{a2} AND {b2}" 

Теперь мне нужно сгруппировать все строки ?result в одну строку со строкой «ИЛИ». поэтому я получаю:

 "{a1} AND {b1} OR {a1} AND {b2} OR {a2} AND {b1} OR {a2} AND {b2}" 

Есть ли какая-нибудь функция в прологе для этого?


person user2598997    schedule 20.09.2013    source источник
comment
Я не знаю, можете ли вы сделать это в Prolog AllegroGraph или нет, но это можно сделать относительно легко с помощью запроса SPARQL 1.1. (Это не отвечает на ваш вопрос, но я ожидаю, что AllegroGraph поддерживает SPARQL 1.1, поэтому вы, вероятно, сможете получить этот результат с помощью AllegroGraph, будь то на Прологе или нет.)   -  person Joshua Taylor    schedule 20.09.2013
comment
Спасибо. На самом деле я не мог найти способ сделать это в прологе. Думаю, мне придется вернуться к SPARQL для всего проекта. Не могли бы вы объяснить, как это сделать в SPARQL, пожалуйста.   -  person user2598997    schedule 27.09.2013
comment
Сожалеем, что вы не нашли решения на Прологе, но теперь у вас есть ответ на основе SPARQL.   -  person Joshua Taylor    schedule 27.09.2013


Ответы (1)


Тот факт, что у вас есть только a* слева и b* справа, означает, что у вас есть какое-то другое условие выбора, чем просто наличие метки. Учитывая такие данные:

@prefix : <http://example.org/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.

:a1 a :ClassA ; rdfs:label "a1" .
:a2 a :ClassA ; rdfs:label "a2" .
:b1 a :ClassB ; rdfs:label "b1" .
:b2 a :ClassB ; rdfs:label "b2" .

вы можете выбрать ?a и ?b по их классам (:ClassA и :ClassB), а затем также извлечь их метки с помощью шаблона, например:

?a a :ClassA ; rdfs:label ?alabel .
?b a :ClassB ; rdfs:label ?blabel .

Затем вы можете получить {alabel} AND {blabel} с помощью bind и concat:

bind( concat( "{", ?alabel, "} AND {", ?blabel, "}" ) as ?AandB )

Используя их, запрос типа

prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?AandB { 
 ?a a :ClassA ; rdfs:label ?alabel .
 ?b a :ClassB ; rdfs:label ?blabel .
 bind( concat( "{", ?alabel, "} AND {", ?blabel, "}" ) as ?AandB )
}

даст вам результаты, которые вы уже можете получить:

-------------------
| AandB           |
===================
| "{a2} AND {b2}" |
| "{a2} AND {b1}" |
| "{a1} AND {b2}" |
| "{a1} AND {b1}" |
-------------------

Хитрость теперь состоит в том, чтобы использовать group_concat и неявную группу, чтобы объединить все это в строку с разделителем " OR ":

prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ( group_concat( ?AandB ; separator=" OR ") as ?string ) where { 
 ?a a :ClassA ; rdfs:label ?alabel .
 ?b a :ClassB ; rdfs:label ?blabel .
 bind( concat( "{", ?alabel, "} AND {", ?blabel, "}" ) as ?AandB )
}

чтобы получить результат:

----------------------------------------------------------------------
| string                                                             |
======================================================================
| "{a2} AND {b2} OR {a2} AND {b1} OR {a1} AND {b2} OR {a1} AND {b1}" |
----------------------------------------------------------------------

Если хотите, вы даже можете избавиться от bind и просто поместить выражение concat прямо в group_concat. Вам может показаться, что это легче читать (меньше прыгать вокруг) или сложнее читать (большой однострочный текст), но, по крайней мере, хорошо иметь варианты:

prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ( group_concat( concat( "{",?alabel,"} AND {",?blabel,"}" ) ; separator=" OR ") as ?string ) where { 
 ?a a :ClassA ; rdfs:label ?alabel .
 ?b a :ClassB ; rdfs:label ?blabel .
}

Есть и другие примеры использования group_concat в StackOverflow, которые также могут быть вам полезны:

person Joshua Taylor    schedule 27.09.2013