关于约束的prolog推理

时间:2017-08-17 09:41:17

标签: prolog

我试图使用Prolog来推理约束,然后查询知识库以将这些约束传递给求解器(不能使用clpfd)。

%a first example would be constrainsquare(Row,Col,Val)
constrainsquare(1,1,3).
constrainsquare(1,2,2).

然后我可以使用类似bagof/3的内容查询所有约束。这不是令人满意的,因为我也希望能够写

 constrainsquare(3,4,8):-constrainsquare(3,3,7).

如果解决方案在位置7处有3,3的能力;它必须在8位置3,4。 现在,您无法再使用bagof/3等内容收集所有约束。

你如何在prolog中以理想的方式做到这一点?

请注意,我不能简单地做

constrainsquare(L) :-
  member(cs(1,1,3),L),
  member(cs(1,2,2),L),
  member(cs(3,4,8),L),
  member(cs(3,3,7),L).

因为我定期收到关于解决方案的新事实,不能改变现有事实。

目前,我正在考虑使用约束列表并执行类似

的操作
info(cell(1,1,3)).
info(cell(1,2,2)).
constrainsquare(I,[I]).
partialinfo(cell(3,4,8),cell(3,3,7)).
....

然后通过运行bagoff来获取[cell(1,1,3)],[cell(1,2,2)]...,然后折叠/追加到[cell(1,1,3),cell(1,2,2)]来查询它,但这感觉有点“meh”#。我想知道"正确的"方式。

1 个答案:

答案 0 :(得分:1)

假设您有查询,我们称之为Q,您希望运行一系列假设事实。我们将这组事实称为Facts。您可以编写一个谓词,该谓词将动态地对这些事实运行查询,如下所示:

what_if_query(Q, Facts) :-
    maplist(assertz, Facts),
    call(Q),
    maplist(retract, Facts).

如果Q为结果选择一个参数R,那么我们可以写:

what_if_query(Q, Facts, R) :-
    maplist(assertz, Facts),
    call(Q, R),
    maplist(retract, Facts).

然后,如果你有一个事实情景列表,你可以写:

what_if_scenarios(Scenarios, Q, Results) :-
    maplist(what_if_query(Q), Scenarios, Results).

A"事实"可以是任何可断言的Prolog术语,因此也可以是一个规则:(Head :- P1, P2, ..., Pn)。例如,您的事实清单"可能是:

[cs(1,1,3), cs(1,2,2), (cs(3,4,8) :- cs(3,3,7))]