• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

bit of help with prolog

Status
Not open for further replies.

7imz

Member
i'm having a bit of trouble with this prolog predicate, it's basically to test for membership.

mySetMember(X,[X|R]).
mySetMember(X,[A|Y]) :- mySetMember(X,Y).

My problem is i need it to return yes with the following input

mySetMember([a,b],[c,d,[b,a],d]).

any suggestions?
 

7imz

Member
i'm dealing with sets wish means

[a,b] = [b,a]
[b,c,a] = [a,b,c] = [a,c,b]
..etc

I need to a new mySetMember that can handle sets

mySetMember([a,b],[c,d,[b,a],d]).
yes

mySetMember([b,c,a],[o,p,e,q,[a,c,b]])
yes

mine can handle sets as long as it's in the right order

mySetMember([a,b],[c,d,[a,b],d]).
yes

mySetMember([a,b],[c,d,[b,a],d]).
no
 

Overseer

Member
Yeah, you seem to more than I do so there is not much I can do. Try posting on a tech forum you should get responses very fast there.
 

golem

Member
instead of working your way against the second list, you should probably move your way through the first list, and search through the second list for each entry in the first list. that way order wont matter..
 

iapetus

Scary Euro Man
7imz said:
i'm having a bit of trouble with this prolog predicate, it's basically to test for membership.

mySetMember(X,[X|R]).
mySetMember(X,[A|Y]) :- mySetMember(X,Y).

My problem is i need it to return yes with the following input

mySetMember([a,b],[c,d,[b,a],d]).

any suggestions?

It's been a long time since I spoke Prolog in anger, and I don't recall the syntax properly, but here's something that seems to work:

mySetMember(X,[H|R]) :- equalSetOrAtom(X,H).
mySetMember(X,[A|Y]) :- mySetMember(X,Y).

equalSetOrAtom(X, X).
equalSetOrAtom(A, X) :- containsSet(A, X), containsSet(X, A).

containsSet([], X).
containsSet([H|T], X) :- mySetMember(H, X), containsSet(T, X).

The reasoning here is that your check for equality in the first definition of mySetMember() doesn't account for unordered sets. Hence the not-particularly-efficient check for equality between two unordered lists.

Note that this will only work if you don't mind [a,b] being seen as equal to [b, a, b, b, a, b, a, a, b]. If you need that, then you'll have to be a bit more cunning.

Note that this almost certainly isn't the most efficient way of doing things, because it's late and I'm tired.
 

7imz

Member
iapetus said:
It's been a long time since I spoke Prolog in anger, and I don't recall the syntax properly, but here's something that seems to work:

mySetMember(X,[H|R]) :- equalSetOrAtom(X,H).
mySetMember(X,[A|Y]) :- mySetMember(X,Y).

equalSetOrAtom(X, X).
equalSetOrAtom(A, X) :- containsSet(A, X), containsSet(X, A).

containsSet([], X).
containsSet([H|T], X) :- mySetMember(H, X), containsSet(T, X).

The reasoning here is that your check for equality in the first definition of mySetMember() doesn't account for unordered sets. Hence the not-particularly-efficient check for equality between two unordered lists.

Note that this will only work if you don't mind [a,b] being seen as equal to [b, a, b, b, a, b, a, a, b]. If you need that, then you'll have to be a bit more cunning.

Note that this almost certainly isn't the most efficient way of doing things, because it's late and I'm tired.


i love you...
 

iapetus

Scary Euro Man
There is, of course, a deliberate mistake in the solution I provided:

mySetMember([], [a, b, c]) will return yes, when clearly it shouldn't.

I'll leave it to you to work out why that's the case, and to fix it. :)

[Edit: Doh. Ignore that - my solution is (I think) better than I give it credit for, and it shouldn't fall foul of that. :)]
 
Status
Not open for further replies.
Top Bottom