Prolog:迭代

发布于 2024-11-30 14:20:53 字数 604 浏览 1 评论 0原文

晚上好, 我有一个简单的问题,我警告你我对序言很陌生。 假设有三个相同大小的列表,每个列表仅包含 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 技术交流群。

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

发布评论

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

评论(2

欢你一世 2024-12-07 14:20:53

一些备注:混合 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) 你可以将它们全部放在一行中:

maplist(\X^Y^Z^(abs(X)+abs(Y)+abs(Z) #= 1), Xs, Ys, Zs).

Some remarks: Mixing library(clpfd) and (is)/2 is mostly not a good idea. You can write X #= Y + 1 in place of X 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) where r/3 is the relation you are interested in. So we have to define r(X,Y,Z).

What about abs(X)+abs(Y)+abs(Z) #= 1?

With library(lambda) you can put it all into a single line:

maplist(\X^Y^Z^(abs(X)+abs(Y)+abs(Z) #= 1), Xs, Ys, Zs).
各自安好 2024-12-07 14:20:53

您可以通过简单的递归来完成。该程序仅测试输入,不能用于生成解决方案。如果您需要,您必须说明事实中允许哪些值,例如通过添加 onlyOne(0,0,1)。 onlyOne(0,0,-1).

onlyOne(0,0,_).
onlyOne(0,_,0).
onlyOne(_,0,0).
onlyOne([],[],[]).
onlyOne([H1|T1],[H2|T2],[H3|T3]) :- onlyOne(H1,H2,H3), onlyOne(T1,T2,T3).

编辑:重新阅读问题我想您需要恰好有一个条目非零,而不是最多一个。在这种情况下,您需要这些规则而不是事实:

onlyOne(0,0,X) :- X \= 0.
onlyOne(0,X,0) :- X \= 0.
onlyOne(X,0,0) :- X \= 0.

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.

onlyOne(0,0,_).
onlyOne(0,_,0).
onlyOne(_,0,0).
onlyOne([],[],[]).
onlyOne([H1|T1],[H2|T2],[H3|T3]) :- onlyOne(H1,H2,H3), onlyOne(T1,T2,T3).

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:

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