谓词来获取丢失的事实(predicate to fetch missing fact)

2019-11-03 05:22发布

我有一堆的事实。

f(1, John).
f(2, Peter).
f(3, Gordon).
f(4, Bono).
f(5, Carl).
f(6, Mick).

check([], []) .
check([f(X, Y)|L1] , [f(X, Y)|L2] ) :-  f(X, Y), check(L1,L2).

如果我运行检查谓词

check([ f(1, John), f(3, Gordon), f(2, Peter), _, f(6, Mick), f(5, Carl)], Group).

应打印。

Group = [ f(1, John), f(3, Gordon), f(2, Peter), f(4, Bono), f(6, Mick), f(5, Carl)].

黑色的空间充满了丢失的事实。 但我的程序进行打印。

Group = [ f(1, John), f(3, Gordon), f(2, Peter), f(1, John), f(6, Mick), f(5, Carl)].

它获取的第一个事实。 如何解决这个问题?

Answer 1:

你混淆了两两件事:回溯和迭代名单(通过尾递归)。

此外,你有你的“事实”数据库变量( JohnPeter等)时,你可能会真正去为原子? (如johnpeter ,或者,如果你想在资本, 'John''Peter' )。 你应该看到一堆“单变量”警告,如果你尝试编译此。 但事与愿违,

查询

?- f(X, Y).

会给你通过回溯

X = 1, Y = john;
X = 2, Y = peter

等等。

你写的谓词, check/2 ,在你给它,什么是实际执行的每一步是,它会检查是否存在是一个事实列表迭代f(X, Y)适合的XY你有提供。 (同样,因为你的第二个参数是变量的时刻,这也是不完全正确,但对此的解释并不重要)。

由于这样的事实f(1, John)是定义的第一个,这是相匹配的一个。 如果原路返回,你应该看到在同一地点的所有其他事实了。

但它是什么,你实际上是试图实现对我来说并不很清楚。

编辑:

你所试图实现是非常奇怪的。 你怎么知道你有多少个空白呢? 你必须知道所有的事实,知道这一点。 你试图让你的事实的排列?



Answer 2:

这是在之前解决这个问题的早期形式 。 下面是该解决方案的一个简单的适应:

f(1,john).
f(2,peter).
f(3,gordon).
f(4,bono).
f(5,carl).
f(6,mick).

check(L, C) :-
    check(L, [], C).

check([], _, []).
check([f(X,Name)|T], A, [f(X,Name)|C]) :-
    f(X, Name),
    \+ member(f(X, Name), A),
    check(T, [f(X,Name)|A], C).

这里的关键是,你必须沿着到目前为止(您发现的携带A ),因为每一个新的查询check ,查询到f “开始新的”搜索并从数据库的开始。 这不是一个回溯。 但是,当我们检查的成员,并找到该元素一个成员,我们原路返回到f查询来获取下一个,直到我们遇到一个不那么到目前为止,我们已经积累了名单中的一员。

测试运行:

| ?- check([f(1,john), f(3,gordon), f(2,peter), _, f(6,mick), f(5,carl)], Group).

Group = [f(1,john),f(3,gordon),f(2,peter),f(4,bono),f(6,mick),f(5,carl)] ? a

no
| ?-

正如在其他的答案,我挂出,这一技术将多张空白的工作。

你也可以这样做没有“结果”列表参数和实例原始列表自由变量:

check(L) :-
    check(L, []).

check([], _).
check([f(X,Name)|T], A) :-
    f(X, Name),
    \+ member(f(X, Name), A),
    check(T, [f(X,Name)|A]).

| ?- X = [f(1,john), _, f(2,peter), _, f(6,mick), f(5,carl)], check(X).

X = [f(1,john),f(3,gordon),f(2,peter),f(4,bono),f(6,mick),f(5,carl)] ? a

X = [f(1,john),f(4,bono),f(2,peter),f(3,gordon),f(6,mick),f(5,carl)]

(1 ms) no
| ?-

请注意,如果你想使用大写的名称,你可以将它们括在单引号,让自己原子,不变量。 例如, f(1, 'John')



文章来源: predicate to fetch missing fact
标签: prolog