编写一个接受包装常量的函数,但只有一个级别

时间:2017-06-04 13:28:51

标签: prolog

我想编写一个函数(道歉可能没有在这里使用正确的术语wubble这对于那些常量的特定常量是真的如果包裹成另一个常数,但只有一层深!例子:

% are supposed to be TRUE:
?- wubble(foo).
?- wubble(bar).
?- wubble(wrapper(foo)).
?- wubble(wrapper(bar)).

% are suppoed to be FALSE:
?- wubble(not_in_knowledge_base).
?- wubble(wrapper(wrapper(foo))).

天真(至少在我脑中)的实现看起来像这样:

wubble(foo).
wubble(bar).

wubble(wrapper(wrapper(_))) :- !, fail.
wubble(wrapper(X)) :- wubble(X).

这适用于上面的查询。但是,我无法使用此实现枚举X的所有有效wubble

?- wubble(X).
X = foo
X = bar

因此缺少X = wrapper(foo)X = wrapper(bar)。是否有可能以某种方式修复我的实现?

2 个答案:

答案 0 :(得分:4)

您可以将事实与规则分开:

wubble_(foo).
wubble_(bar).

wubble(X) :- wubble_(X).
wubble(wrapper(X)) :- wubble_(X).

答案 1 :(得分:2)

正如OP所指出的,在这个特殊情况下的一个解决方案如下:

wubble(foo).
wubble(bar).

wubble(wrapper(X)) :- wubble(X), ((X = wrapper(_), !, fail); true).

由于他也要求对这种模式进行解释,这是我最好的镜头:

鉴于上述知识库,wubble(X).这样的查询会从上到下查看与目标wubble(X)统一的事实或规则主管。如果它找到了一个事实,例如wubble(foo),那么目标就会成功,将X与事实的内部术语统一起来,在这种情况下foo。之后,我们可以告诉Prolog回溯到最后的选择点(Prolog在此过程中构建的深度优先搜索树中的节点),在这种情况下由原始目标{{给出1}}并让它寻找该目标的其他解决方案。如果我们在这里这样做,我们当然会得到第二个常数wubble(X)的事实。

现在为有趣的部分。如果我们再次回溯,那么满足目标wubble(bar)的唯一方法就是满足你的规则的前提。现在让我们机械地完成这个。这可能会令人惊讶,但wubble(X)wubble(wrapper(X))结合在一起;你必须将这些wubble(X)视为独立的。在查询X和规则定义wubble(X)的情况下,wubble(wrapper(X)) :- ...都只是本地名称。实际上,这两个变量在这种情况下是独立的,未经实例化的变量,并且由于未实例化的变量基本上与所有内容相结合,因此我们有X,因此规则的头部与我们的查询匹配。我们现在应该分别为查询和规则调用X = wrapper(X)X1

现在规则的尾部是一个连词,所以我们首先尝试满足第一个目标X2,这会创建一个新的选择点。现在,这个过程基本上重新开始:我们从上到下搜索知识库,找出与之相结合的东西,首先找到wubble(X)。因此,wubble(foo)现已与X2统一,我们会检查现在与foo合并的第二部分是否成功,因为X2 = foo。因为合并的两个目标都成功foo \= wrapper(_),我们的原始目标也会成功X2 = foo

从这里回溯基本上将我们带回到第二个选择点,由规则中的第一个目标创建。接下来,我们找到X1 = wrapper(X2) = wrapper(foo),它会再次检查结合的第二部分,我们的原始目标会成功X2 = bar

接下来,我们再次达到规则;我们统一X1 = wrapper(bar),我们的新目标是X2 = wrapper(X3),创建一个新的选择点,这会成功wubble(X3),第二部分也会检出。所以现在我们进入一层,我们有X3 = foo。这不符合第二部分的结合!它会触发X2 = wrapper(foo),因此我们!, fail的原始目标,即我们统一wubble(X1)失败。但不仅如此,我们还会削减,这消除了第一次递归X1 = wrapper(X2) = wrapper(wrapper(foo))调用及其下方所有内容的选择点,因此我们甚至不再尝试kippleX3 = bar。< / p>

所以我们回到目标X3 = wrapper(X4)的原始选择点;但是数据库中没有与此相匹配的条款,所以我们已经完成了。

现在我知道这可能很难以文本形式出现,所以这是我尝试可视化搜索树:

Search three for the query <code>wubble(X)</code>. Red signifies what the cut ... well cuts.