Во-первых, в RDF есть встроенная конструкция List, которую вы можете использовать следующим образом:
ex:mylist rdf:type rdf:List .
ex:myList rdf:first ex:firstElement .
ex:myList rdf:rest _:sublist1 .
_:sublist1 rdf:first ex:SecondElement .
_:sublist1 rdf:rest rdf:nil .
Здесь, чтобы узнать, что вы достигли конца списка, вам нужен специальный список с именем rdf:nil
. Это играет ту же роль, что и указатель null
в конце связанного списка в языках программирования.
Однако, хотя rdf:List
хорошо используется в существующих данных в Интернете, он никак не ограничивает использование предикатов rdf:first
и rdf:rest
, поэтому вы можете иметь много первых элементов для данный список, не вызывая несоответствия.
Итак, если вы действительно хотите смоделировать связанный список, вам нужны довольно выразительные возможности OWL. Я сделал это некоторое время назад, и это может быть найдено в http://purl.org/az/List.
Это нормально, что у вас есть пустой класс, так как вы указали, что Node
должен иметь nextNode
. Не следует навязывать, что узлы имеют контент или следующий элемент. Скорее, вы должны сказать, что количество элементов не превышает 1, что домен и диапазон hasNext
- это Node, а EndNode
- это узел без следующего узла. Но этого все еще недостаточно, поскольку это не означает, что вообще существует EndNode
. У вас может быть бесконечная последовательность или цикл.
Если вы хотите избежать циклов или бесконечной последовательности, вы должны определить переходное свойство hasFollower
и сказать, что в классе EndNode
.
есть хотя бы один последователь.
В общем, реализация строгих списков в OWL полностью отстает в плане производительности и в большинстве случаев совершенно бесполезна, так как rdf:List
достаточно для подавляющего большинства ситуаций.