Prolog中的可选绑定

时间:2018-06-04 12:38:50

标签: prolog

让我们想象一个简单的家谱事实数据库,其中mother(M, C)father(F, C)表示M / F是孩子C的母亲/父亲。< / p>

我写了一条规则,找到一个孩子的已知父母(零,一个或两个):

parents(C, M, F) :-
  (mother(M, C) -> true; true),
  (father(M, C) -> true; true).

如果已知MF,则会将其绑定,否则会将其解除绑定。

它工作正常,这意味着对于一组事实:

mother(m1, c1).
father(f1, c1).
mother(m2, c2).

parents(c1, M, F)的调用会返回:

M = m1,
F = f1.

parents(c2, M, F)返回:

M = m2.

但使用箭头操作符对我来说似乎有点奇怪。我错过了什么基本的东西?可以避免/简化(X -> true ; true)来电吗?

任何帮助表示感谢。

干杯,

2 个答案:

答案 0 :(得分:4)

从逻辑角度来看,此计划中的主要错误是不完整

例如,考虑最常见的查询

?- parents(X, Y, C).
X = c1,
Y = m1.

因此,报告<{1}}的没有解决方案

但是存在这样的解决方案,如下所示:

?- parents(c2, Y, C).
Y = m2.

那么,,是否有解决方案?

如果您使用c2和其他违反代码的逻辑纯度的构造,则几乎总是会出现错误。有关详细信息,请参阅

因此,从逻辑的角度来看,我只能建议避免这样的结构,因为它们打破了逻辑编程语言的主要优势:开始逻辑的能力< / em>关于你的节目。

相反,请关注您想要描述的关系的明确描述,并说明使它们成立的条件。这将允许您以合理的方式使用Prolog程序。

编辑:我觉得你更喜欢拙劣的程序。为此,我建议 (->)/2 ignore/1ignore(Goal)称为Goal成功。您可以使用它来简化程序,并确保它仍然不完整。

答案 1 :(得分:1)

Prolog是一种真实的脚踏实地编程语言。它有一个纯粹的子集。 两个都有自己的位置。

once( (A ; true) )是问题的答案&#34;我们如何简化(A -> true; true)&#34;。

如果你想要更高的纯度,你可以使用&#34;软剪切来编写(A *-> true ; true )&#34; *->承认来自成功A所有解决方案,并且仅在A未生成任何。另见例如我的this answer可以进行更多讨论。

另一个变体是(A ; \+ A)