尾部整数的尾部恢复列表
例如
?- divisors(14,What).
What = [2, 7] ?
除数,
?- divisors(14,[2, 8]).
no
除非我试图验证[]不是列表,否则不幸的是成功:
?- divisors(14,[]).
true
可以在调试器中看到为什么它错误地成功了,但是我看不到如何解决这个问题:
divisors_aux(1,_,L,L).
divisors_aux(D,N,List,Aux) :- D>1,0 is N mod D,D1 is D-1,
divisors_aux(D1,N,List,[D|Aux]).
divisors_aux(D,N,List,Aux) :- D>1,D1 is D-1,divisors_aux(D1,N,List,Aux).
divisors(N,List) :- N>1,nonvar(N),D is N-1,divisors_aux(D,N,List,[]).
我知道有循环方法(foreach,foreach,foreach,foreach,foreach,等)但是,我试图根据我到目前为止所学到的知识(Covington等人的前100页)来使这种“蛮力”方法起作用
。谢谢。
I am trying to make a simple tail-recursive loop to collect the divisors of an integer, divisors(N,List) and its working when List is not instantiated, for example,
?- divisors(14,What).
What = [2, 7] ?
And I can verify that the wrong list is not the list of divisors,
?- divisors(14,[2, 8]).
no
Unless I try to verify that [] is not the list, this unfortunately succeeds:
?- divisors(14,[]).
true
can see in the debugger why it is erroneously succeeding, but I don't see how to fix this:
divisors_aux(1,_,L,L).
divisors_aux(D,N,List,Aux) :- D>1,0 is N mod D,D1 is D-1,
divisors_aux(D1,N,List,[D|Aux]).
divisors_aux(D,N,List,Aux) :- D>1,D1 is D-1,divisors_aux(D1,N,List,Aux).
divisors(N,List) :- N>1,nonvar(N),D is N-1,divisors_aux(D,N,List,[]).
I know there are looping approaches (foreach, etc.) but I am trying to make this "brute force" approach work based on what I have learned so far (roughly first 100 pages of Covington et. al.)
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是,当
divisors_aux的第二子句/3
失败(或者成功并要求其他解决方案)时,它将始终回到第三子句。数字是N。
您可能需要使用
\+(0是n mod d)来捍卫第三子句
,以便当当前 否则构造:Your problem is that when the second clause of
divisors_aux/3
fails (or if it succeeds and you ask for another solution) it will always backtrack to the third clause.You may want to guard the third clause with
\+(0 is N mod D)
so that it fails when the current number is a divisor of N.Or alternatively join both clauses with an if-then-else construct: