在prolog中排除tuples_in列表

Vik*_*kat 5 prolog clpfd

这就是问题所在:16个孩子将坐在一个4 x 4的椅子上.孩子是8个女孩(编号为1..8)和8个男孩(编号为9..16).1,3,5,8认为男孩是令人讨厌的9,10,11,14认为女孩是粗暴这些对是敌人:[[1,2],[4,6],[4,7],[4,9 ],[9,11],[12,14],[14,16]]

找到两个孩子不是敌人的谓词定义为:

not_enemy(A, B) :-
    NotA #\= A #\/ NotB #\= B,
    tuples_in([[NotA, NotB]],
              [[1,2], [4,6], [4,7], [4, 9],[9,11], [12, 14], [14,16]]).
Run Code Online (Sandbox Code Playgroud)

上面的代码在这里找到

但是当我查询? - not_enemy(1,2)时输出为真.

我必须使用这个长代码:

not_enemy(A, B) :-
          A #=1 #==> B #\= 2,
          A #=4 #==> B #\= 6,
          A #=4 #==> B #\= 7,
          A #=4 #==> B #\= 9,
          A #=9 #==> B #\= 11,
          A #=12 #==> B #\= 14,
          A #=14 #==> B #\= 16.
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙纠正第一段代码吗?提前致谢.

Cap*_*liC 6

我会优化你的代码,只是为了使它成为通用的

not_enemy(A, B) :-
    maplist(not_enemy(A,B), [[1,2], [4,6], [4,7], [4,9], [9,11], [12,14], [14,16]]).
not_enemy(A,B,[X,Y]) :-
    X #= A #==> Y #\= B.
Run Code Online (Sandbox Code Playgroud)

我找不到合适的方法来使用tuples_in来解决这个问题.


Vik*_*kat 3

我找到了另一个答案,而不是使用这个

not_enemy(A, B) :-
    NotA #\= A #\/ NotB #\= B,
    tuples_in([[NotA, NotB]],
              [[1,2], [4,6], [4,7], [4, 9],[9,11], [12, 14], [14,16]]).
Run Code Online (Sandbox Code Playgroud)

只需用 #\ 来否定 tuples_in

not_enemy(A, B) :-
    #\ tuples_in([[A,B]],
                 [[1,2], [4,6], [4,7], [4, 9],[9,11], [12, 14], [14,16]]).
Run Code Online (Sandbox Code Playgroud)

  • 我检查了文档,如果经过进一步调查,您的答案是正确的,我将在 clpfd 文档上提交错误报告 (3认同)