For Programmers: Free Programming Magazines  


Home > Archive > Prolog > July 2004 > [newbie] siblings and surnames









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author [newbie] siblings and surnames
Fabio

2004-07-21, 8:57 pm

Hello,

I'm a prolog newbie, studying it for my IA course, and trying to
implement some things I need for an exam...

I've read trough the archives, and I saw that the commutativity/simetry
topic was already covered, and that's been of great help to me, however
i'm now unable to solve another problem.

My problem doesn't concern siblings and surnames, but to not introduce
even more confusion in the discussion I thought I'd simply reuse the
terms used in the past thread about simmetry rules.

Let's assume that we already have this simmetric predicate called
siblings/2, which basically states that

siblings(X,Y) <==> siblings(Y,X)

Now, I want to code the rule which says that "All siblings share the
same surname". Question is: how the heck do I do that without incurring
in a loop?

What I've come up with is this:

%all siblings share the same surname
surname(X, Y) :- siblings(X, Z), surname(Z, Y).

%john's surname is smith.
surname(john, smith).

%john and paul are sibligs
siblings(john, paul).

But of course the first clause causes a loop, if I type

surname(paul, X).

If I put the first clause as last, that is this way:

%john's surname is smith.
surname(john, smith).

%john and paul are sibligs
siblings(john, paul).

%all siblings share the same surname
surname(X, Y) :- siblings(X, Z), surname(Z, Y).

then, for how prolog does the search, it works, somwhat, because when it
encounters the surname predicate in the last clause's body it starts its
search from the first clause in the program and thus fids surname(john,
smith). However, if I press ';' when it gives me the answer then I can
see that it went into another loop. I can fix this if I modify the last
clause this way:

%all siblings share the same surname
surname(X, Y) :- siblings(X, Z), surname(Z, Y), !.

However, 1) I don't want to put such a clause after all the facts about
the siblings relationship, and 2) this still doesn't allow me to get all
siblings with a given surname.

Any suggestions?

Fabio

Nameless

2004-07-21, 8:57 pm

"Fabio" wrote in message
news:0wBLc.9178$OH4.123594@twister1.libero.it...
> I'm a prolog newbie, studying it for my IA course, and trying
> to implement some things I need for an exam...
>
> I've read trough the archives, and I saw that the
> commutativity/simetry topic was already covered, and that's
> been of great help to me, however i'm now unable to solve
> another problem.
>
> My problem doesn't concern siblings and surnames, but to not
> introduce even more confusion in the discussion I thought I'd
> simply reuse the terms used in the past thread about simmetry
> rules.
>
> Let's assume that we already have this simmetric predicate
> called siblings/2, which basically states that
>
> siblings(X,Y) <==> siblings(Y,X)
>
> Now, I want to code the rule which says that "All siblings
> share the same surname". Question is: how the heck do I do
> that without incurring in a loop?
>
> What I've come up with is this:
>
> %all siblings share the same surname
> surname(X, Y) :- siblings(X, Z), surname(Z, Y).
>
> %john's surname is smith.
> surname(john, smith).
>
> %john and paul are sibligs
> siblings(john, paul).
>
> But of course the first clause causes a loop, if I type
>
> surname(paul, X).
>
> If I put the first clause as last, that is this way:
>
> %john's surname is smith.
> surname(john, smith).
>
> %john and paul are sibligs
> siblings(john, paul).
>
> %all siblings share the same surname
> surname(X, Y) :- siblings(X, Z), surname(Z, Y).
>
> then, for how prolog does the search, it works, somwhat,
> because when it encounters the surname predicate in the last
> clause's body it starts its search from the first clause in
> the program and thus fids surname(john, smith). However, if I
> press ';' when it gives me the answer then I can see that it
> went into another loop. I can fix this if I modify the last
> clause this way:
>
> %all siblings share the same surname
> surname(X, Y) :- siblings(X, Z), surname(Z, Y), !.
>
> However, 1) I don't want to put such a clause after all the
> facts about the siblings relationship, and 2) this still
> doesn't allow me to get all siblings with a given surname.
>
> Any suggestions?


You'd do better to approach the problem this way:

% facts:

% name(FirstName, Surname)
name(john, smith).
name(peter, jones).
name(paul, smith).

% rules:

% sibling(+FirstName, +Surname)
% all siblings share the same surname
sibling(First, Surname) :-
name(FirstName, Surname),
\+ FirstName == First.

Sorry if this doesn't give a complete answer to your
question, but it's late and way past my bedtime.

--
Mail sent to this email address is automatically deleted
(unread) on the server. Send replies to the newsgroup.


Fabio

2004-07-21, 8:57 pm

Nameless wrote:
> You'd do better to approach the problem this way:
>
> % facts:
>
> % name(FirstName, Surname)
> name(john, smith).
> name(peter, jones).
> name(paul, smith).
>
> % rules:
>
> % sibling(+FirstName, +Surname)
> % all siblings share the same surname
> sibling(First, Surname) :-
> name(FirstName, Surname),
> \+ FirstName == First.
>
> Sorry if this doesn't give a complete answer to your
> question, but it's late and way past my bedtime.


