1
votes

I've been searching for something that might help me with my problem all over the internet but I haven't been able to make any progress. I'm new to logic programming and English is not my first language so apologize for any mistake.

Basically I want to implement this prolog program: discord/3 which has arguments L1, L2 lists and P where P are the indexes of the lists where L1[P] != L2[P] (in Java). In case of different lengths, the not paired indexes just fail. Mode is (+,+,-) nondet.

I got down the basic case but I can't seem to wrap my head around on how to define P in the recursive call.

discord(_X,[],_Y) :-
    fail.
discord([H1|T1],[H1|T2],Y) :-
    ???
    discord(T1,T2,Z).
discord([_|T1],[_|T2],Y) :-
    ???
    discord(T1,T2,Z).

The two clauses above are what I came up to but I have no idea on how to represent Y - and Z - so that the function actually remembers the length of the original list. I've been thinking about using nth/3 with eventually an assert but I'm not sure where to place them in the program.

I'm sure there has to be an easier solution although. Thanks in advance!

1
Can you add an example query to your question? Like this (just guessing): ?- discord([a,b,c],[x,b,y], [1,3]). should be true? - user1812457
Exactly! The mode I meant to use was (+,+,-) so a sample query could be something like ?- discord([a,b,c], [d,e,c], X) which should give answers X=1; X=2 or ?- discord([1,2,3], [1,2,3], X) which should answer false - GoldenMat
It would be enough to write dif(X, Y), nth1(P, L1, X), nth1(P, L2, Y) - user1812457
I'm not quite sure what you mean? I tried this implementation but it doesn't work, If I have a true answer it always answers P=1- because the recursion doesn't remember the length of the original list! discord(_X,[],_Y) :- fail. discord([],_X,_Y) :- fail. discord([X|T1],[Y|T2],P) :- dif(X,Y), nth1(P, [X|T1], X), nth1(P, [Y|T2], Y), discord(T1,T2,P). - GoldenMat
No need for recursive predicate at all, this code snippet is the full definition of your discord/3. You can also write a recursive predicate for this, but maybe unnecessary. - user1812457

1 Answers

0
votes

You can approach this in two ways. First, the more declarative way would be to enumerate the indexed elements of both lists with nth1/3 and use dif/2 to ensure that the two elements are different:

?- L1 = [a,b,c,d],
   L2 = [x,b,y,d],
   dif(X, Y),
   nth1(P, L1, X),
   nth1(P, L2, Y).
X = a, Y = x, P = 1 ;
X = c, Y = y, P = 3 ;
false.

You could also attempt to go through both list at the same time and keep a counter:

discord(L1, L2, P) :-
    discord(L1, L2, 1, P).

discord([X|_], [Y|_], P, P) :-
    dif(X, Y).
discord([_|Xs], [_|Ys], N, P) :-
    succ(N, N1),
    discord(Xs, Ys, N1, P).

Then, from the top level:

?- discord([a,b,c,d], [a,x,c,y], Ps).
Ps = 2 ;
Ps = 4 ;
false.