-1

I have this predicate spaces_uni(Spc,LstWords), Spc is a list of variables like [X,Y,Z] or [a,Y,Z] and LstWords is a list of words like [[o,r,a,n,g,e],[a,p,p,l,e],[b,a,n,a,n,a]].

The purpose of this predicate is to check if there is any word in LstWords that can unify with the given Spc.

Example:

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], spaces_uni(Space,Words).
true.

So why is the output true, simple, its because the word drama unifies with [d,A,B,C,D] becoming [d,r,a,m,a]. The problem is that my program is instead returning false and i dont understand why.

Program:

spaces_uni(E,[P|R]) :-
                         length(E,CE),
                         length(P,CP),
                         CE \== CP,!,
                         spaces_uni(E,R).

spaces_uni(E,[P|R]) :-
                           length(E,CE),
                           length(P,CP),
                           CE == CP,!,
                           P \= E,
                           spaces_uni(E,R).


spaces_uni(E,[P|_]) :-
                         length(E,CE),
                         length(P,CP),
                         CE == CP,
                         {}/(P = E),!,
                         true.

Really any help would be appreciated.

Martim Correia
  • 483
  • 5
  • 16

1 Answers1

0

What Prolog implementation are you using, and where did you get the goal {}/(P = E) from?

Prolog's unification already handles list unification just fine:

?- [d, A, B, C, D] = [d, r, a, m, a].
A = r,
B = D, D = a,
C = m.

?- [x, A, B, C, D] = [d, r, a, m, a].
false.

So all you need to do is write a predicate that succeeds if a list unifies with one element of a list of lists.

Something like:

word_words(Word, [Word | _Words]).
word_words(Word, [_Word | Words]) :-
    word_words(Word, Words).

Which works like this:

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], word_words(Space, Words).
Words = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, r, a, m, a], [m, a, e], [m, a, n|...], [s, e|...], [s|...]],
Space = [d, r, a, m, a],
A = r,
B = D, D = a,
C = m ;
false.

But we don't even need to define our own word_words/2 predicate. It doesn't do anything specific to words, and it might look more familiar if we renamed some things:

member_list(X, [X | _List]).
member_list(X, [_Y | List]) :-
    member_list(X, List).

This is just a predicate expressing list membership. So we don't have to write any predicate definitions at all, we can just use the existing membership predicates that probably come with your Prolog implementation:

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], member(Space, Words).
Words = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, r, a, m, a], [m, a, e], [m, a, n|...], [s, e|...], [s|...]],
Space = [d, r, a, m, a],
A = r,
B = D, D = a,
C = m ;
false.

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], memberchk(Space, Words).
Words = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, r, a, m, a], [m, a, e], [m, a, n|...], [s, e|...], [s|...]],
Space = [d, r, a, m, a],
A = r,
B = D, D = a,
C = m.
Isabelle Newbie
  • 9,258
  • 1
  • 20
  • 32