0

Im using SWI-Prolog and when I try to run some predicates I write, they put a full stop at the end of my answer automatically and go straight to the next line. While some require me to either press enter or put the fullstop there myself. Why is this?

% range(1,5,X) -> X = [1,2,3,4,5]

range(X, X, [X]).
range(Low, High, [Low | Xs]) :-
    Low =< High,
    Low1 is Low+1,
    range(Low1, High, Xs).

This is an example of one I need to 'manually' either press enter or '.' to finish off, it also returns false if I press ';'. But I can't see why it would return false.

false
  • 10,264
  • 13
  • 101
  • 209
Sam
  • 454
  • 4
  • 18

1 Answers1

1

When you press ;, you are telling PROLOG that the last result is not good enough for you and it should backtrack to the last decision junction and take another branch. Prolog will not allow you to press ; if there is no decision points. In case of the sample function, the decision is taken when two of the parameters are equal, and both cases range(X, X, [X]). and range(Low, High, [Low | Xs])... are valid choices. The first result you are give will correspond to range(X, X, [X]). and will return [X], which is the last element of the range. If we assume that the original query was range(1,2,X), the search will end with range(2,2,[2]).. But when you press ; it will go to:

range(2, 2, [2|Xs]) ....

which will perform recursive query to

range(3, 2, Xs) ....

Which will eventually fail on Low =< High and produce the false result.

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
  • That makes sense! Thank you, is it generally accepted to write predicates like this with more than one answer or can I write some way of making mine finish 'properly'? – Sam Mar 16 '15 at 16:35
  • 1
    It's really depending on your requirements. If you know that only one valid result is expected, you can cut the backtracking with the `!` - the "cut" predicate. If your query can yield more than one valid results, and you might want have all of them (or some subset, which is not just the first result), it is good to have this functionality. Look here about the "cut": http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse43 – Eugene Sh. Mar 16 '15 at 16:43
  • @user2964689 predicate with more than one result are quite common. Prolog is all about finding solutions to a query or finding which specific values of a variable make a given relationship true, for which there can easily be more than one possible answer. That's one primary behavior that distinguishes Prolog from imperative languages. As an example, `member(X, [a,b,c])` will provide 3 solutions. – lurker Mar 16 '15 at 17:24
  • 1
    @user2964689 the "decision junction" that Eugene refers to in his answer is called a *choice point* in Prolog parlance. – lurker Mar 16 '15 at 18:13