I'm trying to work on an assignment, however am really stuck on this section. What I need to do is write a predicate called matching with three parameters, all lists. The third list must contain the index of the positions in which the first two lists contain the same value. I really don't know where to start on this so any help would be much appreciated!
答案 0 :(得分:2)
第三个列表必须包含前两个列表包含相同值的位置的索引。
首先重要的是:
第三个列表必须包含前两个列表包含相同值的位置索引。
使用统一。作为谓词:
same_value(X, X).
第三个列表必须包含前两个列表包含相同值的位置索引。
lists_same_value([X|_], [Y|_]) :- same_value(X, Y). % succeed
lists_same_value([_|Xs], [_|Ys]) :- % skip head
lists_same_value(Xs, Ys). % recursive definition
简化并统一:
lists_same_value([X|_], [X|_]). % succeed
lists_same_value([_|Xs], [_|Ys]) :- % skip head element
lists_same_value(Xs, Ys). % recursive definition
第三个列表必须包含前两个列表包含相同值的位置的索引。
为当前索引添加累加器,当磁头是相同的元素时成功,并查看列表的其余部分。
lists_same_value_index([X|_], [X|_], N, N). % succeed
lists_same_value_index([_|Xs], [_|Ys], N0, N) :- % skip head element
succ(N0, N1), % next index
lists_same_value_index(Xs, Ys, N1, N). % recursive definition
实例化累加器:
lists_same_value_index(Xs, Ys, N) :-
lists_same_value_index(Xs, Ys, 0, N).
与bagof
一起使用以查找所有解决方案:
?- bagof(N, lists_same_value_index([a,b,c,a,c,d,c], [a,c,c,a,d,d,c], N), Ns).
Ns = [0, 2, 3, 5, 6].
并且这与当然有两个nth0
的解决方案不同,请参阅:
?- numlist(1, 100, L), time( bagof(N, lists_same_value_index(L, L, N), Ns) ).
% 314 inferences, 0.000 CPU in 0.000 seconds (98% CPU, 1785481 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Ns = [0, 1, 2, 3, 4, 5, 6, 7, 8|...].
?- numlist(1, 100000, L), time( bagof(N, lists_same_value_index(L, L, N), Ns) ).
% 300,014 inferences, 0.052 CPU in 0.052 seconds (100% CPU, 5765387 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Ns = [0, 1, 2, 3, 4, 5, 6, 7, 8|...].
然后使用nth0
:
?- numlist(1, 100, L), time( findall(N, ( nth0(N, L, E), nth0(N, L, E) ), Ns) ).
% 2,181 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 3329847 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Ns = [0, 1, 2, 3, 4, 5, 6, 7, 8|...].
?- numlist(1, 100000, L), time( findall(N, ( nth0(N, L, E), nth0(N, L, E) ), Ns) ).
% 1,667,166,681 inferences, 151.139 CPU in 151.244 seconds (100% CPU, 11030703 Lips)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Ns = [0, 1, 2, 3, 4, 5, 6, 7, 8|...].
答案 1 :(得分:1)
正如@Capellic建议您可以使用findall / 3和nth1 / 3谓词:
common_elemnts_pos(L1,L2,Pos):-
findall(X, (nth0(X,L1,Elem), nth0(X, L2, Elem)) , Pos).
上面简单地说找到所有位置X,L1中的元素是Elem,L2中的元素是Elem,所以具有相同的元素。
示例:
?- common_elemnts_pos([1,3,4,5,7,9],[1,2,4,5,8,9],Pos).
Pos = [0, 2, 3, 5].
执行纯粹的递归解决方案也很容易:
common_elemnts_pos(L1,L2,Pos):- common_elemnts_pos(L1,L2,Pos,0).
common_elemnts_pos([],_,[],_).
common_elemnts_pos(_,[],[],_).
common_elemnts_pos([H|T],[H|T1],[CurrentPos|T2],CurrentPos):-
N_CurrentPos is CurrentPos+1,
common_elemnts_pos(T,T1,T2,N_CurrentPos).
common_elemnts_pos([H|T],[H1|T1],T2,CurrentPos):-
dif(H,H1), N_CurrentPos is CurrentPos+1,
common_elemnts_pos(T,T1,T2,N_CurrentPos).
示例:
?- common_elemnts_pos([1,3,4,5,7,9],[1,2,4,5,8,9],Pos).
Pos = [0, 2, 3, 5] ;
Pos = [0, 2, 3, 5] ;
false.
?- common_elemnts_pos([1,3,4,5,7,9],[1,2,4,5,8,9],Pos).
Pos = [0, 2, 3, 5] ;
false.
在上面的第一个测试中有两个相同的解决方案,因为两个基本情况都是有效的。如果你只想要一个,你可以替换:
common_elemnts_pos([],_,[],_).
common_elemnts_pos(_,[],[],_).
基础案例:
common_elemnts_pos([],[_|_],[],_).
common_elemnts_pos(_,[],[],_).