试图确定列表中的两个数字是否等于给定值。
我已经阅读了swi-prolog文档中的许多问题和大多数list.pl。我可以确定如何确定列表中所有项目的总和是否等于给定值,但是不知道是否有两个项目等于给定值。
sum([ ],0). %Pretty sure this makes the list(?)
sum([H|T],Sum) :- sum(T, Temp), Sum is Temp + H. %recursively adds the numbers
%maybe my base case is off
?- sum([1,2,3,4], 10).
返回true,因为列表项的总和为10,但是...
?- sum([1,2,3,4], 6).
返回false,我需要它返回true,因为4 + 2 = 6。
答案 0 :(得分:3)
DCG显然是这样:
sum_of_2_items(Xs, N) :-
phrase(( ..., [A], ..., [B], ...), Xs),
N is A+B.
... --> [] | [_], ... .
或者,至少效率更高:
sum_of_2_items(Xs, N) :-
phrase(( ..., [A], ..., [B], {N is A+B}, ...), Xs).
答案 1 :(得分:0)
append/3
是您分解清单时的朋友。
尝试这样的事情:
sum_of_2_items(L,N) :-
take2( L, X, Y ),
N =:= X + Y
.
take2( L , X , Y ) :-
append( Pfx, [X|Sfx], L ),
gety( Pfx, Sfx , Y )
.
gety( L, _, Y ) :- gety( L, Y ).
gety( _, L, Y ) :- gety( L, Y ).
gety( [Y|_], Y ).
gety( [_|Ys], Y ) :- gety( Ys, Y ).
答案 2 :(得分:0)
为此的教科书谓词为select/3
。这是列表,列表中的元素以及列表其余部分之间的真正关系。
?- select(X, [1,2,3,4], Rest).
X = 1,
Rest = [2, 3, 4] ;
X = 2,
Rest = [1, 3, 4] ;
X = 3,
Rest = [1, 2, 4] ;
X = 4,
Rest = [1, 2, 3].
所以您只需使用两次:
sum_of_two(List, Sum) :-
select(X, List, L0),
select(Y, L0, _),
plus(X, Y, Sum).
答案 3 :(得分:0)
您可以更一般一些,检查数字是否为列表中数字的总和。
有两种基本情况:
N是列表的成员
sum(L, N) :-
member(L, N).
N可以是两个数字的和:
sum(L, N) :-
select(A, L, L1),
select(B, L1, _),
N is A+B.
现在是一般情况:
sum(L, N):-
select(A, L, L1),
N1 is N-A,
N1 >= 0,
sum(L1, N1).
请注意,此代码仅适用于正数 可能有很多解决方案,所以我们只需使用 once / 1 检查是否存在解决方案。 所以:
check_sum(L, N) :-
once(sum(L, N)).
sum(L, N):-
select(N, L, _).
sum(L, N) :-
select(A, L, L1),
select(B, L1, _),
N =:= A+B.
sum(L, N):-
select(A, L, L1),
N1 is N-A,
N1 >= 0,
sum(L1, N1).