我有一个名为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
。
我是否正确调用了该函数,或者我是否可以不使用已经实例化的列表?
答案 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.