Управление перебором. Отсечение
Упражнение 3. Измените программу так, чтобы кроме решения она выводила цвет шкатулки, на которых оба высказывания истинны, цвет шкатулки, на которой оба высказывания ложны, и цвет шкатулки, на которой одно высказывание истинно, а другое ложно.
В приведенной ниже программе описываются сведения, полученные в процессе расследования убийства [2, 7, 16]. Не рекомендуется запускать программу без ее предварительного изучения.
domains
sex = m; f.
class facts
person: (symbol Name, integer Age, sex, symbol Occupation).
had_affair: (symbol Name, symbol Name).
killed_with: (symbol Name, symbol Object).
killed: (symbol Name).
motive: (symbol Vice).
smeared_in: (symbol Name, symbol Substance).
owns: (symbol Name, symbol Object).
operates_identically: (symbol Object, symbol Object).
class predicates
owns_probably: (symbol Name, symbol Object) nondeterm.
suspect: (symbol Name) nondeterm.
killer: (symbol Name) nondeterm (o).
% Facts about the murder
clauses
person("Allan", 25, m, "football player").
person("Allain", 35, m, "butcher").
person("John", 30, m, "pickpocket").
person("Bert", 55, m, "carpenter").
person("Barbara", 30, f, "hairdresser").
had_affair("Barbara", "John").
had_affair("Barbara", "Bert").
had_affair("Susan", "John").
killed_with("Susan", "club").
killed("Susan").
motive("money").
motive("jealousy").
motive("righteousness").
smeared_in("Susan", "blood").
smeared_in("Allan", "mud").
smeared_in("Allain", "blood").
smeared_in("John", "chocolate").
smeared_in("Barbara", "chocolate").
smeared_in("Bert", "blood").
owns("Bert", "wooden leg").
owns("John", "pistol").
% Background knowledge
operates_identically("wooden leg", "club").
operates_identically("bar", "club").
operates_identically("pair of scissors", "knife").
operates_identically("football boot", "club").
owns_probably(X, "football boot"):-
person(X, _, _, "football player").
owns_probably(X, "pair of scissors"):-
person(X, _, _, "hairdresser").
owns_probably(X, "knife"):-
person(X, _, _, "butcher").
owns_probably(X, Object):-
owns(X, Object).
% Suspect all those who own a weapon
% with which Susan could have been killed.
suspect(X):-
killed(Woman),
killed_with(Woman, Weapon),
operates_identically(Object, Weapon),
owns_probably(X, Object).
% Suspect men who have had an affair with Susan.
suspect(X):-
motive("jealousy"),
person(X, _, m, _),
killed(Woman),
had_affair(Woman, X).
% Suspect females who have had an affair
% with someone that Susan knew.
suspect(X):-
motive("jealousy"),
person(X, _, f, _),
had_affair(X, Man),
killed(Woman),
had_affair(Woman, Man).
% Suspect pickpockets whose motive could be money.
suspect(X):-
motive("money"),
person(X, _, _, "pickpocket").
killer(Killer):-
person(Killer, _, _, _),
killed(Killed),
Killed <> Killer, % It is not a suicide
suspect(Killer),
smeared_in(Killer, Goo),
smeared_in(Killed, Goo).
run():-
killer(Killer),
write("Killer is ", Killer), nl,
fail;
_ = readLine().
Пример
3.3.
"Кто убийца?"
Упражнение 4. Прочитайте программу "Кто убийца?" (см. листинг 3.3), опишите сюжет драмы и, не запуская программу, для каждого участника описанных событий выясните, является ли он убийцей. Ответ подробно обоснуйте.
Ниже рассматриваются три способа определения максимума двух чисел: без отсечений, с зеленым отсечением и с красным отсечением (см. листинг 3.4). На рис. 3.1 (a) и (b) показаны деревья поиска для предиката maximum1, в определении которого нет отсечений.
Дерево поиска для предиката maximum2, в определении которого используется зеленое отсечение, сокращается в случае, когда значение первого аргумента не меньше, чем значение второго (рис. 3.2 (a)). Дерево поиска для предиката maximum, в определении которого имеется красное отсечение, сокращается и в случае, когда значение первого аргумента меньше значения второго (рис. 3.2 (b)).
На практике обычно используется красное отсечение, которое позволяет существенно сократить вычисления.
class predicates
maximum1: (integer, integer, integer [out]) nondeterm.
maximum2: (integer, integer, integer [out]) determ.
maximum: (integer, integer, integer [out]).
clauses
maximum1(X, Y, X):- X >= Y. % вариант без отсечений
maximum1(X, Y, Y):- X < Y.
maximum2(X, Y, X):- X >= Y, !. % зеленое отсечение
maximum2(X, Y, Y):- X < Y.
maximum(X, Y, X):- X >= Y, !. % красное отсечение
maximum(_, Y, Y).
run():-
maximum1(3, 7, M), % maximum1(7, 3, M),
write(M), nl,
fail;
maximum2(3, 7, M),
write(M), nl,
fail;
maximum(3, 7, M),
write(M),
_ = readLine().
Пример
3.4.
Максимум

