任务是计算从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, To, S).
但是当我尝试计算时:
my_sum(0,10,S), writeln(S).
我得到了假而不是正确的数字。这个例子出了什么问题?
答案 0 :(得分:2)
对于Next \ = 0:S is S + Next
,这肯定是假的。另一个更基本的问题是你以“反向”顺序进行计算。也就是说,当From > To
和程序停止时,您不会“返回”结果。然后你应该添加一个累加器(另一个参数,传播到所有递归调用)并在最后一步将它与部分和统一起来......
无论如何,应该更简单:
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
答案 1 :(得分:2)
我在这些行中编写谓词,使用带有附加累加器的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(1,3,X)
和sum(3,1,X)
都会产生6(1 + 2 + 3),尾递归,这意味着它应该能够处理任何大小的范围而不会出现堆栈溢出。
答案 2 :(得分:2)
实际上,还有一个纯粹的分析解决方案:
sum(N, Sum) :- Sum is N * (N+1) / 2.
使用中:
?- sum(100, N).
N = 5050.
你使用了循环标记,所以这可能不是你想要的答案,但是当存在这种解决方案时,最好选择这种解决方案。
答案 3 :(得分:0)
class CreateProductForm(forms.Form):
name = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))
content = forms.CharField(widget=forms.Textarea(attrs={'class':'form-control', 'id': 'ck-editor-area'}))
excerpt = forms.CharField(widget=forms.Textarea(attrs={'class':'form-control', 'rows': '7'}), required=False)
price = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Amount'}))
status = forms.CharField(widget=forms.Select(choices=(('1', 'Active'),('0', 'Inactive'),), attrs={'class':'form-control'}))
quantity = forms.CharField(widget=forms.NumberInput(attrs={'class':'form-control'}))