Prolog 检查元素是否为列表的成员

Prolog 检查元素是否为列表的成员,prolog,Prolog,基本上,我正在尝试创建标准成员谓词,以避免将模块加载到我的项目中 到目前为止,这是我的代码,但不幸的是它不起作用。我做错了什么?我甚至把切割操作符(!)放在那里,以确保它工作,但它不 /** * Checks if an element is part of a list * @param [H|T] List to evaluate * @param Elem Elem to check */ memberCheckSimple([], _):- !, fail. /* stop co

基本上,我正在尝试创建标准成员谓词,以避免将模块加载到我的项目中

到目前为止,这是我的代码,但不幸的是它不起作用。我做错了什么?我甚至把切割操作符(!)放在那里,以确保它工作,但它不

/**
* Checks if an element is part of a list
* @param [H|T] List to evaluate
* @param Elem Elem to check
*/
memberCheckSimple([], _):- !, fail.     /* stop condition */
memberCheckSimple([H|T], Elem):-
  Elem \= H,                            /* check if element equals head of list and negate it */
  memberCheckSimple(T, Elem).           /* loop */
memberCheckSimple(_, _).                /* only gets here if Elem belongs to list */

谓词逻辑的一个主要问题是,它是基于失败的,并且您试图使成功成为无失败的默认值。这通常与你想要的逻辑相反。你希望它以成功为基础,也就是说,你希望建立事实和规则来描述什么是真实的

您可以按如下方式进行播放。您知道,如果元素位于列表的开头,那么它就是列表的一个元素。因此,以下是正确的:

memberCheckSimple([H|T], H).   /* H is a member of [H|T] */
如果元素是列表尾部的成员,那么它也是列表的成员:

memberCheckSimple([_|T], H) :- memberCheckSimple(T, H).
这两条规则是你真正需要的。与上述规则之一不匹配的查询将失败,这正是您想要的

现在看看为什么基于失败的谓词不能正常工作,并且在失败案例中成功,这是因为以下规则:

memberCheckSimple(_, _).
这意味着任何事物都是任何事物的一部分。你必须承认,这似乎不符合逻辑(因为事实并非如此)。考虑到你先前的条款与削减:

memberCheckSimple([], _) :- !, fail.
如果第一个参数是空列表(
[]
),这将防止回溯到“universaltrue”子句,但如果其非空,则不会。例如,
memberCheckSimple([a],b)
最终将通过与第二个子句匹配的路径失败,然后与第一个子句匹配。但是第一个子句中的删节并不能阻止
memberCheckSimple([a],b)
对第三个子句进行回溯(和后续)。您可以通过执行
跟踪
来观察这一点

要完成基于失败的方法(我将再次强调,这是解决问题的错误方法,并且还有其他问题,例如不相关),您还需要在第二条中删去:

memberCheckSimple([H|T], Elem) :-
  Elem \= H,                    /* check if element equals head of list and negate it */
  !,
  memberCheckSimple(T, Elem).   /* loop */

你在代码中的注释表明了一个强制性的思维过程。例如,你所谓的“循环”实际上是一个“递归”。另外,正如在另一条评论中提到的,参数顺序更自然地表示为元素后跟列表,因为您将其命名为“member”,而不是“contains”。

注意,参数通常是:
member(El,Els)
memberCheckSimple(非元素,非列表)
succeeds@false是的,我知道,但是现在我所有的项目功能都是相反的,如果我现在试图改变它们,我会把事情搞得一团糟。所以,不妨让它保持一致(x)顺便说一句,我在stackoverflow上看到的每一篇序言都有你的身影!:p、 …但不幸的是,它不起作用。请解释一下你试过什么,什么不起作用。@潜伏者只要试一下,它就不会起作用了。memberCheckSimple([a,b,c],d)在应该说否时输出yes。