Search code examples
prolog

Prolog Inverse Predicate


I have the following statements in Prolog:

speak("Portuguese","Brazil").
speak("Portuguese","Africa").
speak("English","EUA").
speak("Spanish","Spain").
capital("Brasilia", "Brazil").
capital("Washington", "EUA").
capital("Madrid", "Spain").

I'm trying to get all countries that do not speak a language. For instance, getting all the coutries that do not speak Portuguese would return EUA and Spain. I tried the following code:

notSpeak(X) :- speak(_,Y), not(speak(X,_)),write(Y),nl,fail.

However, it just returns false. Someone could point me where the error is?

Thanks in advance!


Solution

  • Prolog is a logic language (Programming in Logic, get it?)

    You simply make the statement and let the inference engine do its work:

    not_speak( L, C ) :- % to find countries that don't speak language L
      speak(X,C),        % - find a country that speaks any language X
      L \= X .           % - provided that that language X is not language L
    

    And finding all the solutions is easy:

    not_speak_all( L, Cs ) :- findall( C , not_speak(L,C) , Cs ) .
    

    Giving us this program.

    not_speak( L, C ) :- speak(X,C), L \= X .
    
    not_speak_all( L, Cs ) :- findall(C, not_speak(L,C) , Cs ) .
    
    speak( portuguese , brazil         ) .
    speak( portuguese , africa         ) .
    speak( english    , usa            ) .
    speak( spanish    , spain          ) .
    speak( english    , united_kingdom ) .
    speak( dutch      , netherlands    ) .