Все словари RDF, в том числе базовые rdf (xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#") и rdfs (http://www.w3.org/2000/01/rdf-schema#), кроме собственно URI ("понятий словаря") и триплетов с ними ("аксиом" словаря), содержат в своей документации ряд "подразумеваемых следствий" или "правил логического вывода" из описываемых этими словарями понятий и аксиом, которые системы обработки этого RDF должны иметь ввиду и делать "логические выводы" из обратабываемого RDF с учётом всего, что следует неявно через эти "правила".
Вывод из аксиом может быть рекурсивным и потенциально бесконечным. Поэтому, у меня сложилось мнение, что его предполагается делать на лету, по мере поиска решения конкретной задачи, только для тех элементов, которые нужны для решения задачи. Авось задачи достичь конца цепочки никто не поставит.
Если сделать смотрелку только созданных триплетов, не умеющую на лету отображать все эти предполагаемые следствия всех аксиом всех затронутых словарей, то появляется желание попробовать предполагаемые свыводы сформировать в явном виде - создать, запомнить (мемоизировать логический вывод) и посмотреть что нагенерировалось. Мемоизировать выводы.
Хочется же посмотреть, сколько всего было подразумеваемым сверх явно заданного, и сколько из явно заданного могло быть подразумеваемым! Да и дальнейшие выводы делать не с нуля, а опираясь на ранее сделанные выводы - кажется вполне разумным. Мемоизация (кэширование) вычисляемого, собственно, для этого и делается, как правило.
Про всё созданное логическим выводом хотелось бы понимать, из каких триплетов и по каким правилам они следуют. Для этого как правила, так и всё по ним нагенерированное хочется снабдить мета-информацией - аннотировать. Анннотации, чтоб не множить сущности системы, тоже уместно делать триплетами.
Нагенерированное - это триплеты, и ссылаться на из других триплетов них можно либо реификацией в чистом виде, либо с помошью псевдо-свойств, что немножко сэкономит память.
Идею про псевдо-свойство я где-то подсмотрел, позже найду источник и поставлю ссылку. Псевдо-свойство - это, как и для реификации, уникальный URI, соответствующий одному триплету, который нужно аннотировать. Для связи со своим аннотируемым триплетом, он используется в копии аннотируемого триплета в качестве предиката между субъектом и объектом аннотируемого триплета, и для него делается ещё один служебный триплет, в котором он - субъект, объектом является предикат аннотируемого триплета, а предикатом является "tbpp:PseudoProperty". Таким образом, этот уникальный URI ссылается на все три URI аннотируемого им триплета всего двумя триплетами. В настоящей реификации уникальный URI триплета ссылается на три элемента своего аннотируемого триплета тремя отдельными триплетами.
Определения дополнительного словаря метаинформации:
Описание отдельного правила, скажем, tb:Rule_rdfs3, может выглядеть так:
tb:Rule_rdfs3 rdf:type tb:EntailmentPattern
tb:Rule_rdfs3 tb:EntailmentRule "aaa rdfs:range xxx; uuu aaa vvv => vvv rdf:type xxx"
tb:Счетчик_результата_Rule_rdfs3 tb:Это_счетчик_для tb:Rule_rdfs3
tb:Исходный_1_Rule_rdfs3 tb:Исходный_триплет tb:Rule_rdfs3
tb:Исходный_2_Rule_rdfs3 tb:Исходный_триплет tb:Rule_rdfs3
tb:Результат_Rule_rdfs3 tb:Триплет-Результат tb:Rule_rdfs3
и необязательные информационные триплеты
tb:Rule_rdfs3 rdfs:label "Rule rdfs 3"
tb:Rule_rdfs3 rdfs:seeAlso "https://www.w3.org/TR/2004/REC-rdf-mt-20040210/#RDFSRules"
tb:Rule_rdfs3 rdfs:comment "Range предиката сообщает, что про объект триплета, что он - ресурс соответствующего класса"
Генерация запускается для каждого правила отдельно.
При запуске генерации для правила tb:RuleN создается URI tb:Имя_состоит_из_порядкового_номера_и_времени (далее: tb:Gn)
Если триплеты хранить не совсем в общей куче, а делить по "схемам", то для результатов генерации создается новая схема с именем tb:Gn (совпадает с именем URI генерации), и всё далее расписываемое создаётся в ней.
Записываем следующие триплеты про саму сессию генерации
tb:Gn tb:По_правилу tb:RuleN
tb:Gn tb:Время_генерации "DD.MM.YYYY HH:MI:SS"
Далее. Предположим, есть два триплета (их псевдо-свойства назовём tbpp:t1 и tbpp:t2), подходящие под правило. При генерации применяем правило tb:RuleN и получаем результирующий триплет, его псевдо-свойство назовём tbpp:tR.
Если результирующего триплета ещё не было в БД
Записываем триплет и его псевдо-свойство tbpp:tR в схему для генерации.
Указываем, по какой генерацией создан триплет
tbpp:tR tb:Создано_генерацией tb:Gn (в схему генерации tb:Gn)
Указываем, что по данному правилу результирующий триплет создан 1 раз
tbpp:tR tb:Счетчик_результата_RuleN "1" (в схему генерации tb:Gn)
Указываем, какие исходые триплеты породили tbpp:tR на данном применении правила - создаем новое URI: tbpp:tF и триплеты (в схему генерации tb:Gn)
tbpp:t1 tb:Исходный_1_RuleN tbpp:tF
tbpp:t2 tb:Исходный_2_RuleN tbpp:tF
tbpp:tR tb:Результата_RuleN tbpp:tF
Если результирующий триплет уже был в БД
Выбираем или создаем в псевдо-свойство результирующего триплета tbpp:tR.
Ищем, зарегистрировано ли связь триплета tbpp:tR с этой генерацией. Если нет - регистрируем.
tbpp:tR tb:Создано_генерацией tb:Gn (в схему генерации tb:Gn)
Ищем счётчик отношения tbpp:tR к правилу N.
tbpp:tR tb:Счетчик_результата_RuleN ?xxx
Если нет - создаём (в схему генерации tb:Gn), записывая 1 в качестве ?xxx. Если есть счётчик - увеличиваем счётчик. Запоминаем значение счётчика.
Если счётчик < 10, ищем триплеты данного образца связи tbpp:tR через правило N с триплетами tbpp:t1 и tbpp:t2. Если счётчик >= 10, считаем что образцов достаточно.
tbpp:t1 tb:Исходный_1_RuleN ?aaa
tbpp:t2 tb:Исходный_2_RuleN ?aaa
tbpp:tR tb:Результата_RuleN ?aaa
Если нет - создаём их, используя новый уникальный URI в качестве ?aaa.
Все словари RDF, в том числе базовые rdf (xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#") и rdfs (http://www.w3.org/2000/01/rdf-schema#), кроме собственно URI ("понятий словаря") и триплетов с ними ("аксиом" словаря), содержат в своей документации ряд "подразумеваемых следствий" или "правил логического вывода" из описываемых этими словарями понятий и аксиом, которые системы обработки этого RDF должны иметь ввиду и делать "логические выводы" из обратабываемого RDF с учётом всего, что следует неявно через эти "правила".
См. например http://www.w3.org/TR/2014/REC-rdf11-mt-20140225/#patterns-of-rdfs-entailment-informative и https://trinidata.ru/tech_reasoner.htm
Вывод из аксиом может быть рекурсивным и потенциально бесконечным. Поэтому, у меня сложилось мнение, что его предполагается делать на лету, по мере поиска решения конкретной задачи, только для тех элементов, которые нужны для решения задачи. Авось задачи достичь конца цепочки никто не поставит.
Если сделать смотрелку только созданных триплетов, не умеющую на лету отображать все эти предполагаемые следствия всех аксиом всех затронутых словарей, то появляется желание попробовать предполагаемые свыводы сформировать в явном виде - создать, запомнить (мемоизировать логический вывод) и посмотреть что нагенерировалось. Мемоизировать выводы.
Хочется же посмотреть, сколько всего было подразумеваемым сверх явно заданного, и сколько из явно заданного могло быть подразумеваемым! Да и дальнейшие выводы делать не с нуля, а опираясь на ранее сделанные выводы - кажется вполне разумным. Мемоизация (кэширование) вычисляемого, собственно, для этого и делается, как правило.
Про всё созданное логическим выводом хотелось бы понимать, из каких триплетов и по каким правилам они следуют. Для этого как правила, так и всё по ним нагенерированное хочется снабдить мета-информацией - аннотировать. Анннотации, чтоб не множить сущности системы, тоже уместно делать триплетами.
Нагенерированное - это триплеты, и ссылаться на из других триплетов них можно либо реификацией в чистом виде, либо с помошью псевдо-свойств, что немножко сэкономит память.
Идею про псевдо-свойство я где-то подсмотрел, позже найду источник и поставлю ссылку. Псевдо-свойство - это, как и для реификации, уникальный URI, соответствующий одному триплету, который нужно аннотировать. Для связи со своим аннотируемым триплетом, он используется в копии аннотируемого триплета в качестве предиката между субъектом и объектом аннотируемого триплета, и для него делается ещё один служебный триплет, в котором он - субъект, объектом является предикат аннотируемого триплета, а предикатом является "tbpp:PseudoProperty". Таким образом, этот уникальный URI ссылается на все три URI аннотируемого им триплета всего двумя триплетами. В настоящей реификации уникальный URI триплета ссылается на три элемента своего аннотируемого триплета тремя отдельными триплетами.
Определения дополнительного словаря метаинформации:
Пространства имён tb, tbpp (как вариант, xmlns:tb="https://raw.githubusercontent.com/Nashev/TextBrain/origin/schemas/schema.rdf" xmlns:tbpp="https://raw.githubusercontent.com/Nashev/TextBrain/origin/schemas/PseudoProperties.rdf")
tbpp:PseudoProperty rdfs:label "Pseudo Property (reification analogue)" tbpp:PseudoProperty rdf:type rdf:Property
tb:EntailmentPattern rdfs:label "Entailment Pattern" tb:EntailmentPattern rdf:type rdf:Class tb:EntailmentPattern rdfs:comment "Правило логического вывода"@ru
tb:EntailmentRule rdfs:label "Entailment Pattern Rule" tb:EntailmentRule rdf:type rdf:Property tb:EntailmentRule rdfs:domain tb:EntailmentPattern tb:EntailmentRule rdfs:comment "Свойство с описанием собственно правила"@ru
tb:Исходный_триплет ... tb:Триплет-Результат ... tb:Это_счетчик_для ...
tb:По_правилу ... tb:Время_генерации ... tb:Создано_генерацией ...
Описание отдельного правила, скажем, tb:Rule_rdfs3, может выглядеть так: tb:Rule_rdfs3 rdf:type tb:EntailmentPattern tb:Rule_rdfs3 tb:EntailmentRule "aaa rdfs:range xxx; uuu aaa vvv => vvv rdf:type xxx" tb:Счетчик_результата_Rule_rdfs3 tb:Это_счетчик_для tb:Rule_rdfs3 tb:Исходный_1_Rule_rdfs3 tb:Исходный_триплет tb:Rule_rdfs3 tb:Исходный_2_Rule_rdfs3 tb:Исходный_триплет tb:Rule_rdfs3 tb:Результат_Rule_rdfs3 tb:Триплет-Результат tb:Rule_rdfs3 и необязательные информационные триплеты tb:Rule_rdfs3 rdfs:label "Rule rdfs 3" tb:Rule_rdfs3 rdfs:seeAlso "https://www.w3.org/TR/2004/REC-rdf-mt-20040210/#RDFSRules" tb:Rule_rdfs3 rdfs:comment "Range предиката сообщает, что про объект триплета, что он - ресурс соответствующего класса"
Генерация запускается для каждого правила отдельно. При запуске генерации для правила tb:RuleN создается URI tb:Имя_состоит_из_порядкового_номера_и_времени (далее: tb:Gn)
Если триплеты хранить не совсем в общей куче, а делить по "схемам", то для результатов генерации создается новая схема с именем tb:Gn (совпадает с именем URI генерации), и всё далее расписываемое создаётся в ней.
Записываем следующие триплеты про саму сессию генерации tb:Gn tb:По_правилу tb:RuleN
tb:Gn tb:Время_генерации "DD.MM.YYYY HH:MI:SS"
Далее. Предположим, есть два триплета (их псевдо-свойства назовём tbpp:t1 и tbpp:t2), подходящие под правило. При генерации применяем правило tb:RuleN и получаем результирующий триплет, его псевдо-свойство назовём tbpp:tR.
Если результирующего триплета ещё не было в БД
Если результирующий триплет уже был в БД