从事实中获取子串

时间:2014-05-05 20:42:46

标签: prolog

所以我得到了像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,_)吗?

1 个答案:

答案 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).