#< Symbol In Prolog - prolog

I want to know what #< means in Prolog?
I encountered this symbol in this line of code while reading about the Bridge and Torch Problem:
select_one_or_two(L, [Sel1,Sel2], L2) :-
select(Sel1, L, NewL),
select(Sel2, NewL, L2),
Sel1 #< Sel2.

The comparative operators that start with # are more general than the ones that don't. With operators such as </2, you can only compare numeric values and expressions (involving literal numerics and variables that are instantiated with numeric values). So, with </2 you can do this:
?- X = 2, Y = 3, X + Y < 2*Y.
X = 2,
Y = 3.
?- X = 2, Y = 3, X + Y > 2*Y.
false.
?-
But you will get an error in the following cases if the expressions don't evaluate to a known numeric:
?- Y = 3, X + Y < 2*Y.
ERROR: </2: Arguments are not sufficiently instantiated
Or:
?- a < b.
ERROR: </2: Arithmetic: `a/0' is not a function
However, using #</2 you can compare lots of different types of objects in prolog. The comparison evaluation follows the rules described in the link that #Ankur gave. To understand these rules, you'll need to know what Prolog terminology means, such as term, functor, atom, etc (see, for example, Prolog Terms)
Looking at some examples:
?- a #< b.
true.
?- a(1) #< a(2).
true.
?- b(1) #< a(2).
false.
?- 20 #< a.
true.
These are pretty straight-forward, following the rules. Here's a more interesting case (from above):
?- Y = 3, X + Y #< 2*Y.
false.
Why would X + Y be considered "not less than" 2*Y? Prolog would internally look at this as:
`+(X,3) #< *(2,3).`
(Note Y is instantiated to 3.) These are compound terms (they aren't individual atoms or variables). If we look through the comparison rules, the matching rule is:
Compound terms are first checked on their arity, then on their functor
name (alphabetically) and finally recursively on their arguments,
leftmost argument first.
The arity of both terms is 2. The functor names are + and * respectively. Those are different. And in teh ASCII collating sequence, + comes after *. Therefore it is not true that + "is less than" *, and therefore not true that +(X,3) #< *(2,3). Thus, it is not true that Y = 3, X + Y #< 2 * Y.
Note also that #</2 doesn't evaluate numeric expressions. So even with X and Y instantiated as values, you will get:
?- X = 2, Y = 3, X + Y #< 2*Y.
false.
Whereas, when we had </2 here, this is true, since the expression X + Y < 2*Y, when evaluated, is true. When variables are simply unified, it understands that, however, so you would have:
| ?- X #< Y.
yes
But on the other hand:
| ?- X = 2, Y = 1, X #< Y.
no
In this case X #< Y is seen as 2 #< 1 due to the unification of X with 2 and Y with 1 and the numeric rule kicks in.
Having said all that, the use of #</2 in the predicate select_one_or_two enables that predicate to be usable on lists of all sorts of objects, not just numbers or fully instantiated numeric expressions. If it had used </2, then the following would work:
?- select_one_or_two([2,1,3], X, Y).
X = [2, 3],
Y = [1] ;
X = [1, 2],
Y = [3] ;
X = [1, 3],
Y = [2] ;
false.
But the following fails:
?- select_one_or_two([b,a,c], X, Y).
ERROR: </2: Arithmetic: `b/0' is not a function
?-
However, with the #< operator, it works:
?- select_one_or_two([b,a,c], X, Y).
X = [b, c],
Y = [a] ;
X = [a, b],
Y = [c] ;
X = [a, c],
Y = [b] ;
false.

Related

Prolog power of 2 recursion

Need help creating a recursive clause is a rule: X is a power of 2 only if there is a Y such that when adding Y to Y the result is
X, and Y is a power of 2. in prolog
We are going to define this predicate recursively. The followings are the fact and rule for detecting whether a numeral
is a power of 2 or not:
• The base clause is a fact: 1 is a power of 2 (because 1=20);
• The recursive clause is a rule: X is a power of 2 only if there is a Y such that when adding Y to Y the result is
X, and Y is a power of 2.
For example, the following shows how the queries should be performed:
| ?- powerOf2(succ(succ(succ(succ(0))))).
true ?
yes
| ?- powerOf2(succ(succ(succ(0)))).
no
The first query shows that 4 is a power of 2; while the second shows that 3 is not.
can not use the built-in is/2 predicate to perform arithmetic
To make it easier to represent natural numbers in Peano notation, you can use the following predicate:
nat(0, 0).
nat(N, s(P)) :-
succ(M, N),
nat(M, P).
Examples:
?- nat(3, P).
P = s(s(s(0))) ;
false.
?- nat(5, P).
P = s(s(s(s(s(0))))) ;
false.
To get the double of a Peano number, use the predicate:
double(0, 0).
double(s(A), s(s(B))) :-
double(A, B).
Examples:
?- nat(1, P), double(P, D).
P = s(0),
D = s(s(0)) ;
false.
?- nat(3, P), double(P, D).
P = s(s(s(0))),
D = s(s(s(s(s(s(0)))))) ;
false.
To check whether a Peano number is a power of two, use the predicate:
power_of_two(s(0)).
power_of_two(s(s(N))) :-
double(M, s(s(N))),
power_of_two(M).
Example:
?- between(1,9,N), nat(N,P), power_of_two(P).
N = 1,
P = s(0) ;
N = 2,
P = s(s(0)) ;
N = 4,
P = s(s(s(s(0)))) ;
N = 8,
P = s(s(s(s(s(s(s(s(0)))))))) ;
false.
Need help creating a recursive clause
The recursive clause will be:
power_of_two(1).
power_of_two(X) :-
X > 1,
Y is X / 2,
power_of_two(Y).
A base case which handles 1 being a power of two. And a case which handles when X is greater than one, Y is half X and recursively checks that Y is a power of two.
can not use the built-in is/2 predicate to perform arithmetic
You can't, but I can for the sake of illustrating the recursive clause you asked about. I'm assuming that since it tells you to use "succ(succ(succ(succ(0))))" you already have met that and have some code for adding/subtracting/dividing which you can reuse to replace Y is X / 2.

Boolean unification in Prolog?

I am struggling alreay for a long time with the
following problem. I want to make the usual unification
of Prolog more smart.
Basically I want that certain variables understand that
for example 0 = ~1 and 1 = ~0. This doesn't work normally:
?- op(300, fy, ~).
true.
?- X = ~Y, Y = 0.
X = ~0,
Y = 0.
I know that that CLP(B) can do it:
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.7)
:- use_module(library(clpb)).
true.
?- sat(X=:= ~Y), Y = 0.
X = 1,
Y = 0.
But I require something more lightweight than loading a full CLP(B) library. Any ideas?
It seems that SWI-Prologs when/2 does the job. I am using
the Quine algorithm from here to partially evaluate a boolean expression.
I can then define a Boolean let/2 predicate:
let(X, Y) :-
eval(Y, H),
term_variables(H, L),
( L== [] -> X = H;
cond(L, R),
when(R, let(X, H))).
cond([X], nonvar(X)) :- !.
cond([X,Y|Z], (nonvar(X);T)) :-
cond([Y|Z], T).
The above predicate will reevaluate the expression assigned
to the variable X when ever some variable inside the expression
changes. The expression is associate with the variable X through when/2. Since we see when/2 in the top-level, we see the associated expression:
?- let(X, ~Y).
when(nonvar(Y), let(X, ~Y))
?- let(X, Y+Z).
when((nonvar(Y); nonvar(Z)), let(X, Y+Z))
And we can also do our use case and even more:
?- let(X, ~Y), Y = 0.
X = 1,
Y = 0.
?- let(X, Y+Z), Y = 0.
Y = 0,
when(nonvar(Z), let(X, Z))
?- let(X, Y+Z), Y = 0, Z = 1.
X = 1,
Y = 0,
Z = 1

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

How to print all the facts in prolog

I am a beginner and I am using SWI Prolog to write a rule to print all the facts about addition of two numbers.The following is the code:
addition(X,Y,Z) :- Z is X+Y.
add(X,Y):-
between(X,Y,A),
addition(X,A,Z),
writeln(addition(X,A,Z)),
X1 is X+1,
add(X1,Y).
And the following is the output:
1 ?- add(1,2).
addition(1,1,2)
addition(2,2,4)
addition(1,2,3)
addition(2,2,4)
false.
As you can see the output addition(2,2,4) is repeating and addition(2,1,3) is missing. What am I doing wrong here??
addition/3 is a "rule", or a "predicate", not a fact. Anyway, you have defined it as:
% addition(X, Y, Z)
% Z is the sum of the integers X and Y
Now you want to apply this predicate to (and I am guessing here) each pair X and Y such that X is between A and B and Y is between A and B:
% add(A, B, Addition)
% Add all numbers X and Y that are between A and B
add(A, B, addition(X, Y, Z)) :-
between(A, B, X),
between(A, B, Y),
addition(X, Y, Z).
You will notice that you don't need recursion (or iteration): you can use the fact that between/3 is non-deterministic and will create choice points that will be evaluated on backtracking.
You can now call it like this:
?- add(1, 2, A).
A = addition(1, 1, 2) ;
A = addition(1, 2, 3) ;
A = addition(2, 1, 3) ;
A = addition(2, 2, 4).
You can press the ; or space to backtrack and evaluate the next solution.
The third argument to add/3 is unified with the term addition/3 in the head of add/3. It happens to have the same name as the predicate addition/3, but it could have been called anything.
If you insist on printing it out from a single call, you could use forall/2:
?- forall(add(1, 2, A), format('~q', [A])).

Prolog - descending order list

I am trying to write a function - decListRange(X,List) which give a list in range [X-1:1] by descending order. For example -
decListRange(9,List).
Will give -
List = [8,7,6,5,4,3,2,1].
I tried the following but it goes into infinite loop -
decListRange(1,[]) :- !.
decListRange(X,[H|Rest]) :-
H = X-1, NextX = X - 1 ,decListRange(NextX,Rest).
You have two problems. The first real one is that you need to use is instead of =:
H is X-1
This is needed to trigger arithmetic evaluation. Your second problem isn't a real problem but speaks to a bigger misunderstanding, which is that H and NextX are equivalent. Because Prolog only has bindings and not "assignables" as it were, you should never really need to create two "variables" with the same binding. There's no state being kept around for you to modify later.
Cleaning up both you get this:
decListRange(1, []) :- !.
decListRange(X, [H|Rest]) :-
X > 1,
H is X-1,
decListRange(H, Rest).
Edit 2: a clpfd implementation
:- use_module(library(clpfd)).
declist(N, L) :- N == 1, !, L = []. % green cut
declist(1, []).
declist(N, [N1|Ns]) :-
N #> 1,
N1 #= N - 1,
declist(N1, Ns).
This one has the properties #false mentions below in the comments:
?- declist(3, L).
L = [2, 1] ;
false.
?- declist(3, [2,1]).
true ;
false.
?- declist(N, [3,2,1]).
N = 4.
?- declist(N, X).
N = 1,
X = [] ;
N = 2,
X = [1] ;
N = 3,
X = [2, 1] ;
N = 4,
X = [3, 2, 1] ;
N = 5,
X = [4, 3, 2, 1] .
Edit: a short interlude on the difference between = and is.
In procedural languages = is almost always syntax for assigning a particular value to a variable. In Prolog, variables are bindings, and once established they cannot be directly modified by reassigning the variable a different value. Instead they work more like variables in math and logic, where the variable "stands in" for interesting values, but those values are themselves basically immutable. In Prolog, = essentially asks the unification engine to establish bindings. So if you were to do something like this:
?- name(X, Y) = name(bob, tony).
Prolog responds with variable bindings:
X = bob,
Y = tony.
Once those bindings exist, contradictory bindings will fail and affirmative bindings will succeed:
?- name(X, Y) = name(bob, tony), X = bob.
X = bob,
Y = tony.
?- name(X, Y) = name(bob, tony), X = william.
false.
The unification algorithm itself doesn't know anything about arithmetic. This has the pleasant side-effect that you can use any expression raw. For instance:
?- Expr = X + 3, Z + Q = Expr.
Expr = Z+3,
X = Z,
Q = 3.
This is probably really surprising looking. You may expect that somehow Prolog was smart enough to keep the expression around because it noticed X was a variable or something, but that isn't true either:
?- X = 4, Expr = X + 3, Z + Q = Expr.
X = 4,
Expr = 4+3,
Z = 4,
Q = 3.
Another way of looking at this is that Prolog is considering + to be just another operator, so X+3 is a fact just like add(X, 3) that doesn't necessarily have any special meaning. Whichever way you look at it, the is/2 operator exists to apply arithmetic reasoning and produce a value:
?- X = 4, Expr is X + 3.
X = 4,
Expr = 7.
Notice that Expr has the computed value but none of the original structure:
?- X = 4, Expr is X + 3, Z + Q = Expr.
false.
In practice, if you need to do a lot of reasoning with arithmetic, you will want to use a library like clpfd or clpqr depending on whether you're interested in integers or reals. This library enables you to do more interesting things more easily, like specify that an equation holds for values in a certain range and get those values out.

Resources