Управление перебором. Отсечение
Упражнение 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. Максимум