我想检查用户输入的句子中的单词是否与列表中的至少一个字符串匹配。这就是我所拥有的。当我输入例如'banana car'时,我的谓词测试返回false(它不应该)。
在swish prolog中我写了enterQuery。当提示我写'香蕉车'。我回来了[香蕉,汽车] [香蕉,苹果]假
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
答案 0 :(得分:2)
您在显示的代码中执行了许多不必要的操作。
以下是我将如何从顶层直接执行此操作:
?- L = [banana, car], member(E, L), member(E, [banana, apple]).
L = [banana, car],
E = banana .
目前的问题是你的代码期望string
,但你给它一个原子。使用您的代码:
?- enterQuery.
|: "banana car".
[banana,car][banana,apple]
false.
请注意双引号!
仍然存在问题:现在,第一个列表中的banana
和car
为string
,第二个列表中为banana
和apple
是原子。
或者,来证明:
?- 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"].
答案 1 :(得分:1)
当面对(很多)文本解析时,在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].
鲍里斯已经解决了其他问题......