检查prolog

时间:2018-06-01 11:30:45

标签: prolog

我有很多事实代表一个单元格,其中包含行,列和某个单元格中的数字。我想检查这些事实,就像检查正常数组一样。

我试过这个功能,但它似乎不起作用,我认为我没有检查所有的事实。

allcolored(X,Y) :-
   cell(X,Y,_),
   X1 is X - 1,
   Y1 is Y - 1,
   allcolored(X1,Y1).

2 个答案:

答案 0 :(得分:0)

如果我理解正确,你想检查一对X / Y坐标,这些坐标所跨越的网格中的所有位置都被cell/3个事实所覆盖。为了论证,让我们考虑目前存在以下事实:

cell(1,1,100).
cell(1,2,200).
cell(1,3,300).
cell(2,1,110).
cell(2,2,120).
cell(2,3,130).

查看您对递归规则的尝试,尝试检查对于给定对,是否说2/2,对于2/2对是否有事实cell/3 1/1。但是你可能想要来检查是否覆盖了以下对:2 / 2,1 / 2,2 / 1和1/1。正如您在此序列中所看到的,X坐标减少到1,然后Y坐标减小,而X坐标再次从2开始。所以你需要以某种方式保留X的原始值。这可以通过带有附加参数的辅助谓词来完成。您的谓词allcolored/2将成为此类谓词的调用谓词,我们称之为allcolored_/3

allcolored(X,Y) :-
   allcolored_(X,Y,X).

正如@lurker已经指出的那样,你的谓词缺少一个基本情况,递归可以停止。一个显而易见的候选者是1/1:

allcolored_(1,1,_) :-
   cell(1,1,_).

然后需要一条规则来描述X和2之间的所有值必须由cell/3覆盖:

allcolored_(X,Y,Max) :-
   cell(X,Y,_),
   X > 1,
   Y >= 1,
   X0 is X-1,
   allcolored_(X0,Y,Max).

当X达到1时,还有一个额外的规则来描述下一个较低Y坐标的变化:

allcolored_(1,Y,Max) :-
   cell(1,Y,_),
   Y > 1,
   Y0 is Y-1,
   allcolored_(Max,Y0,Max).

现在,您可以测试由您提供的坐标跨越的网格是否被事实cell/3覆盖:

?- allcolored(2,2).
true ;
false.

?- allcolored(2,3).
true ;
false.

?- allcolored(3,3).
false.

请注意,上面的代码假设网格中的最小坐标是1.要更改它,例如0,您必须将目标X >1Y >= 1Y > 1中的1替换为0。另请注意,由于目标的排序(首先是cell/3目标),您还可以提出问题,例如 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.

答案 1 :(得分:0)

不检查范围内每个索引对的事实是否存在,而是检查某些对不存在的事实是否存在范围内的指数:

allcolored(X,Y) :- 
    \+ (between(1,X,A), between(1,Y,B), \+ cell(A,B,_)).

这说明:allcolored(X,Y)在允许范围(A, B1..X)中没有索引1..Y的情况下成立cell(A,B)存在。

换句话说,“给定区域中没有空单元格”相同,“给定区域中的所有单元格都已满”