如何从列表中确定两个数字的和

时间:2019-04-26 22:47:34

标签: prolog

试图确定列表中的两个数字是否等于给定值。

我已经阅读了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。

4 个答案:

答案 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).