I could be wrong, but that doesn't answer my question at all :-)

What I want is to be able to inferr that paul's surname is smith, if I
know that the surname of paul, john's sibling, is smith and that
siblings share the same surname.

In other words, in the knowledge base there needn't be the fact that
paul's surname is smith.

Fabio Alemagna
Fabio

2004-07-21, 8:57 pm

Nameless wrote:
> You'd do better to approach the problem this way:
>
> % facts:
>
> % name(FirstName, Surname)
> name(john, smith).
> name(peter, jones).
> name(paul, smith).
>
> % rules:
>
> % sibling(+FirstName, +Surname)
> % all siblings share the same surname
> sibling(First, Surname) :-
> name(FirstName, Surname),
> \+ FirstName == First.
>
> Sorry if this doesn't give a complete answer to your
> question, but it's late and way past my bedtime.


I could be wrong, but that doesn't answer my question at all :-)

What I want is to be able to inferr that paul's surname is smith, if I
know that the surname of paul, john's sibling, is smith and that
siblings share the same surname.

In other words, in the knowledge base there needn't be the fact that
paul's surname is smith.

Fabio
Cesar Rabak

2004-07-21, 8:57 pm

Fabio escreveu:
> Hello,
>
> I'm a prolog newbie, studying it for my IA course, and trying to
> implement some things I need for an exam...
>
> I've read trough the archives, and I saw that the
> commutativity/simetry topic was already covered, and that's been of
> great help to me, however i'm now unable to solve another problem.
>
> My problem doesn't concern siblings and surnames, but to not
> introduce even more confusion in the discussion I thought I'd simply
> reuse the terms used in the past thread about simmetry rules.


OK, supposing, that the even so the example captures your difficulties. . .
>
> Let's assume that we already have this simmetric predicate called
> siblings/2, which basically states that
>
> siblings(X,Y) <==> siblings(Y,X)
>
> Now, I want to code the rule which says that "All siblings share the
> same surname". Question is: how the heck do I do that without
> incurring in a loop?
>
> What I've come up with is this:

[snipped]

> Any suggestions?


Fabio, you have to decide what property(ies) will be precedents and what
will be consequents:

Let's say the knowledge base will contain the facts below:

%john's surname is smith.
surname(john, smith).

% so is jane's, etc.
surname(jane, smith).
surname(mike, bronson).
surname(lana, lane).
surname(martha, lane).
surname(chuck, fox).
surname(craig, fox).
surname(jewel, fox).

And the following rule:

%all siblings share the same surname
siblings(X, Y) :- surname(X, Z) , surname(Y, Z), X \= Y.

I 'decided' that one is not a sibling of himself!

If you consult a file with the knowledge base above, with your favorite
Prolog interpreter you'll get:

?- siblings(jewel, S).

S = chuck ;

S = craig ;

No
?- siblings(mike, S).

No
?- siblings(jane, S).

S = john ;

No

Hope this gets you started.

--
Cesar Rabak

Fabio

2004-07-22, 8:56 am

Fabio wrote:
> What I want is to be able to inferr that paul's surname is smith, if I
> know that the surname of paul, john's sibling, is smith and that

^^^^ ^^^^

Damned, those two should be inverted :-)

Fabio
Fabio

2004-07-22, 8:56 am

Cesar Rabak wrote:
> [...]
> Fabio, you have to decide what property(ies) will be precedents and what
> will be consequents:
>
> Let's say the knowledge base will contain the facts below:
>
> %john's surname is smith.
> surname(john, smith).
>
> % so is jane's, etc.
> surname(jane, smith).
> surname(mike, bronson).
> surname(lana, lane).
> surname(martha, lane).
> surname(chuck, fox).
> surname(craig, fox).
> surname(jewel, fox).
>
> And the following rule:
>
> %all siblings share the same surname
> siblings(X, Y) :- surname(X, Z) , surname(Y, Z), X \= Y.


Ehum... doesn't that rather say that two people with the same surname
are siblings, as long as they are not the same person?

If so, that's not what I want to code. People can share the same surname
and yet not be siblings.

> I 'decided' that one is not a sibling of himself!


Well, unfortunately in my case I cannot do that "simplification" :-)

Fabio
Fabio

2004-07-22, 8:56 am

Fabio wrote:

> Fabio wrote:
>
>
> ^^^^ ^^^^
>
> Damned, those two should be inverted :-)


Uh... it didn't come out very well. Ok, let's rewrite it from scratch:

What I want is to be able to inferr that paul's surname is smith, if I
know that the surname of john, paul's sibling, is smith.

Sorry for the many (useless?) posts.

Fabio
Cesar Rabak

2004-07-22, 3:58 pm

Fabio escreveu:
> Cesar Rabak wrote:
>
>
>
> Ehum... doesn't that rather say that two people with the same surname
> are siblings, as long as they are not the same person?


Yes.

>
> If so, that's not what I want to code. People can share the same surname
> and yet not be siblings.
>


Then you have to figure out which additional facts or rules you want to
have on your knowledge base so the question in Prolog when asked retuns
the info you want.

