尾部整数的尾部恢复列表

发布于 2025-01-31 07:58:23 字数 705 浏览 2 评论 0原文

例如

?- 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清秋悲枫 2025-02-07 07:58:23

您的问题是,当divisors_aux的第二子句/3失败(或者成功并要求其他解决方案)时,它将始终回到第三子句。

数字是N。

您可能需要使用\+(0是n mod d)来捍卫第三子句,以便当当前 否则构造:

divisors_aux(1,_,L,L).
divisors_aux(D,N,List,Aux) :- D>1,
                              (0 is N mod D -> Aux1=[D|Aux] ; Aux1=Aux),
                              D1 is D-1,
                              divisors_aux(D1,N,List,Aux1).

divisors(N,List) :- N>1,nonvar(N),D is N-1,divisors_aux(D,N,List,[]).

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:

divisors_aux(1,_,L,L).
divisors_aux(D,N,List,Aux) :- D>1,
                              (0 is N mod D -> Aux1=[D|Aux] ; Aux1=Aux),
                              D1 is D-1,
                              divisors_aux(D1,N,List,Aux1).

divisors(N,List) :- N>1,nonvar(N),D is N-1,divisors_aux(D,N,List,[]).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文