Re: Look for a mother of a child (Roelof Wobben)
Kaitain Jones <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <CAMeycMz+DCbe-dezKzpODkkvYJus-YhZBqPYxo9=8=NWe8qe7Q@mail.gmail.com> |
> mother(child):-
> parent(X, child),
> female(X).
> But when I do mother(tamara). I see no where I expected to see chantal.
> Did I do something wrong or does swi-prolog do something wrong ?
It's usually a wise default to assume the error is yours, not the
language/compiler's.
This predicate is written as though you're possibly thinking that it will
be a function that returns a value somehow: as though you're half-expecting
it to return X to some calling code. But you need to get used to Prolog's
unification system. If you are expecting to have one known value and are
looking for some associated second value that the predicate will find for
you, you should expect to have (at least) two variables in the head of the
predicate. Nothing is ever "returned" from a Prolog predicate: instead, you
are expecting that the variables in the head will end up bound to values if
the search finds valid solutions. So, as you discovered later,
is_mother(Child,Mother):-
...feels much more likely to be the right kind of thing you want in your
program.
btw, although this is partially a religious thing, I would say that your
choice of predicate name and variable order is not necessarily very clear.
I would go for "is_mother_of" because that suggests a relationship between
two things, rather than just a property of one entity. (You might also want
to have an is_mother( Mother ) predicate which is used specifically to
identify all women who are mothers, irrespective of their children's
identities.)
I also prefer
is_mother_of( Mother, Child )
in the same way that I would prefer
is_greater_than( BigNumber, SmallNumber )
...but some people think the other way around makes more sense to them.
(Shrugs.) Just be consistent, I suppose.
This predicate also reads a bit weirdly:
> siblings(Father,Mother) :-
> is_father(X, Father),
> is_mother(X, mother).
As you may have realized, there is an error here because on the last line
you use 'mother' with a lower case m, making it an atom, instead of
'Mother' with an upper case M, which would make it a variable, which is
what you want. But leaving that aside, there are all sorts of problems with
this clause as written. This seems to be a clause that identifies parents
who share the same child in common. I don't really think these two people
would usually regarded as "siblings" unless the society was an unusual one.
You might have wanted something like this:
siblings( Sib1, Sib2 ) :-
parent( X, Sib1 ),
parent( X, Sib2 ),
Sib1 \= Sib2.
This would potentially identify half-siblings as well, though, and would
return (possibly-unwanted) duplicate solutions for "full" siblings linked
through the same male AND female parent. Indeed, you might want to think
about specifying rules for both half-siblings and full-siblings, then
adding one that treated both these relationships as a more generic sibling
relationship.
Note the line that specifies that Sib1 and Sib2 should not be the same.
Without this, every person with a parent would be treated as being their
own sibling.
KJ
-------------- next part --------------
HTML attachment scrubbed and removed