关于约束的prolog推理

关于约束的prolog推理,prolog,Prolog,我试图使用Prolog对约束进行推理,然后查询知识库,将这些约束传递给解算器(不能使用clpfd) 然后我可以使用类似于bagof/3的东西查询所有约束。这不是statisfactory,因为我也想能够写作 constrainsquare(3,4,8):-constrainsquare(3,3,7). 如果解决方案在位置3,3处有一个7的能力;它必须在位置3,4处有一个8。 现在,您无法再使用类似于bagof/3的方法收集所有约束 在prolog中,您将如何在思想上做到这一点 请注意,我不能

我试图使用Prolog对约束进行推理,然后查询知识库,将这些约束传递给解算器(不能使用clpfd)

然后我可以使用类似于
bagof/3
的东西查询所有约束。这不是statisfactory,因为我也想能够写作

 constrainsquare(3,4,8):-constrainsquare(3,3,7).
如果解决方案在位置
3,3
处有一个
7
的能力;它必须在位置
3,4
处有一个
8
。 现在,您无法再使用类似于
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查询它,获得
[单元格(1,1,3)],[cell(1,2,2)]…
,然后折叠/附加到
[单元格(1,1,3),单元格(1,2,2)]
,但这感觉有点“meh”。我想知道“正确”的方法。

假设您有一个查询,我们称之为
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).
然后,如果你有一个事实场景列表,你可以写:

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).
“事实”可以是任何可断言的Prolog术语,也可以是规则:
(Head:-P1,P2,…,Pn)
。例如,您的“事实”列表可以是:

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

您能否举例说明您希望如何调用
bagof/3
,以及为什么它不起作用?如果我断言事实
constraintsquare(1,1,3)。
constraintsquare(1,2,2)。
constraintsquare(3,3,7)。
规则
constraintsquare(3,4,8):-constraintsquare(3,3,7)。
和查询,
bagof([A,B,C],constraintsquare(A,B,C),L)
,我得到了
中列出的所有预期解决方案。所以我不太明白这个问题。啊,是的,如果你先断言平方(3,3,7),那么这个规则就行了。这里的问题是,真正的解决方案不需要在位置3,3处有一个7。给出的唯一信息是,如果那里有一个7,那么位置3,4也必然有一个8。我找不到一个“优雅”的解决方法,这通常意味着我在用根本错误的方式做某事,所以我在问什么是正确的方式。:)我想我没有按照你说的那样,用
bagof/3
收集所有约束条件
bagof/3
不收集约束,而是根据当前断言的事实和规则收集已知的解决方案。您可以做的是说(我在手机上,看不出我如何做代码标记)“hasto(cell(1,2,3))。hasto(cell(3,4,5))。然后使用bagof,您可以获得包含所有需求的列表[cell(1,2,3),cell(3,4,5)]。因此,我可以查询我的知识库,以获得传递给解算器的约束条件。我有一种感觉,我的问题不是很清楚,但我不确定我可以改变什么使其更好。我只想提供有关解决方案的事实,包括条件事实,然后收集可能的解决方案。老实说,我不知道assertz和retract的存在。可以用来做我想做的事情,谢谢你花这么多时间回答我的问题:p@camel-当您进入Prolog程序时,您静态地“断言”定义事实和规则的术语。Prolog还允许动态断言和收回术语。如果您浏览手册中的Prolog预定义谓词,您将在那里找到许多有趣的谓词。:)