Решение мгновенного безумия в PROLOG, но я всегда получаю «НЕТ» - PullRequest
0 голосов
/ 11 января 2020

В настоящее время я пишу Солвер для Баси c Instant-Insanity. Моя программа все время говорит мне «НЕТ», так как она не может найти решение моей проблемы, и я не могу найти ошибку. Кто-нибудь может мне помочь? Даже простой совет может быть достаточно. Большое спасибо!

ps: я использую GNU Prolog 1.4.5

pps: solutionnormal (l) должен напечатать меня l со списком кубов в нем.

   /*
         |   |
         | 3 |
     -----------------
     | 5 | 1 | 6 | 2 |
     -----------------
         |   |
         | 4 |
   numeration of grid faces, for our problem is 1,2,5,6 interesting   
*/
%basecubes
cube(1,[r,w,w,b,r,g]).
cube(2,[r,b,w,g,b,w]).
cube(3,[r,g,b,b,g,w]).
cube(4,[r,r,r,b,w,g]).  

%possible rotations
rotate(S, [X1,X2,X3,X4,X5,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X2,X5,X4,X6,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X2,X6,X4,X1,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X6,X2,X1,X4,X3,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).    
rotate(S, [X6,X1,X4,X5,X3,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X1,X3,X5,X2,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X1,X2,X5,X6,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X1,X6,X5,X4,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X6,X5,X3,X4,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X6,X4,X3,X1,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X6,X1,X3,X2,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X1,X6,X2,X3,X5,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X4,X3,X2,X1,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X4,X1,X2,X6,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X1,X4,X6,X2,X5,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X6,X4,X5,X2,X3,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X6,X5,X2,X1,X3,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X5,X3,X1,X4,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X5,X4,X1,X6,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X5,X6,X1,X2,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X3,X1,X6,X4,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X1,X3,X4,X6,X5,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X3,X5,X6,X2,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X3,X2,X6,X1,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).

%my list
l([cube1,cube2,cube3,cube4]).
%solutionnormal().
solutionnormal([cube1,cube2,cube3,cube4]) :- 
   getfaces([cube1,cube2,cube3,cube4],1,L1), frontdiff(L1),
   getfaces([cube1,cube2,cube3,cube4],2,L2), backdiff(L2),
   getfaces([cube1,cube2,cube3,cube4],5,L5), leftdiff(L5),
   getfaces([cube1,cube2,cube3,cube4],6,L6), rightdiff(L6),
   cube1(1, cube1),
   rotate(2, cube2),
   rotate(3, cube3),
   rotate(4, cube4).
%get a list of faces on this side
getfaces([C1,C2,C3,C4], X, List) :-
   List = [fd_nth(C1, X),fd_nth(C2,X),fd_nth(C3,X),fd_nth(C4,X)].

%all diff for list
frontdiff(L1) :- fd_all_different(L1).

backdiff(L2) :- fd_all_different(L2).

leftdiff(L5) :- fd_all_different(L5).

rightdiff(L6) :- fd_all_different(L6).

1 Ответ

1 голос
/ 11 января 2020

К сожалению, я не могу использовать gprolog в данный момент (это длинная история) ... но мне кажется, что вы должны повернуть кубы раньше, а затем проверить лица.

Я имею в виду. .. что-то вроде

rotate(1, C1), % rotation of cube1 (needed? you can use directly cube1 instead?)
rotate(2, C2), % rotation of cube2
rotate(3, C3), % rotation of cube3
rotate(4, C4), % rotation of cube4
getfaces([C1, C2, C3, C4], 1, L1), frontdiff(L1),
getfaces([C1, C2, C3, C4], 2, L2), backdiff(L2),
getfaces([C1, C2, C3, C4], 5, L5), leftdiff(L5),
getfaces([C1, C2, C3, C4], 6, L6), rightdiff(L6).

Off topi c: я не вижу необходимости в frontdiff/1, backdiff/1, leftdiff/1, rightdiff/1 в качестве псевдонимов fd_all_different/1

Мне кажется, гораздо понятнее использовать fd_all_diff/1 напрямую

rotate(1, C1),
rotate(2, C2),
rotate(3, C3),
rotate(4, C4),
getfaces([C1, C2, C3, C4], 1, L1), fd_all_different(L1),
getfaces([C1, C2, C3, C4], 2, L2), fd_all_different(L2),
getfaces([C1, C2, C3, C4], 5, L5), fd_all_different(L5),
getfaces([C1, C2, C3, C4], 6, L6), fd_all_different(L6).

- РЕДАКТИРОВАТЬ -

Я добавляю полную компиляцию , с помощью следующей команды

swipl --goal=main --stand_alone=true -o test -c test.pl

Пример SWI-пролога для платформы Linux.

Файл test.pl содержит

%:- initialization(main).
:- use_module(library(clpfd)).

%basecubes
cube(1, [1,2,2,3,1,4]).
cube(2, [1,3,2,4,3,2]).
cube(3, [1,4,3,3,4,2]).
cube(4, [1,1,1,3,2,4]).  

%possible rotations
rotate(S, [X1,X2,X3,X4,X5,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X2,X5,X4,X6,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X2,X6,X4,X1,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X6,X2,X1,X4,X3,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).    
rotate(S, [X6,X1,X4,X5,X3,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X1,X3,X5,X2,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X1,X2,X5,X6,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X1,X6,X5,X4,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X6,X5,X3,X4,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X6,X4,X3,X1,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X6,X1,X3,X2,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X1,X6,X2,X3,X5,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X4,X3,X2,X1,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X4,X1,X2,X6,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X1,X4,X6,X2,X5,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X6,X4,X5,X2,X3,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X6,X5,X2,X1,X3,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X5,X3,X1,X4,X6]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X3,X5,X4,X1,X6,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X5,X6,X1,X2,X3]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X2,X3,X1,X6,X4,X5]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X1,X3,X4,X6,X5,X2]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X4,X3,X5,X6,X2,X1]) :- cube(S, [X1,X2,X3,X4,X5,X6]).
rotate(S, [X5,X3,X2,X6,X1,X4]) :- cube(S, [X1,X2,X3,X4,X5,X6]).

%get a list of faces on this side
getfaces([C1, C2, C3, C4], X, [Y1, Y2, Y3, Y4]) :-
  nth1(X, C1, Y1), nth1(X, C2, Y2), nth1(X, C3, Y3), nth1(X, C4, Y4).

main :-
  rotate(1, C1), rotate(2, C2), rotate(3, C3), rotate(4, C4),
  getfaces([C1, C2, C3, C4], 1, L1), all_distinct(L1),
  getfaces([C1, C2, C3, C4], 2, L2), all_distinct(L2),
  getfaces([C1, C2, C3, C4], 5, L5), all_distinct(L5),
  getfaces([C1, C2, C3, C4], 6, L6), all_distinct(L6),
  writeln(L1), writeln(L2), writeln(L5), writeln(L6),
  writeln("ok"),
  halt(0).

main :-
  halt(1).

и вывод, выполнение ./test,

[4,3,2,1]
[2,3,4,1]
[2,1,3,4]
[1,2,4,3]
ok
...