Search code examples
prolog

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).

Solution

  • 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.