Checking all of facts in prolog - prolog

I have a number of facts that represents a cell with a row,Column and the number in that certain cell, And I want to check those facts just like checking a normal array .
I tried this function but it doesn't seem to work ,I don't think I am checking all my facts.
allcolored(X,Y) :-
cell(X,Y,_),
X1 is X - 1,
Y1 is Y - 1,
allcolored(X1,Y1).

If I understand you correctly, you want to check if, given a pair of X/Y coordinates, all positions in the grid spanned by those coordinates are covered by cell/3 facts. For arguments sake, let's consider that the following facts are currently present:
cell(1,1,100).
cell(1,2,200).
cell(1,3,300).
cell(2,1,110).
cell(2,2,120).
cell(2,3,130).
Looking at your attempt for a recursive rule, you try to check if, for a given pair, say 2/2, there are facts cell/3 for the pairs 2/2 and 1/1. But you probably want to check if the following pairs are covered: 2/2, 1/2, 2/1 and 1/1. As you can see in this sequence, the X-coordinate is being reduced to 1, then the Y-coordinate is decreased while the X-coordinate starts over at 2 again. So you need to preserve the original value of X somehow. This can be done with an auxiliary predicate with an additional argument. Your predicate allcolored/2 would then be the calling predicate for such a predicate, let's call it allcolored_/3:
allcolored(X,Y) :-
allcolored_(X,Y,X).
As #lurker already pointed out, your predicate is lacking a base case, where the recursion can stop. An obvious candidate for that would be the pair 1/1:
allcolored_(1,1,_) :-
cell(1,1,_).
Then a rule is needed to describe that all values between X and 2 have to be covered by cell/3:
allcolored_(X,Y,Max) :-
cell(X,Y,_),
X > 1,
Y >= 1,
X0 is X-1,
allcolored_(X0,Y,Max).
And an additional rule to describe the change to the next lower Y-coordinate, once X reached 1:
allcolored_(1,Y,Max) :-
cell(1,Y,_),
Y > 1,
Y0 is Y-1,
allcolored_(Max,Y0,Max).
Now you can test if a grid, spanned by the coordinates you provide, is covered by facts cell/3:
?- allcolored(2,2).
true ;
false.
?- allcolored(2,3).
true ;
false.
?- allcolored(3,3).
false.
Note that the above code assumes that the smallest coordinate in the grid is 1. To change that, to e.g. 0, you have to replace the 1's in the goals X >1, Y >= 1 and Y > 1 by 0's. Also note that due to the ordering of the goals (the cell/3 goals first) you can also ask questions like What grids are there that are covered by the facts of cell/3? :
?- allcolored(X,Y).
X = Y, Y = 1 ;
X = 2,
Y = 1 ;
X = Y, Y = 2 ;
X = 2,
Y = 3 ;
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
false.

Instead of checking for the existence of a fact for every pair of indices in range, check for the non-existence of non-existence of the fact for some pair of indices in range:
allcolored(X,Y) :-
\+ (between(1,X,A), between(1,Y,B), \+ cell(A,B,_)).
this says: allcolored(X,Y) holds if there are no indices A, B in allowed ranges (1..X, 1..Y) for which the fact cell(A,B) doesn't exist.
In other words, "there are no empty cells in the given area" is the same thing as "all cells in the given area are full".

Related

How to stop backtracking and end the recursion in Prolog

