开发者

Prolog: iteration

开发者 https://www.devze.com 2023-03-29 17:07 出处:网络
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.

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 d开发者_运维问答oes 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!


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).


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.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号