Пролог неизвестен в базе знаний
Я пытаюсь выучить пролог, и кажется, что полнота знаний очень важна, потому что, очевидно, если в базе знаний нет факта или он неверен, это повлияет на результаты запроса. Мне интересно, как лучше обрабатывать неизвестные детали факта. Например,
%life(<name>,<birth year>,<death year>)
%ruler(<name>,<precededBy>,<succeededBy>)
Некоторые люди, которых я добавляю в базу знаний, все еще живы, поэтому их год смерти неизвестен. В примере с правителями у первого правителя не было предшественника, а у нынешнего правителя нет правопреемника. В случае, если есть эти неизвестные, я должен указать какое-то неизвестное значение флага или детали могут быть опущены. В случае правителя, не зная предшественника, будет ли этот факт выглядеть так?
ruler(great_ruler,,second_ruler).
1 ответ
Ну, у вас есть несколько вариантов.
В этом конкретном случае я бы поставил под сомнение ваш дизайн. Вместо того, чтобы ставить предыдущее и следующее на линейке, вы можете просто поместить следующее и использовать правило для поиска предыдущего:
ruler(great_ruler, second_ruler).
ruler(second_ruler, third_ruler).
previous(Ruler, Previous) :- ruler(Previous, Ruler).
Этот предикат просто потерпит неудачу для great_ruler
что, вероятно, уместно - в конце концов, перед ними никого не было.
В других случаях это может быть не просто. Поэтому вам нужно решить, хотите ли вы сделать явное значение для unknown или использовать переменную. По сути, вы хотите сделать это:
ruler(great_ruler, unknown, second_ruler).
или вы хотите сделать это:
ruler(great_ruler, _, second_ruler).
В первом случае вы можете получить ложные ответы с участием unknown
, если вы не пишете какую-то собственную логику, чтобы поймать ее. Но я на самом деле думаю, что второй случай хуже, потому что эта пустая переменная будет объединена с чем угодно, поэтому многие запросы будут давать странные результаты:
ruler(_, SucceededHimself, SucceededHimself)
удастся, например, объединение SucceededHimself = second_ruler
что, вероятно, не то, что вы хотите. Вы можете проверить переменные, используя var/1
а также ground/1
, но в этот момент вы вмешиваетесь в поиск Пролога, и он станет более сложным. Таким образом, пустая переменная не так похожа NULL
в SQL, как вы могли бы хотеть, чтобы это было.
В итоге:
- предпочитаю представления, которые не приводят к этой проблеме
- если принудительно, используйте специальное значение