解决 PR​​OLOG 中的 Instant Insanity 但我总是得到 "NO"

Solving Instant Insanity in PROLOG but i always get "NO"

我目前正在为 Basic Instant-Insanity 编写求解器。 我的程序一直告诉我 "NO" 因为它找不到解决我的问题的方法,我很困惑地发现失败。谁能给我一些帮助?即使是一个简单的提示就足够了。 非常感谢!

ps: 我正在使用 GNU Prolog 1.4.5

pps : solutionnormal(l) 应该用立方体列表打印 me 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).

不幸的是,我目前不能使用 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).

题外话:我认为 frontdiff/1backdiff/1leftdiff/1rightdiff/1 不需要作为 fd_all_different/1[=23 的别名=]

我好像直接用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

Linux 平台的 SWI-prolog 示例。

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