【发布时间】:2017-08-17 09:41:17
【问题描述】:
我正在尝试使用 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).
如果解决方案在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 来查询它以获得[cell(1,1,3)],[cell(1,2,2)]...,然后折叠/附加到[cell(1,1,3),cell(1,2,2)],但这感觉有点'meh'。我想知道“正确”的方式。
【问题讨论】:
-
您能否举例说明您希望如何调用
bagof/3以及为什么它不起作用?如果我断言事实constrainsquare(1,1,3).、constrainsquare(1,2,2).、constrainsquare(3,3,7).和规则constrainsquare(3,4,8):-constrainsquare(3,3,7).并查询bagof([A,B,C], constrainsquare(A,B,C), L),我会得到L中列出的所有预期解决方案。所以我不太明白这个问题。 -
啊,是的,如果你先断言 constrainsquare(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)]。所以我可以查询我的知识库以获得传递给求解器的约束。
-
我觉得我的问题不是很清楚,但我不确定我可以改变什么来使它变得更好。我只想提供有关解决方案的事实,包括条件事实,然后收集可能的解决方案。
标签: prolog