Why `X=1,X=1.` prints `X=1` instead of `true` - prolog

I'm learning the basics of Prolog and I was wondering why the following line prints X = 1 instead of true?
?- X=1,1=X.
X = 1.
--
The first X=1 in my command is an assignment, and the second one will be a check of equality.

There are no assignments or equality tests in your query, only unification of terms. The query succeeds by unifying the variable X with 1 and that's what the top-level reports: it tells which variable bindings makes the query true.
After the first goal in the conjunction, X = 1, succeeds, the second goal is the unification 1 = 1, which trivially succeeds.
P.S. Also note that Prolog systems differ in the way they report successful queries. Some print true, others print yes (the traditional way that successful queries are reported).

When the answer is true and a value is bound to variable at the top level, the value of the variable is displayed, which implies the result was true.
Here are some examples.
test_01 :-
X = 1,
X = 1.
test_02 :-
X = 1,
X = 2.
test_03(X) :-
X = 1,
X = 1.
test_04(X) :-
X = 1,
X = 2.
and when the examples are run from the top level using SWI-Prolog
?- test_01.
true.
?- test_02.
false.
?- test_03(X).
X = 1.
?- test_04(X).
false.
Here are some examples that are done only in the top level
?- X=1.
X = 1.
?- 1=1.
true.
?- 1=0.
false.
?- 1==0.
false.
The first X=1 in my command is an assignment, and the second one will be a check of equality.
X=1 is not an assignment it is a unification of the integer 1 to the variable X. The second X=1 is not a check of the equality, it is another unification of X to 1, but since X is bound to 1 by this time, it is really a different unification.
To do equality checking in Prolog use ==, e.g.
?- 1 == 1.
true.
?- 1 == 2.
false.
Also , is the logical and, so if
?- X = 1.
X = 1.
then 1 is bound to X and is true and similar for the second line in your question.
However the code has to be also viewed as
?- true,true.
true.
as opposed to
?- true,false.
false.
While ; is logical or
?- true;true.
true ;
true.
?- true;false.
true ;
false.
?- true;false;true.
true ;
true.
?- false;true.
true.
?- false;false.
false.
Notice that the first 3 answers have 2 results, but the last two answers have 1 result.

Related

SWI-Prolog: Call 3=2+1 -> Fail: 3=2+1

I'm working on something in Prolog and I wanted to check, at some point in my proogram, if some variable1 equals variable 2 + 1 (var1=var2+1). It said false. Variable1 is equal to 3 in my case, and var2 is equal to 2. It doesn't register as true and I can't understand why. I tried to 'trace' it, but still can't understand what the problem is, it just fails.
In Prolog 2+1 is just 2+1, or more canonical +(2,1). After all, it is only because some people see + as addition that 2+1 is equivalent to 3.
You can use is/2 [swi-doc] to evaluate an arithmetic expression, for example:
?- X is 2+1.
X = 3.
?- 3 is 2+1.
true.
You can also =:=/2 [swi-doc] to check if the two operands are equivalent if these are evaluated arithmetically:
?- 3 =:= 2+1.
true.
?- 4 =:= 2+1.
false.

Prolog only check variable is instantiated

In Prolog, is it possible to check if the variable is certain value only if the variable is instantiated.
? - my_rule(X).
my_rule(X):-
X = 4,
write('continue').
Here I am trying to check if the X is 4, if the X is 4 then we continue, but I also want the rule to continue if the X is _, but when it is called with something else, like X is 3 then it should not continue.
So the results would look like this:
?- my_rule(X).
continue
true.
?- my_rule(4).
continue
true.
?- my_rule(3).
false.
Have a look at var/1, atom/1 and ground/1:
var(X) is true if and only if X is a variable.
?- var(X), X= 1.
X = 1.
?- X=1, var(X).
false.
?- X=f(Y), var(X).
false.
atom(X) is true if X is an atom.
?- atom(a).
true.
?- atom(f(a)).
false.
?- atom(X).
false.
ground(X) is true if X is ground (does not contain variables).
?- ground(f(a)).
true.
?- ground(f(X)).
false.
The three predicates are deterministic (i.e. do not backtrack) and you can safely negate them.
Your code become something like this:
my_rule(4) :-
% handle the 4 case
my_rule(X) :-
var(X),
% general case
I'm just not sure if this is, what you want. In most programs, there should be no necessity to handle the variable only case separately. Also be aware that such meta-logical tests are outside the scope of classical logic. If compare the queries X = 1, var(X) and var(X), X = 1, you can see that the conjunction is not commutative anymore but in logic A ∧ B = B ∧ A holds.
You can use double negation ( \+(\+(...)) ):
In your example:
my_rule(X):-
\+(\+(X = 4)),
write('continue').
my_rule(X):-
check(X),
write('continue').
% A fact used to check a value.
check(4).
% A predicate that checks if X is unbound, e.g. a variable.
check(X) :-
var(X).
Verification of desired results.
?- my_rule(X).
continue
X = 4 ;
continue
true.
?- my_rule(4).
continue
true ;
false.
?- my_rule(3).
false.

