prolog如何逐步处理这个问题?

时间:2016-02-21 11:42:24

标签: prolog

我试图理解序言,但我坚持一个例子,你能解释一下prolog如何通过这个电话:

eli(2,[2,2,1],L)

使用这些事实:

eli(X,[],[]).
eli(X,[Y],[Y]).
eli(X,[X,X|L],L1) :- eli(X,L,L1).
eli(X,[Y|L],[Y|L1]) :- eli(X,L,L1).

结果是:

L = [1]
L = [1]
L = [2, 2, 1]
L = [2, 2, 1]

我不确定为什么。

提前致谢!

1 个答案:

答案 0 :(得分:0)

看起来你的谓词意味着删除任何元素的两个连续出现。

第一个子句,如果目标列表为空,则返回空列表。在这种情况下,事实中的X变量不是必需的。用匿名变量替换X.

eli(_,[],[]).

第二个子句与第一个子句类似,但如果它只包含一个元素,则它与目标列表匹配。变量X也没有必要。

eli(_,[Y],[Y]).

第三个子句,如果目标列表包含两个或多个元素,并且在列表的头部中两个元素都等于X,则不要将这两个元素复制到Result列表,并对{进行递归调用{1}}在规则正文中的谓词,继续搜索。

eli/3

在这种情况下,我们添加eli(X,[X,X|L],L1) :- eli(X,L,L1), !. 谓词,以避免在此规则成功后回溯。否则,您可能会得到不受欢迎的结果,例如测试中的cut 最后一个子句,将目标列表头部中的元素复制到Result列表,并继续递归调用,当目标列表为空或仅包含一个元素(前两个子句)时,这将停止。

L = [2, 2, 1]

现在这是你的谓词eli(X,[Y|L],[Y|L1]) :- eli(X,L,L1).

eli/3

测试:

eli(_,[],[]).
eli(_,[Y],[Y]).
eli(X,[X,X|L],L1) :- eli(X,L,L1), !.
eli(X,[Y|L],[Y|L1]) :- eli(X,L,L1).