【问题标题】:prolog constraint programming and forall/2prolog 约束规划和 forall/2
【发布时间】:2016-09-27 13:00:13
【问题描述】:

我正在使用 SWI 7.2.3 并且有以下程序:

?-use_module(library(clpfd)).
:- dynamic size/2,wall/2.

in_board(X,Y):-X #> 0,Y #> 0,size(N,M),X #=< N,Y #=< M.

wall_exists_line(X,Y,W) :- wall(X,Z),(Y #=< Z,W #=< Y;Y#=< W,Z#=< Y).

wall_not_exists_line(X,Y,W) :- not(wall_exists_line(X,Y,W)).

same_line(X,Y,Z,W):- X #= Z,in_board(Z,W),in_board(X,Y),wall_not_exists_line(X,Y,W).

我在这里使用约束编程,因为我希望 in_board 能够工作,即使 XY 都没有实例化(是的,我知道它可以通过其他方式实现,但我发现这更容易)。

如您所见,size,wall 是动态的,并且两者本质上都采用整数。

我的问题是,如果我断言size(4,4)wall(2,2) 并查询same_line(X,1,Y,3),它在应该返回X = Y, X in 1\/3..4(或类似的)时返回false。

我知道not(something(X)) 的意思是“在某事为真的地方不存在 X”,我想要“在某事 (X) 不为真的地方存在 X”(实际上我的意思是wall_exists_line)。

我尝试使用forall,但对于this 问题中所述的约束条件,forall 无法正常工作。

可以找到针对我的特定问题的解决方案但我更喜欢一般性的答案,那就是如何解决forall 通常会做的约束?

大目标

上面的程序只是prolog程序的一个子集,它应该解决akari游戏(也称为点亮,参见game),需要谓词same_line来确定哪些单元格被某些人点亮光。

size(N,M) 表示我们的板有N 行和M 列,wall(X,Y) 表示单元格(X,Y) 是一堵墙。

编辑

我之前没有wall_not_exists_line,我把not(wall_exists_line)直接放在same_line中,我以为引入单独的谓词可以解决它,但它没有。

我想把wall_exists_line改成它的否定,q and p的否定是not(q) or not(p)所以wall_exists_line会变成这样:

wall_not_exists_line(X,Y,W) :- not(wall(X,Z));(not(Y #=<Z);not(W #=<Y)),(not(Y#=<W);not(Z#=<Y)).

不幸的是,not(wall(X,Z)) 的意思是“不存在 X 或 Z,而 wall(X,Z) 为真”,我不想要这个,因为wall 是动态的,所以我无能为力。

【问题讨论】:

    标签: prolog clpfd


    【解决方案1】:

    我找到了解决方案。

    not(wall_exists_line(X,Y,W)) 将检查 XYW 的每个值(如果它们没有固定值)。

    in_board(X,Y) 约束 XY 在区间但不是固定值,因此 not 将尝试区间中的每个值。

    解决方案是在输入not 之前实例化变量X,Y,W,这是通过将in_board 更改为此:

    in_board(X,Y):-size(N,M),between(0,N,X),between(0,M,Y).
    

    这样between 将实例化XY,幸运的是between 给出了区间中的所有值。

    clpfd 和 between 之间的主要区别在于 clpfd 返回域,而 between - 如果第三个参数未实例化 - 返回两个值之间的每个值。

    【讨论】:

    • 使用 CLP(FD) 约束时,您不再需要 between/3:在需要时使用枚举谓词 indomain/1label/1labeling/2 获取地面解决方案。更优雅的方法是泛化您剩余的谓词也适用于任意变量,而不仅仅是基础整数!
    • 我试过indomainlabel等,我不知道怎么用。无论如何我不明白你的最后一句话,你所说的“地面整数”是什么意思?
    • 如果X 受到足够的约束,例如受到X in 0..N 的约束,您可以简单地声明indomain(X) 以获得X 的拟合整数。 “基本整数”是指 1、7、10 等术语。请注意,如果我们有一个约束 X in 0..5,那么 X 在概念上也绝对是一个整数,但它还不是实例化为一个基本术语。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多