In a siblings knowledge base it could be the ascendancy of the persons,
for example.

HTH

--
Cesar Rabak

Pento

2004-07-22, 3:58 pm

Fabio <dont@spam.please> wrote in
news:sBMLc.10079$OH4.137843@twister1.libero.it:

> If so, that's not what I want to code. People can share the same surname
> and yet not be siblings.


Then you will need to include other information. You should include
information about parents and such ...

--
Pento

De wereld was soep, en het denken meestal een vork,
tot smakelijk eten leidde dat zelden. - H. Mulisch
Fabio

2004-07-22, 8:57 pm

Pento wrote:

> Fabio <dont@spam.please> wrote in
> news:sBMLc.10079$OH4.137843@twister1.libero.it:
>
>
>
>
> Then you will need to include other information. You should include
> information about parents and such ...


Why so? I just want to state that two siblings have the same surname.
Nothing more and nothing less.

Remember that "siblings" here could be whatever thing that matched the
same properties I want to encode, and the only property I want to encode
is that one I talked about above.

I my case, for instance, I have a circuit, and I want to say that two
connected ports have the same signal's value (high or low). So far, I've
been unable to find a way that would let me encode this rule without
incurring in loops.

Fabio Alemagna
Pento

2004-07-22, 8:57 pm

Fabio <dont@spam.please> wrote in
news:pjVLc.11118$OH4.158646@twister1.libero.it:

> Pento wrote:
>
>
> Why so? I just want to state that two siblings have the same surname.
> Nothing more and nothing less.


Then you would need to construct data about who are siblings, and the
surname of at least one of each sibling-group :

siblings(john,paul).
siblings(mary,george).
siblings(mary,lucas).

siblings2(X,Y) :- siblings(X,Y).
siblings2(X,Y) :- siblings(Y,X).

surname(john,smith).
surname(george,dickens).

surname2(X,Name) :-
surname2(X,Name,[]).
surname2(X,Name,_) :- surname(X,Name),!.
surname2(X,Name,L) :-
siblings2(X,Y),
nonmember(Y,L),
surname2(Y,Name,[X|L]).

nonmember(_,[]).
nonmember(X,[X|_]) :- !,fail.
nonmember(X,[_|T]) :- nonmember(X,T).

?- surname2(lucas,Name).

Name = dickens ;

No

Is this what you wanted ?


--
Pento

De wereld was soep, en het denken meestal een vork,
tot smakelijk eten leidde dat zelden. - H. Mulisch
Fabio

2004-07-22, 8:57 pm

Pento wrote:
> [...]
> Then you would need to construct data about who are siblings, and the
> surname of at least one of each sibling-group :


That's of course what I do :-)
>
> siblings(john,paul).
> siblings(mary,george).
> siblings(mary,lucas).
>
> siblings2(X,Y) :- siblings(X,Y).
> siblings2(X,Y) :- siblings(Y,X).
>
> surname(john,smith).
> surname(george,dickens).
>
> surname2(X,Name) :-
> surname2(X,Name,[]).
> surname2(X,Name,_) :- surname(X,Name),!.
> surname2(X,Name,L) :-
> siblings2(X,Y),
> nonmember(Y,L),
> surname2(Y,Name,[X|L]).
>
> nonmember(_,[]).
> nonmember(X,[X|_]) :- !,fail.
> nonmember(X,[_|T]) :- nonmember(X,T).
>
> ?- surname2(lucas,Name).
>
> Name = dickens ;
>
> No
>
> Is this what you wanted ?


Yes, definitely, thanks! I thought I could probably use lists, but it
smelt a bit tricky to me, and perhaps inefficient? Another thing I
dislike about this way of doing things is that there's the need to
introduce another predicate... guess one should resort to a different
logic language to avoid that.

However, why did you use the cut operator in the 2nd surname2 clause's
body? That cut there disallows for thigs like:

?- surname2(Name, smith) % get all names of the smith siblings

or even

?- surname2(Name, Surname) % get all pairs of name/surname.

Is there any reason for that cut? Peformances, perhaps?

Thanks a lot!

Fabio
Fabio

2004-07-22, 8:57 pm

Oh, btw...

Fabio wrote:[color=darkred]

Couldn't nonmember/2 be defined as

nonmember(X, Y) :- \+ member(X, Y).

?

Fabio
Pento

2004-07-23, 8:57 am

Fabio <dont@spam.please> wrote in
news:wxWLc.7379$1V3.144570@twister2.libero.it:

> Couldn't nonmember/2 be defined as
>
> nonmember(X, Y) :- \+ member(X, Y).


Sure.

> However, why did you use the cut operator in the 2nd surname2 clause's
> body? That cut there disallows for thigs like:
>
> ?- surname2(Name, smith) % get all names of the smith siblings
>
> or even
>
> ?- surname2(Name, Surname) % get all pairs of name/surname.
>
> Is there any reason for that cut? Peformances, perhaps?


No, none at all, this was a mistake on my part. Sorry for the confusion.

--
Pento

De wereld was soep, en het denken meestal een vork,
tot smakelijk eten leidde dat zelden. - H. Mulisch
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com