top-shop.ru
Sexy Hair Спрей
Поддержка списков в Прологе

Решение головоломки SEND MORE MONEY, на Прологе

Пролог систему поддерживают механизмы списков - перечислений некоторых значений. Ниже приведено использование списка для решения ребуса "Send More Money". Решения "лобового", и не самого эффективного. Программа достаточно хороша потому, что решает поставленную задачу, хоть и с минимальной эффективностью: smm_1.pl - это журнал моего изучения Пролога
 
digit(X) :- member(X,[0,1,2,3,4,5,6,7,8,9]).

res(S, E, N, D, M, O, R, Y) :- digit(S), digit(E), digit(N), digit(D), digit(M), digit(O), digit(R), digit(Y), 1 =:= M, 0 =:= 10000*M + 1000*O + 100*N + 10*E + Y - 1000*S - 100*E - 10*N - D - 1000*M - 100*O - 10*R - E.


Мне было интересно хотя бы потому, что подтвердилось мое мнение о том, что в цифровом виде ребус удовлетворяет множеству решений. Что интереснее, их оказалось 155 штук (что уже не столь очевидно).
 SEND
+MORE
-----
MONEY
 9000
+1000
-----
10000
Здесь используется предикат member, позволяющий проверить значение переменной на предмет его наличия в списке.
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- ['smm_1'].
compiling E:\Prolog\Program\G1\smm_1.pl for byte code...
E:\Prolog\Program\G1\smm_1.pl compiled, 3 lines read - 3297 bytes written, 20 ms

yes
| ?- res(S, E, N, D, M, O, R, Y).

D = 0
E = 0
M = 1
N = 0
O = 0
R = 0
S = 9
Y = 0 ? 
Головоломку можно решить с помощью аналогичной программы smm_2.pl:
digit(0).
digit(1).
digit(2).
digit(3).
digit(4).
digit(5).
digit(6).
digit(7).
digit(8).
digit(9).

res(S, E, N, D, M, O, R, Y) :- 
digit(S), digit(E), digit(N), digit(D), digit(M), digit(O), digit(R), digit(Y), 
1 =:= M, 
0 =:= 10000*M + 1000*O + 100*N + 10*E + Y - 1000*S - 100*E - 10*N - D - 1000*M - 100*O - 10*R - E.
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- [smm_2].
compiling Z:\MyProject\prolog\smm_2.pl for byte code...
Z:\MyProject\prolog\smm_2.pl compiled, 15 lines read - 3338 bytes written, 140 ms

yes
| ?- res(S, E, N, D, M, O, R, Y).

D = 0
E = 0
M = 1
N = 0
O = 0
R = 0
S = 9
Y = 0 ? 

Проверки типов

В Прологе данные назваются "Термами", набор встроенных "типовых" предикатов Пролога позволяет проверять: является ли он составным (compound) или простым (atomic), а в последнем случае атом ли это (atom) или число (number), причем целое ли это число (integer) или вещественное (float).
var(Term)
Истина, ели Term - свободная переменная (еще не конкретизированная).
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- X = 1, var(X).

no
| ?- var(X).

yes
| ?- 
nonvar(Term)
Истина, ели Term - не свободная переменная (уже конкретизированная).
| ?- X = 1, nonvar(X).

X = 1

yes
| ?- nonvar(X).

no
| ?- 
atom(Term)
Истина, ели Term - атом.
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- atom(like).

yes
| ?- atom([1,2]).

no
| ?- 
integer(Term)
Истина, если Term конкретезирован целым числом.
| ?- integer(1).

yes
| ?- X = 1, integer(X).

X = 1

yes
| ?- integer(1.2).

no
| ?- integer(X).

no
| ?- X = sm. integer(X).

X = sm

yes

no
| ?- 
float(Term)
Истина, если Term конкретезирован вещественным числом.
| ?- random(X), float(X).

X = 0.001251220703125

yes
| ?- 
number(Term)
Истина, если Term конкретезирован вещественным или целым числом.
compound(Term)
Истина, если Term имеет арность больше нуля, т.е. это список или структура.
callable(Term)
Истина, если Term atom или compound.
list(Term)
Истина, если Term - список (пустой или нет).
Блог изучающего Пролог

содержание