I'm currently learning SWI-Prolog. I want to implement a function factorable(X) which is true if X can be written as X = n*b.
This is what I've gotten so far:
isTeiler(X,Y) :- Y mod X =:= 0.
hatTeiler(X,X) :- fail,!.
hatTeiler(X,Y) :- isTeiler(Y,X), !; Z is Y+1, hatTeiler(X,Z),!.
factorable(X) :- hatTeiler(X,2).
My problem is now that I don't understand how to end the recursion with a fail without backtracking. I thought the cut would do the job but after hatTeilerfails when both arguments are equal it jumps right to isTeiler which is of course true if both arguments are equal. I also tried using \+ but without success.
It looks like you add cuts to end a recursion but this is usually done by making rule heads more specific or adding guards to a clause.
E.g. a rule:
x_y_sum(X,succ(Y,1),succ(Z,1)) :-
x_y_sum(X,Y,Z).
will never be matched by x_y_sum(X,0,Y). A recursion just ends in this case.
Alternatively, a guard will prevent the application of a rule for invalid cases.
hatTeiler(X,X) :- fail,!.
I assume this rule should prevent matching of the rule below with equal arguments. It is much easier just to add the inequality of X and Y as a conditon:
hatTeiler(X,Y) :-
Y>X,
isTeiler(Y,X),
!;
Z is Y+1,
hatTeiler(X,Z),
!.
Then hatTeiler(5,5) fails automatically. (*)
You also have a disjunction operator ; that is much better written as two clauses (i drop the cuts or not all possibilities will be explored):
hatTeiler(X,Y) :- % (1)
Y > X,
isTeiler(Y,X).
hatTeiler(X,Y) :- % (2)
Y > X,
Z is Y+1,
hatTeiler(X,Z).
Now we can read the rules declaratively:
(1) if Y is larger than X and X divides Y without remainder, hatTeiler(X,Y) is true.
(2) if Y is larger than X and (roughly speaking) hatTeiler(X,Y+1) is true, then hatTeiler(X, Y) is also true.
Rule (1) sounds good, but (2) sounds fishy: for specific X and Y we get e.g.: hatTeiler(4,15) is true when hatTeiler(4,16) is true. If I understand correctly, this problem is about divisors so I would not expect this property to hold. Moreover, the backwards reasoning of prolog will then try to deduce hatTeiler(4,17), hatTeiler(4,18), etc. which leads to non-termination. I guess you want the cut to stop the recursion but it looks like you need a different property.
Coming from the original property, you want to check if X = N * B for some N and B. We know that 2 <= N <= X and X mod N = 0. For the first one there is even a built-in called between/2 that makes the whole thing a two-liner:
hT(X,B) :-
between(2, X, B),
0 is (X mod B).
?- hT(12,X).
X = 2 ;
X = 3 ;
X = 4 ;
X = 6 ;
X = 12.
Now you only need to write your own between and you're done - all without cuts.
(*) The more general hasTeiler(X,X) fails because is (and <) only works when the right hand side (both sides) is variable-free and contains only arithmetic terms (i.e. numbers, +, -, etc).
If you put cut before the fail, it will be freeze the backtracking.
The cut operation freeze the backtracking , if prolog cross it.
Actually when prolog have failed, it backtracks to last cut.
for example :
a:- b,
c,!,
d,
e,!,
f.
Here, if b or c have failed, backtrack do not freeze.
if d or f have failed, backtrack Immediately freeze, because before it is a cut
if e have failed , it can backtrack just on d
I hope it be useful

Recursion confuses me

