我想写一个谓词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.
为什么?
答案 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统一起来做匹配。