【问题标题】:prolog reasoning about constraints关于约束的序言推理
【发布时间】: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


【解决方案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).

“事实”可以是任何可断言的 Prolog 术语,因此也可以是规则:(Head :- P1, P2, ..., Pn)。例如,您的“事实”列表可能是:

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

【讨论】:

  • 老实说,我不知道 assertz 和 Retract 存在。可以用来做我想做的事,感谢您在我令人困惑的问题上花费了这么多时间:p
  • @camel - 当您进入 Prolog 程序时,您是静态地“断言”定义事实和规则的术语。 Prolog 还允许动态 断言和撤回术语。如果您浏览手册中的 Prolog 预定义谓词,您会在那里发现许多有趣的谓词。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多