I have understood the theory part of Recursion. I have seen exercises but I get confused. I've tried to solve some, some I understand and some I don't. This exercise is confusing me. I can't understand why, so I use comments to show you my weak points. I should have power (X,N,P) so P=X^N.
Some examples:
?- power(3,5,X).
X = 243
?- power(4,3,X).
X = 64
?- power(2,4,X).
X = 16
The solution of this exercise is: (See comments too)
power(X,0,1). % I know how works recursion,but those numbers 0 or 1 why?
power(X,1,X). % X,1,X i can't get it.
power(X,N,P) :- % X,N,P if only
N1 is N-1, % N1=N-1 ..ok i understand
power(X,N1,P1), % P1 is used to reach the the P
P is P1*X. % P = P1*X
What I know recursion, I use a different my example
related(X, Y) :-
parent(X, Z),
related(Z, Y).
Compare my example with the exercise. I could say that my first line, what I think. Please help me out with it is a lot of confusing.
related(X, Y) :- is similar to power(X,N,P) :- . Second sentence of my example parent(X, Z), is similar to N1 is N-1, and the third sentence is related(Z, Y). similar to power(X,N1,P1), and P is P1*X..
Let's go over the definition of the predicate step by step. First you have the fact...
power(X,0,1).
... that states: The 0th power of any X is 1. Then there is the fact...
power(X,1,X).
... that states: The 1st power of any X is X itself. Finally, you have a recursive rule that reads:
power(X,N,P) :- % P is the Nth power of X if
N1 is N-1, % N1 = N-1 and
power(X,N1,P1), % P1 is the N1th power of X and
P is P1*X. % P = P1*X
Possibly your confusion is due to the two base cases that are expressed by the two facts (one of those is actually superfluous). Let's consider the following queries:
?- power(5,0,X).
X = 1 ;
ERROR: Out of local stack
The answer 1 is certainly what we expect, but then the predicate loops until it runs out of stack. That's certainly not desirable. And this query...
?- power(5,1,X).
X = 5 ;
X = 5 ;
ERROR: Out of local stack
... yields the correct answer twice before running out of stack. The reason for the redundant answer is that the recursive rule can reduce any given N to zero and to one thus yielding the same answer twice. If you look at the structure of your recursive rule, it is obvious that the first base case is sufficient, so let's remove the second. The reason for looping out of stack is that, after N becomes zero, the recursive rule will search for other solutions (for N=-1, N=-2, N=-3,...) that do not exist. To avoid that, you can add a goal that prevents the recursive rule from further search, if N is equal to or smaller than zero. That leaves you with following definition:
power(X,0,1). % the 0th power of any X is 1
power(X,N,P) :- % P is the Nth power of X if
N > 0, % N > 0 and
N1 is N-1, % N1 = N-1 and
power(X,N1,P1), % P1 is the N1th power of X and
P is P1*X. % P = P1*X
Now the predicate works as expected:
?- power(5,0,X).
X = 1 ;
false.
?- power(5,1,X).
X = 5 ;
false.
?- power(5,3,X).
X = 125 ;
false.
I hope this alleviates some of your confusions.

Prolog - partially ordered set

