4

It sounds silly, but lets say my predicate largest/2 returns the largest element in a list...the output should look like this:

?- largest([1,2,3,4,5], X).
X = 5.
false.

I implemented largest, and it works like above except it doesn't output "false". How do I make it so it also outputs this "false." value? This is for an annoying assignment I have to finish. :(

false
  • 10,264
  • 13
  • 101
  • 209
Eteocles
  • 41
  • 1
  • 2

4 Answers4

9

That extra false. or No just means that the person running the program asked to get all possible solutions for X, not just the first possible solution.

On most interactive Prolog interpreters, you check to see if there is another solution by pressing the semicolon (;) key.

aschepler
  • 70,891
  • 9
  • 107
  • 161
1

If this was part of an assignment, it probably means that your predicate should not yield a second (possibly different) result after backtracking. Backtracking occurs if the user wants the next solution, often by pressing ;. The interpreter often indicates that another solution is possible when it knows there are still paths not fully evaluated.

Suppose you had a predicate foo/1 as follows:

foo(1).

foo(Bar) :-
   foo(Baz),
   Bar is Baz + 1.

If you ask foo(Bar), the interpreter will respond with Bar = 1. After repeatedly pressing ;, the interpreter will come back with Bar = 2, Bar = 3 and so on.

In your example, finding the largest of a list, should be deterministic. Backtracking should not yield a different answer.

It's up to you to interpret the assignment to mean that you have to allow backtracking but have it fail, or that it would be all right to not even have it backtrack at all.

SQB
  • 3,926
  • 2
  • 28
  • 49
1

sounds like impossible, as if predicate fails, no binding of free variables happens, see

 ?- A=5.
A = 5.

 ?- A=5,false.
false.

however

 ?- A=5;false.
A = 5 ;
false.

To achieve this you should make your predicate "largest" non-deterministic. But to me this seems pretty silly.

Volodymyr Gubarkov
  • 2,173
  • 20
  • 20
  • s(X): if I follow the question to a T, this somewhat odd answer is **it**. And it has great timing, too! – repeat Mar 25 '16 at 14:57
0

There is something to the previous answers by @aschepler, @Xonix, and @SQB.

In this answer, we use for expressing declarative integer arithmetics.

:- use_module(library(clpfd)).

We define largest/2 using the built-in predicate member/2, library maplist/2, and the finite-domain constraint (#>=)/2:

largest(Zs, X) :-
   member(X, Zs),            % X is a member of the list Zs
   maplist(#>=(X), Zs).      % all Z in Zs fulfill X #>= Z

Sample queries:

?- largest([1,2,3,4,5], X).
X = 5.

?- largest([1,2,3,4,5,4], X).
X = 5 ;
false.

?- largest([1,2,3,4,5,5], X).
X = 5 ;
X = 5.

?- largest([1,2,3,4,5,5,4], X).
X = 5 ;
X = 5 ;
false.

?- largest([A,B,C,D], X).
A = X, X#>=D, X#>=C, X#>=B ;
B = X, X#>=A, X#>=D, X#>=C ;
C = X, X#>=A, X#>=D, X#>=B ;
D = X, X#>=A, X#>=C, X#>=B.
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166