0

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).
tas
  • 7,839
  • 2
  • 12
  • 21
Makdous
  • 23
  • 9
  • 1
    If the cells are already provided in the form `cell(X,Y,Value).`, why don't you just query for the desired row and column? For example: if your facts include `cell(2,2,120).`, you can ask _What is the value of the cell at row=2 and column=2?_ by querying `?- cell(2,2,Value).` to which Prolog will respond by answering `Value = 120`. Then you might want to ask _Are there any more solutions?_ by hitting the __;__-key: `Value = 120 ;` and, given you have only one fact for row=2 and column=2, Prolog will tell you that there aren't any: `false.` – tas Jun 01 '18 at 11:53
  • I don't see any information in your predicate that represents what it means for a cell to be "colored". `_` is an "anonymous" variable and using it means you don't care what the value is. – lurker Jun 01 '18 at 12:00
  • yes i don't want the number in the cell i just want to know if the whole fact exists because its a dynamic facts which i assert and just want to check that all of them are asserted – Makdous Jun 01 '18 at 12:03
  • If you query for a pair of X/Y-values you don't have a corresponding fact for, Prolog will answer `false`. That's how you know. But since I clearly don't get the point of your question, I politely ask you to clue me in by providing a few example facts and a few example queries that illustrate what behaviour you expect from `allcolored/2`. – tas Jun 01 '18 at 12:32
  • ok so its like grid of cells which have a diminsion of x & y where each cell is a fact that is maybe asserted or not and i want to check on each cell for the existing of that fact ,exmaple : if i send `allcolored(5,5)` i want it to check for the facts in a 5X5 grid – Makdous Jun 01 '18 at 13:11
  • 1
    About Prolog predicate behavior...Your predicate `allcolored(X,Y) :- cell(X,Y,_), ..., allcolord(X1, Y1).` fails for two reasons. First, you do not have a base case, so there's no condition to end recursion. Secondly, on the recursive call, the new query to `cell(X, Y, _)` starts over at the beginning of the asserted facts. So the new `cell(X, Y, _)` call will continue to find the first `cell/3` fact and succeed on each recursive call. You may need to use `findall/3` then process a list of cells. – lurker Jun 01 '18 at 13:35

2 Answers2

0

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.
tas
  • 7,839
  • 2
  • 12
  • 21
0

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".

Will Ness
  • 69,019
  • 8
  • 93
  • 175