Search code examples
prologclassificationnegation

Prolog classification


I'm developing a prolog game about finding animal. The user keeps an animal in his/her mind, answer the questions in game and the AI is trying to find the animal.

My problem is about separating the animal classes:

mammal    :- verify(gives_milk), !.
bird      :- verify(has_feathers), !.

I want to separate this two classes from each other. If the animal is mammal, the AI does not ask "has_feathers".


Solution

  • I don't quite follow how you will query whether an animal is a mammal: you will need the argument of the animal. So a predicate would look like:

    mammal(A) :-
        verify(A,gives_milk),
        !.
    

    evidently with some kind of database like:

    verify(cow,gives_milk).
    verify(crow,has_feathers).
    % ...
    

    Next you can use the negation in Prolog \+ to determine that an animal has no feathers:

    mammal(A) :-
        verify(A,gives_milk),
        \+ verify(A,has_feathers),
        !.
    

    Do not reuse bird and vice versa, because then you create an infinite loop (unless you allow tabulation support).

    More declarative style

    A more declarative style is probably to specify which aspects should hold and which can't hold. Something like:

    verifies(A,Pos,Neg) :-
        verify_pos(A,Pos),
        verify_neg(A,Neg).
    
    verify_pos(_,[]).
    verify_pos(A,[H|T]) :-
        verify(A,H),
        verify_pos(A,T).
    
    verify_neg(_,[]).
    verify_neg(A,[H|T]) :-
        \+ verify(A,H),
        verify_neg(A,T).
    

    Now you can for instance state:

    mammal(A) :-
        verifies(A,[gives_milk],[has_feathers,produces_eggs]).
    

    etc.