Prolog:迭代
晚上好, 我有一个简单的问题,我警告你我对序言很陌生。 假设有三个相同大小的列表,每个列表仅包含 1、0 或 -1。 我想验证对于所有 i,三个列表的第 i 个元素中,只有一个非零。
这段代码针对固定的 i 执行此操作:
:- use_module(library(clpfd)).
compat1(V1,V2,V3,I) :-
length(V1,G),
nth1(I,V1,X),
nth1(I,V2,Y),
nth1(I,V3,Z),
W is X*X+Y*Y+Z*Z,
W is 1,
I in 1..G.
我如何判断“对于所有 I,compat1(V1,V2,V3,I)”? 我尝试定义,
compat2(V1,V2,V3,1) :- compat1(V1,V2,V3,1).
compat2(V1,V2,V3,K) :- compat2(V1,V2,V3,J), compat1(V1,V2,V3,K), K is J+1.
以便我可以用 K=我感兴趣的最大值来调用它。 但 compat2 不起作用:在“;”之后给出 true,然后无限期地运行。
谢谢!
Good evening,
i have a simple problem, and i warn you that i am very new with prolog.
Suppose to have three lists of the same size, each containing only 1s, 0s or -1s.
I want to verify that for all i, of the i-th elements of the three lists, one and only one is nonzero.
This code does it for a fixed i:
:- use_module(library(clpfd)).
compat1(V1,V2,V3,I) :-
length(V1,G),
nth1(I,V1,X),
nth1(I,V2,Y),
nth1(I,V3,Z),
W is X*X+Y*Y+Z*Z,
W is 1,
I in 1..G.
how can I tell "for ALL I, compat1(V1,V2,V3,I)"?
I tried to define
compat2(V1,V2,V3,1) :- compat1(V1,V2,V3,1).
compat2(V1,V2,V3,K) :- compat2(V1,V2,V3,J), compat1(V1,V2,V3,K), K is J+1.
so that I could call it with K=maximum value i'm interested in.
But compat2 doesn't work: gives true, then, after ";" runs indefinitely.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一些备注:混合
library(clpfd)
和(is)/2
通常不是一个好主意。您可以编写X #= Y + 1
来代替X is Y + 1
,其效率几乎相同(在 SWI 中),但享受其增强的通用性。您感兴趣的关系涉及三个列表的第 i 个元素。也就是说,我们可以写:
maplist(r, Xs, Ys, Zs)
其中r/3
是您感兴趣的关系。所以我们必须定义r(X,Y,Z)
。abs(X)+abs(Y)+abs(Z) #= 1
怎么样?使用
库(lambda)
你可以将它们全部放在一行中:Some remarks: Mixing
library(clpfd)
and(is)/2
is mostly not a good idea. You can writeX #= Y + 1
in place ofX is Y + 1
with almost the same efficiency (in SWI) but enjoying its increased generality.The relation you are interested in, relates the i-th elements of three lists. That is, we can write:
maplist(r, Xs, Ys, Zs)
wherer/3
is the relation you are interested in. So we have to definer(X,Y,Z)
.What about
abs(X)+abs(Y)+abs(Z) #= 1
?With
library(lambda)
you can put it all into a single line:您可以通过简单的递归来完成。该程序仅测试输入,不能用于生成解决方案。如果您需要,您必须说明事实中允许哪些值,例如通过添加
onlyOne(0,0,1)。 onlyOne(0,0,-1).
等编辑:重新阅读问题我想您需要恰好有一个条目非零,而不是最多一个。在这种情况下,您需要这些规则而不是事实:
You could do it with a simple recursion. The program does only test the input, it cannot be used to generate solutions. If you need that, you have to say which values are allowed in the facts, e.g. by adding
onlyOne(0,0,1). onlyOne(0,0,-1).
, etc.Edit: Re-reading the question I guess you require that exactly one entry is nonzero, not at most one. In that case you need these rules instead of the facts: