所以我得到了像document(Title,Topic)
这样的事实。我想制定一个带有两个参数的规则。第一个是Keys,它是一个关键字列表,第二个是文档。
我希望得到结合我给出的关键词的文件的标题。
这就是我现在写的:
isInDoc([],'no'). %Recursion stops here. Don't know what to put as 2nd argument
isInDoc([H|T],document(Title,_)) :-
sub_string(case_insensitive,H,document(Title,_)),
isInDoc(T,document(Title,_)).
我想到的是我读了关键字列表的头部,看它是否是文档标题的子字符串。当我在SWI-Prolog中输入document(Title,_)
时,我会得到文档的标题。我想不出任何其他方式来访问文档的标题。如果我提出问题,我会收到此错误ERROR: table: sub_string/3: Type error:'text' expected, found document(_G6503,_G6504)
。
类型文本不是document(Title,_)
吗?
答案 0 :(得分:3)
在SWI-Prolog中,最近引入了sub_string / 5,但仅适用于字符串。要使用的正确谓词是sub_atom / 5(它也是ISO标准):
isInDoc(Tokens, document(Title, _)) :-
member(Token, Tokens),
sub_atom(Title, _,_,_, Token).
4 ?- document(T,_), isInDoc([and], document(T,_)).
T = 'Rules and Uncertainty' ;
false.
5 ?- document(T,_), isInDoc([and, certa], document(T,_)).
T = 'Rules and Uncertainty' ;
T = 'Rules and Uncertainty' ;
false.
我使用member / 2来“尝试”所有令牌,而不是编写递归规则。顺便说一句,既然你不希望找到任何一个令牌,你希望isInDoc / 2会失败,你可以完全放弃基本情况(但是因为你使用了no
,它永远不会匹配文档(_,_),效果是一样的。)
编辑也许这个片段可以更有用,将原子与文档的匹配分开:
isInDoc(Tokens, document(Title, _)) :- contains(Tokens, Title).
contains(Tokens, Atom) :-
member(Token, Tokens),
sub_atom(Atom, _,_,_, Token).