Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 如何确定列表中两个数字的和_Prolog - Fatal编程技术网

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

Prolog 如何确定列表中两个数字的和,prolog,Prolog,试图确定列表中的两个数字是否等于给定值 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 我已经阅读了swi prolog文档中的许多问题和大多数lists.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
我已经阅读了swi prolog文档中的许多问题和大多数lists.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
返回true,因为列表项的总和为10,但是

?- sum([1,2,3,4], 6).
返回false,我需要它返回true,因为4+2=6。

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 ).
在分解列表时,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 ).

这方面的教科书谓词是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).

这方面的教科书谓词是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).

您可以更一般地检查一个数字是否是列表中的数字之和

有两种基本情况:

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的解决方案。 因此:


您可以更一般地检查一个数字是否是列表中的数字之和

有两种基本情况:

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的解决方案。 因此:


显然,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).

显然,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).

或者甚至取2个有序的XsYs,X,Y:-append_u1;,[X | Ys],XsYs,append_1;,[Y | 1;,Ys.@jsf。。。据我所知,append_uuu,[X | Ys],L与selectX完全相同,L,Ys?@User9213不完全相同,append Ys是X之后的列表的其余部分,select是没有X的整个列表。这就是为什么基于select的解决方案效率有点低,他们按不同的顺序看每个值对两次。@jschimpf我现在明白了¸谢谢!因此,基本上使用append可以在拾取的图元上添加位置约束,这绝对有用。如果你不写评论作为回答,我会写-@用户9213继续;或者甚至取2个有序的XsYs,X,Y:-append_u1;,[X | Ys],XsYs,append_1;,[Y | 1;,Ys.@jsf。。。据我所知,append_uuu,[X | Ys],L与selectX完全相同,L,Ys?@User9213不完全相同,append Ys是X之后的列表的其余部分,select是没有X的整个列表。这就是为什么基于select的解决方案效率有点低,他们按不同的顺序看每个值对两次。@jschimpf我现在明白了¸谢谢!因此,基本上使用append可以在拾取的图元上添加位置约束,这绝对有用。如果你不写评论作为回答,我会写-@用户9213继续;