2

我正在尝试制作一个 Prolog 谓词iscontained/2:如果在给定中列出iscontained(List, Search),则返回,如果没有。如果它是一个输入的变量,那么它只返回它等于列表中的每个元素。true.SearchListfalse.

例子:

?- iscontained([a, b, c], a).

true.

?- iscontained([a, b, c], d).

false.

?- iscontained([a, b, c], A).

A = a;
A = b;
A = c;
false.

我需要朝正确的方向推动,而不是要求伸出援手,除非你知道快速的方法。任何帮助表示赞赏,谢谢。

4

3 回答 3

3

请注意,经常提出的member/2谓词承认根本不是列表的解决方案:

?- 成员(e,[e|非列表])。
真的。

这在很多情况下都不是什么大问题,但还是应该提一下。

仅允许列表的自然对称定义使用 DCG:

... --> [] | [_],...

包含(Es,E):-
   短语((...,[E],...),Es)。

The...是一个非终结符,表示任意序列。

虽然对于这个小例子来说这完全是矫枉过正,但它为您提供了更多有趣模式的模板。喜欢

包含两次(Es,E):-
   短语((...,[E],...,[E],...),Es)。
于 2012-03-23T01:11:10.160 回答
2

既然您肯定已经提出了解决方案,我想提一件事:

经典版本:

成员(项目,[项目|_列表])。
成员(项目,[_Head|List]):- 成员(项目,列表)。

在找到可能的最后一个元素后留下一个选择点,即:

?-成员(A,[1,2,3])。
A = 1;
A = 2;
A = 3 ;
假的。

尽管

成员2(项目,[头|列表]):-
    member2(列表,项目,头)。

member2(_List,项目,项目)。
member2([Head|List], Item, _PreviousHead) :-
    member2(列表,项目,头)。

将空列表同时视为最后一个元素并允许优化:

?- member2(A, [1, 2, 3])。
A = 1;
A = 2;
A = 3。

这就是 SWI-Prolog 中使用的版本(当然还有 Jekejeke Prolog 和其他版本)。它的作者是 Gertjan van Noord。

这只是为了提醒您,虽然自己提出实现的练习member/2非常好,但它不应该导致您事后不使用内置插件,它们通常经过微调并且更高效!

于 2012-03-22T10:24:05.447 回答
2

您将需要考虑两种情况。我将把规则的主体留给你。

  • iscontained([A|Xs],A)
  • iscontained([X|Xs],A)

[编辑删除对空列表的引用:空列表不包含任何内容:如果遇到,谓词失败。]

于 2012-03-22T01:04:54.290 回答