Search code examples
prologcomparebacktracking

Why does Prolog does not backtrack on comparison?


I would expect that the following should always be true if a comparison backtrack, right? unless it goes into an infinite loop!

 ?- Y=2 , random:random(1,3,X), X =\= Y.
 Y = 2,
 X = 1.

 ?- Y=2 , random:random(1,3,X), X =\= Y.
 false. 

but I got false! In general, my question is why doesn't comparison backtrack?


Thanks for all the answers. My confusion seemed to come primarily from my expectation of random keep generating new-random numbers, so I confused that comparison was not backtracking, instead, the reason was that random does its thing only once and fails afterwards. I was unaware of semi-determinate nature of some predicates. But now I can be on a lookout ;) for cases like this. thanks again.


Solution

  • Prolog works with what are called Horn-clauses. This means that each term individually, for example Y=2, is a separate goal in a question to be answered. The result will be yes or no for each goal, and if all goals answer yes, the question is answered with yes.

    What your code asks is as follows:

    %Is Y equal to 2 or can it be made equal? 
    %Yes, Y is a variable and can be assigned the numerical atom 2
    Y=2 ,
    %Give me a random number between 1 and 3. 
    %Is X equal to the random number or can it be made equal? 
    %Yes, X is a variable and can be assigned the outcome atom of random:random
    random:random(1,3,X), 
    %is the term contained within X NOT equivalent to Y?
    X =\= Y.
    

    You can check out existing comparison predicates in for example the SWI documentation or on Learn Prolog Now!.

    Depending on your implementation you can use trace and write to output the actual atoms in the variables, allowing you to explore how your program actually works.

    ?- trace, (Y=2 , random:random(1,3,X), write(X),nl, X =\= Y). %SWI-Prolog
    

    SWI-prolog online editor

    Infinite recursion looks like p(P) :- p(P).. It has a call to the question it is supposed to solve inside the answer itself, meaning to solve for p(P) it will check p(P), which never ends.

    Backtracking only happens when Prolog has choicepoints. Choicepoints are points where in the decision tree, there are MULTIPLE POSSIBLE WAYS to satisfy the question Prolog is currently processing. Prolog works from top to bottom, then left to right.

    Think of a cars salesman who gets asked "which car is the best for me?". He has more than one possible car to sell you, so he'll start showing you different cars that meet your criteria. The car needs to have a transport capacity of a volume over 400 liters? All cars that don't satisfy this condition are not presented as a solution.

    Prolog does a depth-first search, meaning it goes down to the first answer it finds, then checks whether there's other ways to answer it. If there is no result, the answer is no. If there is at least one solution, the answer is yes and you get all possible answers for your question. This way you only get results that satisfy a whole chain of goals you've set.