我有一个单词列表,例如[cola,fanta,pepsi],我想写一个谓词,检查是否有任何元素以指定的字符开头。
到目前为止我的代码如下:
chk_first_letter(Char,[]):-fail.
chk_first_letter(Char, [H|T]):-
perform_check(Char, H);
chk_first_letter(Char, T).
perform_check(Char,[First|_]):-memberchk(Char, First).
然而,咨询我的文件并调用chk_first_letter(p,[cola,fanta,pepsi])即使pepsi以p开头也不会给我。
我尝试使用Char == First而不是memberchk(Char,First),但它也没有用。我不确定区别。
答案 0 :(得分:4)
你有一个原子列表,你的perform_check/2
比较了两个原子。原子不一个字符列表!您需要使用原子处理,例如:
perform_check(First, Word) :-
sub_atom(Word, 0, 1, _After, First).
http://gprolog.univ-paris1.fr/manual/html_node/gprolog043.html#sec200
本节中有许多其他内置函数可供使用,例如将原子分解为字符或字符代码(atom_chars/2
和atom_codes/2
)。但是sub_atom/5
也可以让你轻松做到:
任何长度的前缀:
sub_atom(Word, 0, _Length, _After, Prefix).
后缀:
sub_atom(Word, _Before, _Length, 0, Suffix).
答案 1 :(得分:3)
首次尝试:
chk_first_letter(Char, Atoms) :- member(A, Atoms), atom_chars(A, [Char|_]).
atom_chars / 2这是一个ISO谓词。
你的代码几乎可以正常工作,可以这样简化:
chk_first_letter(Char, [H|T]):-
atom_chars(H, [Char|_]);
chk_first_letter(Char, T).
答案 2 :(得分:2)
memberchk
。在您的情况下,您将为其提供单个字符。
然后你可以通过利用统一来完全取消它:
perform_check(Char,[Char|_]).
这假定您的字符串类型是字符列表(无论字符格式如何)。如果你打算直接对原子进行操作,你可以这样做:
perform_check(Char,String) :- atom_concat(Char,_,String)
还有一些步骤可以使您的代码更加惯用,但这似乎是错误的部分。