Prolog: comparing predicate value with constant

I have some problems with prolog, specifically I can't compare a value of a predicate with a constant.
predicate(9).
compare(X,Y) :- X<Y.
Running the program:
?-compare(predicate(X),10).
Why doesn't it work? Thank you for your answers.
Predicates don't return values in the way that a function does.
This is C:
int nine() { return 9; }
int main() {
int x = nine(); /* x is now 9 */
}
This is Prolog:
% source
nine(9).
% from the top level
?- nine(X).
X = 9.
?- nine(X), X < 10.
X = 9.
?- nine(X), compare(C1, X, 10), compare(C2, 10, X).
X = 9,
C1 = (<),
C2 = (>).
Few things (trying not to use too much Prolog lingo):
What your predicate/1 and my nine/1 does is to unify its only argument with the integer 9. If the unification succeeds, the predicate succeeds, and now the argument is bound to 9. If the unification fails, the predicate fails.
?- nine(9).
true.
?- nine(nine).
false.
?- nine(X), nine(Y).
X = Y, Y = 9.
You will also notice that there is a standard predicate compare/3 that can be used for comparison of Prolog terms. Because predicates don't have a return value in the way that functions do, it uses an extra argument to report the result of the comparison. You could have instead tried something along the lines of:
% greater_than(X, Y) : true if X is greater than Y according
% to the standard order of terms
greater_than(X, Y) :- X #> Y.
But this is just defining an alias for #>/2, which is a predicate itself (but has been declared as an operator so that you can use it in infix notation).
?- #>(a, b).
false.
?- #>(b, a).
true.
Same goes for </2, which is a predicate for comparison of arithmetic expressions:
?- 2 + 4 =< 6.
true.
?- nine(X), X > 10 - X.
X = 9.
?- nine(X), X > 10.
false.
Like #Boris said before "Predicates don't return values in the way that a function does." Here you must try to instantiate the variables in the head of your rule.
If you are trying with you predicate compare/2 to find a number X greater than Y, and at the same time this number X should be a fact predicate/1, then add both conditions to the body of your rule or predicate compare/2
predicate(9).
compare(X,Y) :- predicate(X), X<Y.
Now if you consult:
?- compare(X,10).
The answer will be
X = 9
As you can see, 9 is smaller than 10, and at the same time 9 is a fact predicate/1. And that is the return value you are looking for.
Caution
Note that the operator >/2, requires that both sides are instantiated, so in this case you won't be able ask for the value Y in your predicate
?- compare(9, Y)
</2: Arguments are not sufficiently instantiated
Maybe and if it make sense, you can try to instantiate this variable to a fact predicate/1 too.
predicate(9).
predicate(10).
compare(X,Y) :- predicate(X), predicate(Y), X<Y.
?- compare(9,Y).
Y = 10

Not equal and not unify in Prolog

What is the difference between A \= B and not(A==B) in Prolog?
I found this http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse5
and this wiki page
http://en.wikibooks.org/wiki/Prolog/Built-in_predicates
but it didn't help me since there is no clarification to the difference, nor short meaning for \=.
Thanks.
A \= B is equivalent to not (A = B)
So lets compare =/2 and ==/2 first; from the swi-prolog manual:
?Term1 = ?Term2
Unify Term1 with Term2. True if the unification succeeds
#Term1 == #Term2
True if Term1 is equivalent to Term2.
Notice that =/2 tries to unify the terms and if it succeeds it's true while ==/2 just performs a check:
?- X = 1.
X = 1.
(implicit true.)
while
?- X == 1.
false.
and also:
?- X = Y.
X = Y.
?- X == Y.
false.
now, not/1 will invert the result and be true if =/2 or ==/2 was false.
for==/2 there is nothing complicated; if the terms were equivalent now it will return false otherwise true.
for =/2 you should remember that all unifications will be temporary:
?- \+ (\+ X = 1), print(X).
_G399
true.
(_G399 indicates that X is non-instantiated)

How do return both a variable result and a true/false in Prolog?

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. :(
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.
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.
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.
There is something to the previous answers by #aschepler, #Xonix, and #SQB.
In this answer, we use clpfd for expressing declarative integer arithmetics.
:- use_module(library(clpfd)).
We define largest/2 using the built-in predicate member/2, library meta-predicate 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.

Resources