我试图使用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”#。我想知道"正确的"方式。
答案 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))]