使用Prolog在网格中的同一行和同一列中查找重复项

使用Prolog在网格中的同一行和同一列中查找重复项,prolog,Prolog,我不熟悉Prolog。我正在编写Prolog代码来解决一个难题,这个难题需要我在二维数字网格中找到重复的数字 我的输入类似于: grid(1,1,1). grid(2,1,2). grid(2,1,3). grid(5,1,4). grid(3,2,1). grid(4,2,2). grid(5,2,3). grid(9,2,4). grid(6,3,1). grid(7,3,2). grid(2,3,3). grid(8,3,4). grid(4,4,1). grid(5,4,2). grid

我不熟悉Prolog。我正在编写Prolog代码来解决一个难题,这个难题需要我在二维数字网格中找到重复的数字


我的输入类似于:

grid(1,1,1).
grid(2,1,2).
grid(2,1,3).
grid(5,1,4).
grid(3,2,1).
grid(4,2,2).
grid(5,2,3).
grid(9,2,4).
grid(6,3,1).
grid(7,3,2).
grid(2,3,3).
grid(8,3,4).
grid(4,4,1).
grid(5,4,2).
grid(1,4,3).
grid(3,4,4).
finddup(N,X,Y):-
        a is X, b is Y,
        print('Rule 1 \n'),
        ((grid(N,U,1), U \= a, print('U->'), write(U), print('\n'), print('X->'), write(a));
        (grid(N,1,U), U \= b, print('U->'), write(U), print('\n'), print('Y->'), write(b));
        (grid(N,U,4), U \= a, print('U->'), write(U), print('\n'), print('X->'), write(a));
        grid(N,4,U), U \= b, print('U->'), write(U), print('\n'), print('Y->'), write(b)));
        print('Rule 2 \n'),
        ((finddup(N,X-1,Y), X-1 >= 1, X-1 =< 4, Y >= 1, Y =< 4);
        (finddup(N,X+1,Y), X+1 >= 1, X+1 =< 4, Y >= 1, Y =< 4);
        (finddup(N,X,Y-1), X >= 1, X =< 4, Y-1 >= 1, Y-1 =< 4);
        (finddup(N,X,Y+1), X >= 1, X =< 4, Y+1 >= 1, Y+1 =< 4)).

表示矩阵的:

1 2 2 5
3 4 5 9
6 7 2 8
4 5 1 3

我尝试的代码类似于:

grid(1,1,1).
grid(2,1,2).
grid(2,1,3).
grid(5,1,4).
grid(3,2,1).
grid(4,2,2).
grid(5,2,3).
grid(9,2,4).
grid(6,3,1).
grid(7,3,2).
grid(2,3,3).
grid(8,3,4).
grid(4,4,1).
grid(5,4,2).
grid(1,4,3).
grid(3,4,4).
finddup(N,X,Y):-
        a is X, b is Y,
        print('Rule 1 \n'),
        ((grid(N,U,1), U \= a, print('U->'), write(U), print('\n'), print('X->'), write(a));
        (grid(N,1,U), U \= b, print('U->'), write(U), print('\n'), print('Y->'), write(b));
        (grid(N,U,4), U \= a, print('U->'), write(U), print('\n'), print('X->'), write(a));
        grid(N,4,U), U \= b, print('U->'), write(U), print('\n'), print('Y->'), write(b)));
        print('Rule 2 \n'),
        ((finddup(N,X-1,Y), X-1 >= 1, X-1 =< 4, Y >= 1, Y =< 4);
        (finddup(N,X+1,Y), X+1 >= 1, X+1 =< 4, Y >= 1, Y =< 4);
        (finddup(N,X,Y-1), X >= 1, X =< 4, Y-1 >= 1, Y-1 =< 4);
        (finddup(N,X,Y+1), X >= 1, X =< 4, Y+1 >= 1, Y+1 =< 4)).
finddup(N,X,Y):-
a是X,b是Y,
打印(“规则1\n”),
((网格(N,U,1),U\=a,print('U->')、write(U)、print('\N')、print('X->')、write(a));
(网格(N,1,U),U\=b,print('U->')、write(U)、print('\N')、print('Y->')、write(b));
(网格(N,U,4),U\=a,print('U->')、write(U)、print('\N')、print('X->')、write(a));
网格(N,4,U),U\=b,print('U->'),write(U),print('\N'),print('Y->'),write(b));
打印(“规则2\n”),
((finddup(N,X-1,Y),X-1>=1,X-1=<4,Y>=1,Y=<4);
(finddup(N,X+1,Y),X+1>=1,X+1=<4,Y>=1,Y=<4);
(finddup(N,X,Y-1),X>=1,X=<4,Y-1>=1,Y-1=<4);
(finddup(N,X,Y+1),X>=1,X=<4,Y+1>=1,Y+1=<4))。

请帮帮我,伙计们。。。我已经试了一两周了


谢谢,

Vikas

您不需要尝试指定行和列索引的范围,因为它们已经在网格(..)事实中明确给出。让Prolog回溯这些值

finddup(N,R,C) :-
    grid(N,R,C),
    grid(N,R,C2), C \= C2,
    grid(N,R2,C), R \= R2.
网格(N,R,C)
将验证给定值是否在网格中,或者如果N,R,C的任何(或全部)没有值,它将回溯所有可能的组合

网格(N,R,C2),C\=C2,
将在同一行中找到另一个具有相同N的列

同样,对于
网格(N,R2,C),R\=R2
——但对于另一行

对于找到的任何重复项,这将返回true,但之后可能返回false,因为最后一次回溯可能失败。例如:

?- finddup(N,R,C).
N = 2,
R = 1,
C = 3 ;
false.

?- finddup(2,1,3).
true ;
false.

?- 
(其中分号为用户输入)

在找到解决方案后,可以在末尾添加切口以停止任何进一步的回溯:

finddup(N,R,C) :-
    grid(N,R,C),
    grid(N,R,C2), C \= C2,
    grid(N,R2,C), R \= R2, !.
给予


我不明白。矩阵由第一列表示,对吗?其他栏目是干什么的?什么叫复制?您对输入示例的期望是什么?我的i/p是上述规则中所述的网格。如果我查询finddup(1,1,1),我的o/p应该是这样的。应该返回false。。。类似的finddup(2,1,3)。必须返回TRUE,因为在同一行和列(网格(2,1,2)和网格(2,3,3)中出现另一个2。也许你想重新表述一下你的问题。为什么要检测重复项?我怀疑你最终想将矩阵视为一个大术语。@Vikas Upendra:如果Nick回答了你的问题,别忘了接受他的回答。或者,如果有什么问题仍未解决,请留下评论。