Бертран Рассел Пазл
Решите следующую проблему Калибана, переведя каждую подсказку "лояльно" на Пролог, то есть максимально лояльно.
В качестве простого упражнения в абстракции предположим, что четыре бессмысленных символа a, b, c и d соответствуют в той или иной последовательности одинаково бессмысленным символам w, x, y и z, и предположим далее, что
Если а не х, то с не у.
Если b равно y или z, то a равно x.
Если c не является w, то b является z.
Если d есть у, то b не х.
Если d не х, то б х.В каком порядке соответствуют два набора символов?
Я попробовал следующий код:
vban(L) :-
L=[[a,C1],[b,C2],[c,C3],[d,C4]],
( member(C1,[w,y,z]) -> member(C3,[w,x,z])),
( member(C2,[y,z]) -> member(C1,[x])),
( member(C3,[x,y,z]) -> member(C2,[z])),
( member(C4,[y]) -> member(C2,[w,y,z])),
( member(C4,[w,y,z]) -> member(C2,[x])).
Но это показывает неудачу. Любая помощь будет оценена.
3 ответа
Использование CLP(B) в SICStus Prolog или SWI:
:- use_module(library(clpb)).
:- use_module(library(lists)).
:- use_module(library(clpfd)).
corresponding(Matrix) :-
Matrix = [[ _,AX, _, _],
[ _,BX,BY,BZ],
[CW, _,CY, _],
[ _,DX,DY, _]],
maplist(card1, Matrix),
transpose(Matrix, TMatrix),
maplist(card1, TMatrix),
sat(~AX =< ~CY),
sat(BY + BZ =< AX),
sat(~CW =< BZ),
sat(DY =< ~BX),
sat(~DX =< BX).
card1(Vs) :- sat(card([1], Vs)).
Пример запроса:
?- corresponding(Vs),
pairs_keys_values(Pairs, [t,a,b,c,d], [[w,x,y,z]|Vs]),
maplist(writeln, Pairs).
Уступая (1
обозначает соответствующие элементы):
t-[w,x,y,z]
a-[0,0,1,0]
b-[0,1,0,0]
c-[1,0,0,0]
d-[0,0,0,1]
и привязки для Vs
а также Pairs
,
Мне нравится решение Мата, но для решения проблемы мы можем написать логические выражения с "и" и "или".
a, b, c и d могут обозначаться символами [0,0], [0,1], [1,0] и [1,1].
Два числа M и N равны, если (M1 = N1 и M2 = N2)
Два числа являются разными, если (M1 \= N1) или (M2 \= N2) (или нет (равно))
Импликация u => v переводится в not (u) или v
Итак, мы получаем:
:- use_module(library(clpb)).
:- use_module(library(lambda)).
or(A,B,A+B).
and(A,B,A*B).
% two numbers are equal
equal(A, B, Eq) :-
foldl(\X^Y^Z^T^and(Z, (X =:= Y), T), A, B, 1, Eq).
% two numbers are different
different(A, B, Diff) :-
equal(A,B,Eq),
Diff = ~Eq.
% foldl(\X^Y^Z^T^or(Z, (X =\= Y), T), A, B, 0, Diff).
puzzle :-
A = [0,0],
B = [0,1],
C = [1,0],
D = [1,1],
W = [_,_],
X = [_,_],
Y = [_,_],
Z = [_,_],
% If a is not x, then c is not y.
% (a is x) or (c is not y)
equal(A, X, Eq1),
different(C, Y, Di1),
or(Eq1, Di1, P1),
% If b is either y or z, then a is x.
% (b is not y) and (b is not z) or (a is x)
different(B, Y, Di2),
different(B, Z, Di3),
equal(A, X, Eq2),
and(Di2, Di3, P2),
or(Eq2, P2, P3),
% If c is not w, then b is z.
% (c is w) or (b is z)
equal(C, W, Eq3),
equal(B, Z, Eq4),
or(Eq3, Eq4, P4),
% If d is y, then b is not x.
% (d is not y) or (b is not x)
different(D, Y, Di4),
different(B, X, Di5),
or(Di4, Di5, P5),
% If d is not x, then b is x.
%(d is x) or (b is x)
equal(D, X, Eq5),
equal(B, X, Eq6),
or(Eq5, Eq6, P6),
% we must express that W,X,Y,Z are differents
% W is different from X, Y, Z
foldl(W +\R^S^T^(different(W, R, U),
and(S, U, T)),
[X,Y,Z], 1, Dif1),
% X is different from Y, Z
foldl(X +\R^S^T^(different(X, R, U),
and(S, U, T)),
[Y,Z], 1, Dif2),
% Y is different from Z
different(Y, Z, Dif3),
% now we join all these expressions with an and
Expr = *([P1,P3,P4,P5,P6, Dif1,Dif2, Dif3]),
% we ask Prolog to count the number of solutions
sat_count(Expr, N),
writeln(N : ' solution(s)'),
% we ask Prolog to satisfy the expr
sat(Expr),
maplist(writeln, [A, B, C, D]), nl,
maplist(writeln, [W, X, Y, Z]).
Мы получаем:
?- puzzle.
1: solution(s)
[0,0]
[0,1]
[1,0]
[1,1]
[1,0]
[0,1]
[0,0]
[1,1]
true.
Прямой перевод постановки задачи в ECLiPSe Prolog с библиотекой программирования ограничений ic_symbolic:
:- lib(ic).
:- lib(ic_symbolic).
:- local domain(symbol(w,x,y,z)).
russel(A, B, C, D) :-
[A, B, C, D] &:: symbol,
(A &\= x) => (C &\= y),
(B &= y or B &= z) => (A &= x),
(C &\= w) => (B &= z),
(D &= y) => (B &\= x),
(D &\= x) => (B &= x),
ic_symbolic:alldifferent([A, B, C, D]),
ic_symbolic:indomain(A),
ic_symbolic:indomain(B),
ic_symbolic:indomain(C),
ic_symbolic:indomain(D).
Решение:
[eclipse]: russel(A,B,C,D).
A = y
B = x
C = w
D = z
Yes