Сложные логические выражения в прологе - PullRequest
4 голосов
/ 21 января 2012

В Прологе, как реализовать сложные логические предикаты, такие как (А и В) или (С и D)?

Это может показаться простым вопросом, но многие доступные онлайн-учебные пособия недостаточно детальны для логических выражений. Я полагаю, вы не можете просто написать:

test(A, B, C, D) :- cond(A), cond(B); cond(C), cond(D).

так как бы вы это сделали?

Ответы [ 3 ]

20 голосов
/ 23 января 2012

Как отмечали другие, ваш исходный пример

test(A, B, C, D) :- cond(A), cond(B); cond(C), cond(D).

является абсолютно верным (при условии, что синтаксический анализ соответствует вашим ожиданиям).Разве вы не пробовали это?

Учебник для начинающих

Логический И

foo :- a , b .

Логический ИЛИ

foo :- a ; b .

Комбинированный

foo :- a , b ; c , d .

Вышеуказанные синтаксические разборы как:

foo :- ( a , b ) ; ( c , d ) .

Используйте скобки, чтобы указать другое желаемое связывание:

foo :- a , ( b ; c ) , d .

Еще лучше, исключите оператор ; ИЛИ и разбейте альтернативы на отдельные предложения.Последовательность гораздо проще для понимания людьми, чем ветвящиеся древовидные структуры.Разбиение чередования на несколько предложений упрощает тестирование / отладку и улучшает понимание.Поэтому предпочитайте

foo :- a , b .
foo :- c , d .

, а не

foo :- a , b ; c , d .

и

foo :- a , bar , d .

bar :- b .
bar :- c .

, а не

foo :- a , ( b ; c ) , d .

Возможно, самое главное, разбить вещив несколько подобных разделов облегчает последующее обслуживание.С такой структурой, как:

foo :- a , b ; c , d .

Что вы делаете, когда добавляете еще одно дело?Как насчет того, чтобы расширить до 50 альтернатив?

Каждая дополнительная альтернатива увеличивает число путей кода в предложении, что затрудняет тестирование и понимание.Чтобы получить полное покрытие кода при тестировании, необходимо протестировать множество альтернативных путей.

С эквивалентной структурой

foo :- a , b .
foo :- c , d .

Добавление альтернатив - это просто вопрос добавления дополнительного предложения или предложений,каждый из которых может быть проверен отдельно.

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

1 голос
/ 21 января 2012

Простая альтернатива для союзов - это использование подстанций.Для дизъюнкций используйте несколько строк.Ваш пример:

test(A, B, C, D) :- test1(A, B).
test(A, B, C, D) :- test2(C, D).
test1(A, B) :- A, B.
test2(C, D) :- C, D.

А как насчет (A или B) и (C или D)?

other(A, B, C, D) :- other1(A, B), other2(C, D).
other1(A, B) :- A.
other1(A, B) :- B.
other2(C, D) :- C.
other2(C, D) :- D.

Обратите внимание, что это упоминается только как альтернатива ответу joel76.

0 голосов
/ 21 января 2012

тест (A, B, C, D): - (cond (A), cond (B)); (конд (С), конд (D)).

...