There is a partially ordered set relation le(X,Y), when Y mod X = 0
(so there are le(1,5), le(5,70), le(7,14) etc.)
I have to make predicates
max(X) is X maximum element
greatest(X) is X the greatest element
defining max(X) is simple, because
max(X) :- \+ le(X,A), le(B,X). (there isn't any greater element and X is in set)
But how about greatest(X)?
For the least upper bound (LUB), you need two sets. First the argument set S, that you are asking for the LUB, and then the partial order T where you are searching for the LUB. So input is as follows:
T the partial order
S the set, S subset T
The code is then very similar as for the max. Just use range restricted formulas, that search over the partial order. This works in ordinary Prolog for finite partial orders.
Here is your divisibility example:
?- [user].
ls(X,Y) :-
Y mod X =:= 0.
bound(M,Y) :-
\+ (member(X,M),
\+ls(X,Y)).
lub(S,T,Y) :-
member(Y,T), bound(S,Y),
\+ (member(Z,T), bound(S,Z),
\+ls(Y,Z)).
^D
And here are some example runs:
?- lub([3,2],[1,2,3,4,5,6,7,8,9,10],Y).
Y = 6 ;
false.
?- lub([5,3],[1,2,3,4,5,6,7,8,9,10],Y).
false.
?- lub([5,3],[1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20],Y).
Y = 15 ;
false.
The above very general algorithm is not the efficientest, it is of order m^2*n^2, where n is the size of S and m is the size of T. For infinite partial orders you would need to invent something with CLP(X).

Prolog internal variable names

I have a large numbers of facts that are already in my file (position(M,P)), M is the name and P is the position of the player , I am asked to do a player_list(L,N), L is the list of players and N is the size of this list. I did it and it works the problem is that it gives the list without the names it gives me numbers and not names
player_list([H|T],N):- L = [H|T],
position(H,P),
\+ member(H,L),
append(L,H),
player_list(T,N).
what I get is:
?- player_list(X,4).
X = [_9176, _9182, _9188, _9194] .
so what should I do ?
You could use an additional list as an argument to keep track of the players you already have. This list is empty at the beginning, so the calling predicate calls the predicate describing the actual relation with [] as an additional argument:
player_list(PLs,L) :-
pl_l_(PLs,L,[]). % <- actual relation
The definition you posted is missing a base case, that is, if you already have the desired amount of players, you can stop adding others. In this case the number of players to add is zero otherwise it is greater than zero. You also have to describe that the head of the list (PL) is a player (whose position you don't care about, so the variable is preceded by an underscore (_P), otherwise the goal is just like in your code) and is not in the accumulator yet (as opposed to your code, where you check if PL is not in L) but in the recursive call it is in the accumulator. You can achieve the latter by having [PL|Acc0] in the recursive goal, so you don't need append/2. Putting all this together, your code might look something like this:
pl_l_([],0,_). % base case
pl_l_([PL|PLs],L1,Acc0) :-
L1 > 0, % number of players yet to add
L0 is L1-1, % new number of players to add
position(PL,_P), % PL is a player and
\+ member(PL,Acc0), % not in the accumulator yet
pl_l_(PLs,L0,[PL|Acc0]). % the relation holds for PLs, L0 and [PL|Acc0] as well
With respect to your comment, I assume that your code contains the following four facts:
position(zlatan,center).
position(rooney,forward).
position(ronaldo,forward).
position(messi,forward).
Then your example query yields the desired results:
?- player_list(X,4).
X = [zlatan,rooney,ronaldo,messi] ? ;
X = [zlatan,rooney,messi,ronaldo] ? ;
...
If you intend to use the predicate the other way around as well, I suggest the use of CLP(FD). To see why, consider the most general query:
?- player_list(X,Y).
X = [],
Y = 0 ? ;
ERROR at clause 2 of user:pl_l_/3 !!
INSTANTIATION ERROR- =:=/2: expected bound value
You get this error because >/2 expects both arguments to be ground. You can modify the predicate pl_l_/3 to use CLP(FD) like so:
:- use_module(library(clpfd)).
pl_l_([],0,_).
pl_l_([PL|PLs],L1,Acc0) :-
L1 #> 0, % <- new
L0 #= L1-1, % <- new
position(PL,_P),
\+ member(PL,Acc0),
pl_l_(PLs,L0,[PL|Acc0]).
With these modifications the predicate is more versatile:
?- player_list([zlatan,messi,ronaldo],Y).
Y = 3
?- player_list(X,Y).
X = [],
Y = 0 ? ;
X = [zlatan],
Y = 1 ? ;
X = [zlatan,rooney],
Y = 2 ?
...

How can I assert facts about all List members in Prolog?

I'd like to assert facts about all members of a List in prolog, and have any resulting unification retained. As an example, I'd like to assert that each list member is equal to five, but none of the below constructs does this:
?- L=[X,Y,Z], forall(member(E,L), E=5).
L = [_h27057686,_h27057704,_h27057722]
X = _h27057686
Y = _h27057704
Z = _h27057722
yes
?- L=[X,Y,Z], foreach(member(E,L), E=5).
L = [_h27057686,_h27057704,_h27057722]
X = _h27057686
Y = _h27057704
Z = _h27057722
yes
I would like a way to pose the query such that X=5,Y=5, and Z=5.
There is a lot of terminology that you might be getting wrong, or I am misunderstanding you.
"Equal to" is not the same as "could unify", or "unify", but it depends how you mean it.
With SWI-Prolog, from the top level:
?- X == 5.
false. % the free variable X is not the integer 5
?- unifiable(X, 5, U).
U = [X=5]. % you could unify X with 5, then X will be 5
?- X = 5.
X = 5. % X unifies with 5 (and is now bound to the integer 5)
The comment by CapelliC already has the answer that you are most likely after: given a list of variables (either free or not), make so that each variable in the list is bound to the integer 5. This is best done by unification (the third query above). The maplist simply applies the unification to each element of the list.
PS. In case you are wondering how to read the maplist(=(5), L):
These three are equivalent:
maplist(=(5), [X,Y,Z])
maplist(=, [5,5,5], [X,Y,Z])
X=5, Y=5, Z=5
And of course X=5 is the same as =(X,5).

Resources