Пролог неизвестен в базе знаний

Я пытаюсь выучить пролог, и кажется, что полнота знаний очень важна, потому что, очевидно, если в базе знаний нет факта или он неверен, это повлияет на результаты запроса. Мне интересно, как лучше обрабатывать неизвестные детали факта. Например,

%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, как вы могли бы хотеть, чтобы это было.

В итоге:

  • предпочитаю представления, которые не приводят к этой проблеме
  • если принудительно, используйте специальное значение
Другие вопросы по тегам