Prolog检测到列表中的变化

时间:2014-10-21 09:52:58

标签: prolog

我想写一个谓词find_difference([A|B],[P|Q],[C-D|E-F])来查找列表[A|B][P|Q]之间的区别,并给出结果如[C-D|E-F],C表示更改发生在第N个子列表中,而D表示更改发生在该子列表的第N个元素中(每个子列表中的更改只会是一个字符)。 因此查询和预期结果将如下:

find_difference([[a,b,c],[w,t]],[[a,b,d],[w,s]],X).
X=[1-3,2-2].

谓词也可以处理变量吗?例如:

find_difference([[A,B,C],[A,D]],[[A,D,C],[A,S]],X).
X=[1-2,2-2].

提前感谢您提供任何帮助。

find_difference([],[],1).
find_difference([A|B],[C|D],E):-
    (   A=C ->
        find_difference(B,D,Y),
        E is Y+1
    ;   find_difference(B,D,E)
    ).

我现在只能设法获取列表的不同值。但如果两个列表相同,它将会错误地回答。此外,它无法处理变量。

7 ?- find_difference([A,B,C],[A,B,D],X).
C = D,
X = 4.

为什么?

1 个答案:

答案 0 :(得分:0)

这是一个实现:

find_difference(LA, LB, LDiffs):-
  find_difference(LA, LB, 1, 1, LDiffs).

find_difference([], [], _, _, []).
find_difference([[]|LA], [[]|LB], Row, _, LDiffs):-
  succ(Row, NRow),
  find_difference(LA, LB, NRow, 1, LDiffs).
find_difference([[Item|ATail]|LA], [[Item|BTail]|LB], Row, Col, LDiffs):-
  succ(Col, NCol),
  find_difference([ATail|LA], [BTail|LB], Row, NCol, LDiffs).
find_difference([[AItem|ATail]|LA], [[BItem|BTail]|LB], Row, Col, [Row-Col|LDiffs]):-
  AItem\=BItem,
  succ(Col, NCol),
  find_difference([ATail|LA], [BTail|LB], Row, NCol, LDiffs).

您跟踪当前"行"和"列"并检查第一个列表中的每个项目是否与第二个列表中的项目匹配。如果不匹配,请在第三个列表中添加位置。

find_difference / 5的第一个子句是基本情况(第一个和第二个参数上的空列表)。

第二个条款来自一个"行"到下一个。

第三个子句检查第一个和第二个参数中头部列表的第一项是否统一,在这种情况下,您只需增加"列"。

Fourh子句检查它们是否不统一,因此您将当前的Row-Col添加到"输出"列表。

在第三和第四个子句中,您可以递增当前列并继续递归。

示例:

?- find_difference([[a,b,c],[w,t]],[[a,b,d],[w,s]],X).
X = [1-3, 2-2]

您的第二个示例(使用未实例化的变量)不会产生您期望的结果:

?- find_difference([[A,B,C],[A,D]],[[A,D,C],[A,S]],X).
B = S,
D = S,
X = [] ;

因为你可以将S和D与S统一起来做匹配。