I attempted to solve a problem where you are given a list of facts like:
parent(a,b).
where b is the parent of a,
and I needed to write a clause that determines if someone has at least 3 parents.
Here's my attempt
has3Parent(A) :- parent(A,B), parent(A,C), parent(A,D).
With my attempt,
if A has 1 parent, it will return true once,
if A has 2 parents, it will return true 8 times,
and if A has 3 parents, it will return true 27 times.
I'm rather new to Prolog and I cannot wrap my head around as to why this could be, so any help would be much appreciated.
Because you never assured that B, C and D were different people, you will always get true as long as A has even a single parent.
So the situation with 1 parent is simple; with 2, you have these eight combinations:
A = jane, B = jane, C = jane
A = jane, B = jane, C = john
A = jane, B = john, C = jane
A = jane, B = john, C = john
A = john, B = jane, C = jane
A = john, B = jane, C = john
A = john, B = john, C = jane
A = john, B = john, C = john
Even if you just say they're not equal, you'll get false for less than 3 and true for 3 or more; but you'll still be getting multiple solutions, because order will matter.
Ideally you'd use findall/3 to get the set of parents and count it, which will give you a singular solution. Something like:
has3Parent(A) :- findall(P, parent(A, P), Ps), length(Ps, 3).
(Also note that unlike the previous, this tests whether A has exactly 3 parents, not at least 3 parents. In order to get the previous idea to test for exactly 3 parents, you would have to say that besides B, C and D being different, there also does not exist E different from all of them that is also a parent. The findall solution though is easy to adapt for different kinds of comparison, since you are dealing with a number, not a bunch of unruly variables.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With