(1) Все три числа представляются пустыми списками. Тогда
сумма1( [], [], [], 0, 0, Циф, Циф).
(2) Все три числа имеют какую-то самую левую цифру и справа от нее - остальные цифры. То есть, они имеют вид:
[D1 | N1], [D2 | N2], [D | N]
В этом случае должны выполняться два условия:
(а) Оставшиеся цифры, рассматриваемые как три числа N1, N2 и N, сами должны удовлетворять отношению
сумма1
, выдавая влево некоторый перенос C2 и оставляя некоторое
подмножество неиспользованных цифр
Циф2
.
(b) Крайние левые цифры D1, D2 и D, а также перенос C2 должны удовлетворять отношению, показанному на рис. 7.1: C2, D1 и D2 складываются, давая в результате D и перенос влево. Это условие в нашей программе формулируется в виде отношения
. В его определении есть одна тонкая деталь, касающаяся применения металогического предиката
nonvar
. D1, D2 и D должны быть десятичными цифрами. Если хоть одна из этих переменных еще не конкретизирована, ее нужно конкретизировать какой-нибудь цифрой из списка
Циф2
. Как только такая конкретизация произошла, эту цифру нужно удалить из множества доступных цифр. Если D1, D2 и D уже конкретизированы, тогда, конечно, ни одна из доступных цифр "потрачена" не будет. В программе эти действия реализуются при помощи недетерминированного вычеркивания элемента списка. Если этот элемент - не переменная, ничего не вычеркивается (конкретизации не было). Вот эта программа:
удалить( Элемент, Список, Список) :-
nonvar( Элемент), !.
удалить( Элемент, [Элемент | Список ], Список).
удалить(Элемент, [А | Список], [А | Список1]) :-
удалить( Элемент, Список, Список1).
Полная программа для решения арифметических ребусов приводится на рис. 7.2. В программу включены также определения двух ребусов. Вопрос к пролог-системе для ребуса про DONALD'a, GERALD'a и ROBERT'a с использованием этой программы выглядит так:
Иногда этот ребус упрощают, сообщая часть решения в виде дополнительного ограничения, например D равно 5. В такой форме ребус можно передать пролог-системе при помощи
сумма1
:
?- сумма1( [5, O, N, A, L, 5],
[G, E, R, A, L, 5],
[R, O, B, E, R, T],
0, 0, [0, 1, 2, 3, 4, 6, 7, 8, 9], _ ).
Интересно, что в обоих случаях существует только одно решение, т.е. только один способ заменить буквы цифрами.
Упражнения
7.1. Напишите процедуру
упростить
для упрощения алгебраических сумм, в которых участвуют числа и символы (строчные буквы). Пусть эта процедура переупорядочивает слагаемые так, чтобы символы предшествовали числам. Вот примеры ее использования:
?- упростить( 1 + 1 + а, E).
E = а + 2
?- упростить( 1 + a + 4 + 2 + b + с, E).
E = а + b + с + 7
?- упростить( 3 + x + x, E).
E = 2*x + 3
7.2. Определите процедуру
добавить( Элемент, Список)
для добавления нового элемента в список. Предполагается, что все элементы, хранящиеся в списке, — атомы.
Список
состоит из всех хранящихся в нем элементов, а за ними следует хвост, который не конкретизирован и служит для принятия новых элементов. Пусть, например, в списке уже хранятся