Domanda

I'm currently trying to learn a little Prolog. As an exercise I'm trying to solve the following riddle:

These rules are given:

*Every person that has neither a car nor a plane, has a bike.
*Every person that doesn't have a plane but has a bike, has a car
*Every person that doesn't have a plane but has a car, has a truck
*Every person that doesn't have a truck but has a boat, doesn't have a plane
*Every person that doesn't have a boat but has a plane, doesn't have a car

Now there's four people:

*Person1 doesn't have a car but has a boat
*Person2 doesn't have a boat but has a plane
*Person3 doesn't have a plane but has a bike
*Person4 doesn't have a bike but has a car

Which person doesn't have a truck?

What I've come up with so far is this:

doesnthave(car,pa).
has(boat,pa).
doesnthave(boat,pb).
has(plane,pb).
doesnthave(plane,pc).
has(bike,pc).
doesnthave(bike,pd).
has(car,pd).

has(bike,X) :- doesnthave(car,X),doesnthave(plane,X).
has(car,X) :- doesnthave(plane,X),has(bike,X).
has(truck,X) :- doesnthave(plane,X),has(car,X).
doesnthave(plane,X) :- doesnthave(truck,X),has(boat,X).
doesnthave(car,X) :- doesnthave(boat,X),has(plane,X).

Now this doesn't seem to be enough. Or is this not the way of solving puzzles like this in prolog?

Edit: It seems the first two statements are contradictory. Together they yield: Every person that has neither a car nor a plane, has a car. I'm not sure if there is a sensible solution to this.

È stato utile?

Soluzione

not sure about this solution, but a simpler representation of the knowledge surely helps:

has(car,   pa, n). has(boat,  pa, y).
has(boat,  pb, n). has(plane, pb, y).
has(plane, pc, n). has(bike,  pc, y).
has(bike,  pd, n). has(car,   pd, y).

has(bike,  X,  y) :- has(car,   X, n), has(plane, X, n).
has(car,   X,  y) :- has(plane, X, n), has(bike,  X, y).
has(truck, X,  y) :- has(plane, X, n), has(car,   X, y).
has(plane, X,  n) :- has(truck, X, n), has(boat,  X, y).
has(car,   X,  n) :- has(boat,  X, n), has(plane, X, y).

now we can query what's the ownerships (that note it's a one to many relation)

?- setof((P,T,R), has(T,P,R), L), maplist(writeln, L).
pa,boat,y
pa,car,n
pb,boat,n
pb,car,n
pb,plane,y
pc,bike,y
pc,car,y
pc,plane,n
pc,truck,y
pd,bike,n
pd,car,y
L = [ (pa, boat, y), (pa, car, n), (pb, boat, n), (pb, car, n), (pb, plane, y), (pc, bike, y), (pc, car, y), (pc, ..., ...), (..., ...)|...].

Note I placed the Person before the Transport, then we can inspect visually the result...

Seems that the solution is a triple...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top