Loops 如何在Prolog中计算数列和
任务是计算从0到M的自然数之和。我使用SWI Prolog编写了以下代码:Loops 如何在Prolog中计算数列和,loops,prolog,Loops,Prolog,任务是计算从0到M的自然数之和。我使用SWI Prolog编写了以下代码: my_sum(From, To, _) :- From > To, !. my_sum(From, To, S) :- From = 0, Next is 1, S is 1, my_sum(Next, To, S). my_sum(From, To, S) :- From > 0, Next is From + 1, S is S + Next, my_sum(Next, T
my_sum(From, To, _) :- From > To, !.
my_sum(From, To, S) :-
From = 0,
Next is 1,
S is 1,
my_sum(Next, To, S).
my_sum(From, To, S) :-
From > 0,
Next is From + 1,
S is S + Next,
my_sum(Next, To, S).
但当我试图计算时:
my_sum(0,10,S), writeln(S).
我得到的是假的而不是正确的数字。这个例子出了什么问题?对于Next\=0,这肯定是错误的:
S是S+Next
。另一个更基本的问题是,计算是以“相反”的顺序进行的。也就是说,当From>到并且程序停止时,您不会“返回”结果。然后您应该添加一个累加器(另一个参数,将被传播到所有递归调用),并在最后一步将其和部分和统一起来
无论如何,应该更简单:
my_sum(From, To, S) :-
From < To,
Next is From + 1,
my_sum(Next, To, T),
S is T + From.
my_sum(N, N, N).
| ?- my_sum(2, 4, N).
N = 9
my_sum(从,到,S):-
从<到,
接下来是从+1开始,
我的金额(下一个,To,T),
S是T+From。
我的求和(N,N,N)。
|?-我的总和(2,4,N)。
N=9
对于Next\=0,这肯定是错误的:S是S+Next
。另一个更基本的问题是,计算是以“相反”的顺序进行的。也就是说,当From>到并且程序停止时,您不会“返回”结果。然后您应该添加一个累加器(另一个参数,将被传播到所有递归调用),并在最后一步将其和部分和统一起来
无论如何,应该更简单:
my_sum(From, To, S) :-
From < To,
Next is From + 1,
my_sum(Next, To, T),
S is T + From.
my_sum(N, N, N).
| ?- my_sum(2, 4, N).
N = 9
my_sum(从,到,S):-
从<到,
接下来是从+1开始,
我的金额(下一个,To,T),
S是T+From。
我的求和(N,N,N)。
|?-我的总和(2,4,N)。
N=9
我将使用带有附加累加器的worker谓词,沿着这些行编写谓词:
sum(X,Y,Z) :-
integer(X) ,
integer(Y) ,
sum(X,Y,0,Z)
.
sum(X,X,T,Z) :- Z is T+X .
sum(X,Y,T,Z) :- X < Y , X1 is X+1 , T1 is T+X , sum(X1,Y,T1,Z) .
sum(X,Y,T,Z) :- X > Y , X1 is X-1 , T1 is T+X , sum(X1,Y,T1,Z) .
sum(X,Y,Z):-
整数(X),
整数(Y),
总和(X,Y,0,Z)
.
和(X,X,T,Z):-Z是T+X。
和(X,Y,T,Z):-XY,X1是X-1,T1是T+X,和(X1,Y,T1,Z)。
这个实现是简单的、双向的,这意味着sum(1,3,X)
和sum(3,1,X)
都会产生6个结果(1+2+3),并且尾部递归,这意味着它应该能够处理任何大小的范围而不会出现堆栈溢出。我将沿着这些行编写谓词,将辅助谓词与附加累加器一起使用:
sum(X,Y,Z) :-
integer(X) ,
integer(Y) ,
sum(X,Y,0,Z)
.
sum(X,X,T,Z) :- Z is T+X .
sum(X,Y,T,Z) :- X < Y , X1 is X+1 , T1 is T+X , sum(X1,Y,T1,Z) .
sum(X,Y,T,Z) :- X > Y , X1 is X-1 , T1 is T+X , sum(X1,Y,T1,Z) .
sum(X,Y,Z):-
整数(X),
整数(Y),
总和(X,Y,0,Z)
.
和(X,X,T,Z):-Z是T+X。
和(X,Y,T,Z):-XY,X1是X-1,T1是T+X,和(X1,Y,T1,Z)。
这个实现是简单的,双向的,这意味着sum(1,3,X)
和sum(3,1,X)
都会产生6个结果(1+2+3),并且尾部递归,这意味着它应该能够处理任何大小的范围而不会出现堆栈溢出。事实上,还有一个纯粹的解析解:
sum(N, Sum) :- Sum is N * (N+1) / 2.
使用中:
?- sum(100, N).
N = 5050.
您使用了循环标记,因此这可能不是您想要的答案,但如果存在这种解决方案,最好选择这种解决方案。事实上,还有一种纯粹的分析解决方案:
sum(N, Sum) :- Sum is N * (N+1) / 2.
predicates
sum(integer,integer)
clauses
sum(0,0).
sum(N,R):-
N1=N-1,
sum(N1,R1),
R=R1+N.
使用中:
?- sum(100, N).
N = 5050.
您使用了循环标记,因此这可能不是您想要的答案,但如果存在这种解决方案,最好选择这种解决方案。my_sum(From,to,u):-From>to
表示如果From
大于To
并提供未定义的结果,则成功。这就是你想要的吗?my_sum(From,To,To):-From>To
表示如果From
大于To
并提供未定义的结果,则成功。这就是你想要的吗?请,你能解释为什么S是S+下一个结果为False吗?Prolog中的变量是不可修改的:只能是自由的或绑定到一个值。那么对S的求值为S+N肯定会失败,因为N\=0谢谢!我想我开始明白了。)@AndrejKirejeŭ-为了详细说明Capelical的评论,Prolog中的“变量”与大多数其他语言中的变量不同。它们不是可自由分配的。在Prolog中,一个变量被语言“实例化”以试图使某件事情成功,一旦实例化,它就不能被重新实例化,除非通过回溯。为什么你建议非TR解决方案?(我只是不能上传非TR代码)。请您解释一下为什么S是S+下一个结果为False?Prolog中的变量是不可修改的:只能是自由的或绑定到一个值。那么对S的求值为S+N肯定会失败,因为N\=0谢谢!我想我开始明白了。)@AndrejKirejeŭ-为了详细说明Capelical的评论,Prolog中的“变量”与大多数其他语言中的变量不同。它们不是可自由分配的。在Prolog中,一个变量被语言“实例化”以试图使某件事情成功,一旦实例化,它就不能被重新实例化,除非通过回溯。为什么你建议非TR解决方案?(我只是无法对非TR代码进行表决)。计算sum$take 200$drop 176$cycle[1,7..242]
怎么样,我们也能轻松地得出一个封闭的解决方案吗?(请原谅Haskell语法)。:)这不是批评或任何东西,只是一个评论,:)也许是毫无意义的。计算一下sum$take 200$drop 176$cycle[1,7..242]
,我们能很容易地得出一个封闭的解决方案吗?(请原谅Haskell语法)。:)这不是批评或什么,只是评论,:)也许是毫无意义的。谢谢你的回答!但请花几分钟时间阅读,以获得一些关于回答问题的有用提示。特别是“解释越充分越好”部分。意思:请解释为什么这回答了这个问题(比现有的答案更好)。非常感谢你的建议。这是在期望你能用它做点什么的情况下给出的。谢谢你的回答!但请花几分钟时间阅读,以获得一些关于回答问题的有用提示。特别是“解释越充分越好”部分。意思:请解释为什么这个答案(比现有答案更好)。非常感谢你的建议。它是在期望你能用它做点什么的情况下给出的。
predicates
sum(integer,integer)
clauses
sum(0,0).
sum(N,R):-
N1=N-1,
sum(N1,R1),
R=R1+N.