Лучший способ определить предикат в Прологе - PullRequest
2 голосов
/ 31 декабря 2011

У меня проблема с определением процедур в Прологе.У меня есть два исходных файла, и я хочу проконсультироваться с движком Prolog.Это можно сделать, вызвав Prolog как swipl -g «['1.pl', '2.pl'].

Оба файла сгенерированы другой программой, написанной на другом языке программирования, и я могу 'точное прогнозирование содержимого файлов заранее.

Проблема в том, что в одном из файлов всегда есть правило

predicate1(X):-predicate2(X).

Но иногда правило

predicate2(something):-body

не существует в обоих файлах, и я получаю сообщение об ошибке "Предикат2" не определен при выполнении некоторых запросов для предиката 1.

Если я включаю строку

:- dynamic(predicate2/2). 

водин из файлов, который помогает, только если предикат / 2 не определен в другом файле (в противном случае я получаю что-то вроде «вы действительно уверены, что хотите переопределить предикат2 / 2?». И здесь я не хочу переопределять что-то, чтобысохранить данные из другого файла.

Итак, я понятия не имею, как сделать предикат просто «определенным». Мне нужно решение для SWI-Prolog или SICStus Prolog. (к сожалению, версии не имеют разделадля определения прогнозаест, как визуальный пролог)

Ответы [ 3 ]

3 голосов
/ 15 апреля 2014

Вам необходимо объявить predicate2/2 multifile с той же директивой ISO. Таким образом, в каждом из файлов вы пишете вверху или перед любыми пунктами predicate2/2:

:- multifile(predicate2/2).

Это независимо от того, есть ли у вас предложения для этого предиката.


Предложение @CapelliC определенно опасный шаг. Если вы отключите все ошибки существования, вы пропустите множество законных ошибок!

Например, вы объявили dynamic(predicate2/2), но использовали predicate2(_). Так какой арити ты хочешь?

2 голосов
/ 31 декабря 2011

В SWI Prolog вы можете избежать ошибки.Измените поведение системы с помощью встроенного ISO

:- set_prolog_flag(unknown, Choice).

. Выбор может быть одним из (сбой, предупреждение, ошибка).

Таким образом, ваша командная строка будет выглядеть так:

swipl -g “set_prolog_flag(unknown,fail),['1.pl','2.pl']."

Другая возможность: определить поддельную процедуру

swipl -g “assert(predicate2(_):-fail),['1.pl','2.pl']."

HTH

0 голосов
/ 15 апреля 2014

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

?- isDuck(Donald) .
! ----------------------------------------
! Error 20 : Predicate Not Defined
! Goal : isDuck(_17610)

Пролог ответит, что ничего не знает о «чем-то» это или не утка. То, что происходит, заключается в том, что логический предикат isDuck/1 не определено (предикат не определен), поэтому пролог не возможность проверить, является ли «что-то» уткой или нет. Как мы увидим позже, даже если Пролог не знает, что такое утка, возможно научите его, как различать, что такое утка, а что нет. Как мы уже говорили ранее, Пролог - это язык диалога. В диалоге между системой и программистом Пролог не только способен ответить на определенные вопросы, но также может узнать о том, что он делает не знаю. Чтобы ответить на вопросы, сформулированные программистом, Пролог проверяет базу знаний, где все прописано, что пролог знает. В начале сеанса Пролога база знаний продолжает базовые знания, которые включают, между прочим, понятия и определения арифметики натуральных чисел. Во время сеанса можно расширить эту базу знаний, включая определения и понятия, с которыми Пролог не знаком (например, определение утка), или также изменение и расширение определений, которые Пролог знает (например, включая новые арифметические операторы для натурального номера). Факты и правила выражают базу знаний. Факты и правила являются синтаксическими представлениями роговых предложений первого порядка. Итак все знание Пролога выражается с использованием (почти) исключительно первого порядок логики. Это причина, почему Пролог называется логикой язык. Программа на Прологе - это набор фактов и правил, которые выражают определенные знания.


...