创建Domino列表

时间:2018-12-20 23:09:19

标签: prolog

我正在尝试获取DominoDomino列表的排序列表

我的代码当前如下所示:

listdomino(_,[],[],[]).    
listdomino([I,J],M,Start,Fin):-
    (( member([J,K],M),
       delete(M,[J,K],M2),
       append([[J,K]],Fin1,Fin),
       listdomino([I,K],M2,Start,Fin1)
     )
   ;
    ( member([K,I],M),
      delete(M,[K,I],M2),
      append(Start1,[[K,I]],Start),
      listdomino([K,J],M2,Start1,Fin)
    )
   ).

listdominoSorted(X,M,Out):-
    append(Start,[X],K),
    append(K,Fin,Out),
    listdomino(X,M,Start,Fin).

实际结果:

?- listdominoSorted([1,2],[[2,1],[2,2]],L).
L = [[1, 2], [2, 2], [2, 1]] ;
L = [[2, 1], [1, 2], [2, 2]] ;
L = [[2, 1], [1, 2], [2, 2]] ;
L = [[2, 2], [2, 1], [1, 2]] ;

程序两次返回[[2, 1], [1, 2], [2, 2]] 并且在那之后不会退出。

所需结果:

?- listdominoSorted([1,2],[[2,1],[2,2]],L).
L = [[1, 2], [2, 2], [2, 1]] ;
L = [[2, 1], [1, 2], [2, 2]] ;
L = [[2, 2], [2, 1], [1, 2]] ;
false

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我看了一两分钟的代码,但看到使用delete/3后,警告铃响了,我看了其他示例。尽管与此相关的answer不能回答您的问题,但声明

  

我建议快速检查其有效性,然后让Prolog算出插入点。

带领我尝试一种Prolog非常适合的generate and test方法。

首先测试:

没有多米诺骨牌有效。

domino_test([]).

一个多米诺骨牌有效。

domino_test([[_,_]]).

两个多米诺骨牌共享相同的计数(D_1)时,它们才有效。 这是递归有效的。

domino_test([[_,D_1],[D_1,D_2]|T]) :-
  domino_test([[D_1,D_2]|T]).

下一步生成值。 这实际上只是多米诺骨牌的排列。

?- permutation([[1,2],[2,1],[2,2]],P).
P = [[1, 2], [2, 1], [2, 2]] ;
P = [[1, 2], [2, 2], [2, 1]] ;
P = [[2, 1], [1, 2], [2, 2]] ;
P = [[2, 1], [2, 2], [1, 2]] ;
P = [[2, 2], [1, 2], [2, 1]] ;
P = [[2, 2], [2, 1], [1, 2]] ;
false.

将置换与测试一起放入一个谓词中:

list_domino(L,P) :-
  permutation(L,P),
  domino_test(P).

所有代码

domino_test([]).

domino_test([[_,_]]).

domino_test([[_,D_1],[D_1,D_2]|T]) :-
  domino_test([[D_1,D_2]|T]).

list_domino(L,P) :-
  permutation(L,P),
  domino_test(P).

示例:

?- list_domino([[1,2],[2,1],[2,2]],P).
P = [[1, 2], [2, 2], [2, 1]] ;
P = [[2, 1], [1, 2], [2, 2]] ;
P = [[2, 2], [2, 1], [1, 2]] ;
false.

我怀疑您给定的测试用例是一个简单的用例,需要对此做一些修改,但是我会让您检查一下。