Prolog使用列表中的事实

时间:2017-10-31 13:01:50

标签: prolog

我在swi-prolog中遇到列表结构的问题。

rlTopic([
    [
        [noun],                          % find match for this          
        [
            [ 
                grammar([noun],1),       % use one of this          
                grammar([det,noun],1)           
            ],
            [
                noun(fox,1),               % fill one of the grammars
                det(the,1),                % with these words
                noun(cat,1)
            ]
        ]
    ],
    [
        [det,adj,noun],                                 
        [
            [ 
                grammar([verb,adj],1),       % use one of this          
                grammar([det,noun],1)           
            ],
            [
                det(the,1),               % fill one of the grammars
                adj(quick,1),             % with these words
                noun(cat,1),
                verb(ran,1)
            ]
        ]
    ],
 ....

我尝试使用[noun]找到匹配(来自输入)。在此之后,获取下一级别的一个语法并将其与单词匹配。找到语法现在可以正常工作,但是我将问题插入到语法中会有问题。

我的代码现在:

get_keyword(KeyList, [KeyList,_]).
get_response(RespList, [_, RespList]).

find_grammar([Grammars,Words],AtomGrammar):- 
            is_list(Grammars),
            find_grammar(Grammars,AtomGrammar),!;
            AtomGrammar = Grammars.

find_grammar(_,_).

find_match(Input, [FirstRecord|RestDatabase], ListOfResponse):-
    get_keyword(Keyword, FirstRecord),
    Keyword == Input, get_response(ListOfResponse, FirstRecord), !;
    find_match(Input, RestDatabase, ListOfResponse).

find_match(_, [_], _).

test(Input):-       
    rlTopic(ListOfRecord),
    find_match(Input, ListOfRecord, ListOfResponse), 
    find_grammar(ListOfResponse,G).

对于输入test([det,adj,noun]),输出应该是一个填充了单词的语法,如run quick

提前致谢!

1 个答案:

答案 0 :(得分:2)

我不完全确定我理解你在这里尝试做什么,我认为因为我们都被你创建的数据结构所挫败。在我看来,你喜欢尝试进行词性标注,然后解析一个自然语言句子,这是非常有趣的东西。这是我从未修改过的东西,但是有很多关于这个主题的好书,包括Ivan Bratko的着名书籍 Prolog Programming for Artificial Intelligence 和鲜为人知但费尔南多·佩雷拉非常有用的 Prolog和自然语言分析

这里有很多列表结构似乎正在阻碍,所以我现在要忽略它。您始终可以使用member/2使列表在商店中像事实一样工作。而你的第二个问题是,我认为你想要搜索noun/2det/2以及可能的其他词性,但是当你还没想到要搜索哪一个时,你就不知道坚持一个词。因此,我建议您使用noun/2之类的内容替换det/2part_of_speech(Word, PartOfSpeech)等等。所以这是我开始使用的数据库:

grammar([noun]).
grammar([det,noun]).

part_of_speech(fox, noun).
part_of_speech(the, det).
part_of_speech(cat, noun).

我删除了整数,因为我不知道它们的用途是什么。从这里开始,很容易找到一个语法,并用你的输入填写:

match(Input, Grammar, Tagged) :-
    grammar(Grammar),
    maplist(match_word, Input, Grammar, Tagged).

match_word(Word, Part, Tag) :-
    part_of_speech(Word, Part),
    Tag =.. [Part, Word].

这会产生如下结果:

?- match([the,cat], G, T).
G = [det, noun],
T = [det(the), noun(cat)].

?- match([cat], G, T).
G = [noun],
T = [noun(cat)] ;
false.

?- match([the,cat], G, T).
G = [det, noun],
T = [det(the), noun(cat)].

?- match([the,fox], G, T).
G = [det, noun],
T = [det(the), noun(fox)].

我认为这是你想要的,但我不完全确定,因为我没有看到输入/输出的示例。这是简化问题的简化解决方案;我认为如果解决方案处于正确的范围内,应该可以将其提升到相当不方便的数据结构中。如果不是,那么我建议你考虑一种基于使用DCG而不是像这样的规则/匹配的方法;它可能会更清洁,更直接。

词性标注绝对是AI中一个有趣的话题,尤其是#34;经典" AI,这种方法可能无法很好地扩展。

另外,请查看WordNet;有一个Prolog版本的数据库,这可能会为你节省一些工作。