如何检查用户输入的字符串是否与列表中的字符串匹配?

How can I check whether an user imputed string matches a string in a list?

我想检查用户输入的句子中的单词是否与列表中的至少一个字符串匹配。这是我所拥有的。我的谓词测试 returns false 当我输入例如 'banana car' (它不应该)。

在 swish 序言中我写了 enterQuery。当出现提示时,我写 'banana car'。我回来了[香蕉,汽车][香蕉,苹果]false

enterQuery:-
read(X),
processQuery(X).

processQuery(X):-
split_string(X," ", " ", L),
write(L),
test(L).

test(L):-
write([banana, apple]),
common_member(L,[banana,apple]),
write('successs').

common_member(Xs,Ys) :-
member(E,Xs),
member(E,Ys).

当我查询时:

?- enterQuery.
|: 'banana car'.
[banana,car][banana,apple]
false.

相反,我希望:

?- enterQuery.
|: 'banana car'.
[banana,car][banana,apple]successs

您在显示的代码中做了很多不必要的事情。

以下是我直接从顶层执行此操作的方法:

?- L = [banana, car], member(E, L), member(E, [banana, apple]).
L = [banana, car],
E = banana .

目前的问题是您的代码需要一个 string,但您给了它一个原子。使用您的代码:

?- enterQuery.
|: "banana car".
[banana,car][banana,apple]
false.

注意双引号!

还有一个问题:现在第一个列表中的bananacarstring,而第一个列表中的bananaapple第二个列表是原子。

或者,演示:

?- read(X), string(X).
|: banana.

false.

?- read(X), string(X).
|: "banana".

X = "banana".

因此您还需要制作要比较的列表,从 [banana, apple]["banana", "apple"]

它仍然是非常混乱的代码,不清楚为什么你想用 read/1 阅读而不是像在这个答案顶部的第一个代码片段中那样输入它。

编辑:

如果您需要从顶层输入一个句子,没有什么能阻止您将其用单引号(对于原子)、双引号(对于字符串)括起来,并且仍然以 的形式输入谓词的参数!

下面是一些示例代码:

string_words(S, Ws) :-
        separators_string(Seps),
        split_string(S, Seps, Seps, Ws).

separators_string(Seps) :-
        findall(C,
                ( char_type(C, white)
                ; char_type(C, punct)
                ),
                Cs),
        string_chars(Cs, Seps).

加载后:

?- string_words("banana car", Ws).
Ws = ["banana", "car"].

?- string_words("Hello, how are you doing?", Ws).
Ws = ["Hello", "how", "are", "you", "doing"].

当面对(很多)文本解析时,在 SWI-prolog 中你可以尝试内置的 tokenize_atom/2。尽管名称如此,但它实际上可以与其他文本表示形式一起使用:

?- tokenize_atom('apple banana', L).
L = [apple, banana].

?- tokenize_atom("apple banana", L).
L = [apple, banana].

?- tokenize_atom(`apple banana`, L).
L = [apple, banana].

Boris 已经解决了其他细节...