hello
hello

Reputation: 33

prolog relation and comparison

Let said I have these relations

drive(adam, van).
drive(betty, tank).
drive(adam, truck).
drive(adam, convertible).

how do I write a condition to find out adam drives three different vehicles?

I tried this, but this didn't work.

drivethree(A):-    
  drive(A, X),
  drive(A, Y), 
  drive(A, Z),
  X = not(Y),
  X = not(Z),
  Y = not(Z).

Upvotes: 2

Views: 140

Answers (2)

false
false

Reputation: 10142

At first, you might want to understand why your program does not work. After all, this might not be the only program that causes problems.

Identify incorrect test cases

The problem is that drivethree(X) does not succeed while you expect it to work. How can we localize the problem?

Generalize your program

One possibility is to generalize your program by removing one goal after the other. If the resulting program is still failing, an error must be even in the tiny remaining part! No need to read everything at once.

I will add a * in front of the goals to be removed:

:- op(950,fy, *).
*_.

drivethree(A):-    
   drive(A, X),
   * drive(A, Y), 
   * drive(A, Z),
   X = not(Y),
   * X = not(Z),
   * Y = not(Z).

In this new program drivethree(A) is still failing, but using only two goals. So there must be some bug in these two goals. To better see this, try the query:

?- drive(A, X), X = not(Z).
   false.

which again is failing. Now, we will try only the first goal:

?- drive(A, X).
   A = adam, X = van
;  A = betty, X = tank
; ... .

so X must be some atom, but X = not(Z) demands that it is a structure with functor not/1.

To express inequality it is best to use dif(X, Z) see this for more. In fact use rather:

drivethree(A):-
   dif(X, Y),
   dif(X, Z),
   dif(Y, Z),    
   drive(A, X),
   drive(A, Y), 
   drive(A, Z).

But back to your actual problem. What you are describing here are people who drive at least three vehicles.

Monotonicity

Now imagine, we are adding new facts drive/2 into your program. What will happen? Will adam still be a solution? In fact he will always be a solution if we only add further facts. This property is known as monotonicity. By adding further clauses you will only augment the set of solutions.

Just consider that you want to describe people who drive exactly three vehicles. And just hold on for a moment and think what will happen if we add new facts in such a program. Now it might happen that adam is no longer a solution because he might now drive four or more vehicles. Such a program is called non-monotonic. When starting to learn Prolog, keep away from non-monotonic programs for the first time and stick to monotonic ones.

Upvotes: 2

CapelliC
CapelliC

Reputation: 60034

Your code should work, if you intend 'drives at least 3', after a correction:

...
X = not(Y),
X = not(Z),
...

should be

...
X \= Y,
X \= Z,
...

Otherwise, for a more practical definition, of 'drives exactly 3', you can use setof/3:

drivethree(A) :- setof(V, drive(A,V), [_,_,_]).

Upvotes: 0

Related Questions