Prolog - '会员名单

时间:2014-11-18 18:44:49

标签: list prolog

我有一个名为member的函数,它应该作为参数: 1)一个名字 2)名单。

名称列表已在我的程序中定义,因此我希望能够使用名称和已在程序中初始化的列表调用该方法。

例如,我的Prolog程序包含......

namesList(mike,joe,bob,jill).

member(Element, [Element|_]):-!.
member(Element, [_|Tail]):-member(Element,Tail).

因此,当我在Prolog提示符并键入member(mike,namesList).时,Prolog应该输出true,而是打印false

我是否正确调用了该函数,或者我是否可以不使用已经实例化的列表?

1 个答案:

答案 0 :(得分:1)

首先,Prolog没有功能:它有谓词

其次,使用方括号 - [a,b,c,d]编写非空的prolog列表,其中空列表由原子[]表示。列表实际上由结构./2表示,其中第一个参数是列表的第一个项目(头部),第二个参数是列表的其余部分,或者是另一个非空列表,或者是空列表本身。这就是编译器编写者喜欢调用 syntactic sugar 的东西。所以

  • [a]完全等同于.(a,[])
  • [a,b]完全等同于.(a,.(b,[]))
  • [a,b,c]完全等同于.(a,.(b,.(c,[])))

  • [A|B].(A,B)完全相同。

您可以看到为什么方括号表示法更容易使用。

所以...你可以存储你的名单:

names_list( [mike,joe,bob,jill] ).

在这种情况下,您可以说:

?- names_list( Names ) , member(mike,Names) .
true.

然而 ...如果您以更加......类似prolog的方式维护您的名字,您可能会觉得更容易:

name( mike ) .
name( joe  ) .
name( bob  ) .
name( jill ) .

则...

  • 您可以通常的方式检查是否存在:

    ?- N = sam , name(N) ,
    false.
    
  • 或者,您可以通过回溯来迭代它们:

    ?- name(N).
    N = mike ;
    N = joe ;
    N = tim ;
    N = jill.
    
  • 而且,如果您确实需要它们作为列表,那么很容易以这种形式获取它们:

    ?- findall(N,name(N),Ns).
    Ns = [mike, joe, tim, jill].
    

最后,应该注意可以从

中提取名称列表
names_list( mike , joe , bob , jill ).

但它并不是世界上最优雅的东西:

extract( Name , Arguments ) :-
  atom(Name) ,
  current_functor(Name,Arity) ,
  length(Arguments,Arity) ,
  Goal =.. [Name|Arguments] ,
  callable(Goal) ,
  call(Goal)
  .

一旦你有了,你可以说:

?- extract(names_list,Names) , member(mike,Name).
true.