首页 文章

Prolog递归和累加器

提问于
浏览
2

我是Prolog编程的新手 . 我正在用累加器做递归分类谓词(我相信我需要累加器) . 假设我有以下规则:

species(tiger).
species(carnivora).
species(ferae).
species(scrotifera).
species(laurasiatheria).

isa(tiger,carnivora).
isa(carnivora,ferae).
isa(ferae,scrotifera).
isa(scrotifera,laurasiatheria).
isa(laurasiatheria, mammalia).

我需要分类谓词,它返回给定物种的类的层次结构 . 这是我做的:

classification_aux(mammalia,[H|T],[]).
classification_aux(Specie, Class, Accum) :-
    isa(Specie, Y),
    classification_aux(Y, [Y|Class], Accum).    

classification(Specie, Class) :- classification_aux(Specie,Class,[]).

以下是它应该如何工作的示例:

classification(gray_tree_frog, X).
X = [amphibia, anura, hylidae, hyla].

编辑:我改进了我的代码 . 现在它似乎按照跟踪工作 . 但没有任何回报 .

2 回答

  • 1

    仅基于层次描述(因为物种/ 1似乎至少是对生物学中涉及的复杂术语的误解)

    classification(Specie, Classification) :-
        isa(Specie, Class) ->
          Classification = [Class|SuperClasses],
          classification(Class, SuperClasses)
        ; Classification = [].
    

    产量

    ?- classification(tiger, X).
    X = [carnivora, ferae, scrotifera, laurasiatheria, mammalia].
    

    编辑

    万一你感兴趣,这个片段

    :- use_module(carlo(snippets/genealogy/pqGraphviz_emu)).
    
    classification :-
        graph_window(build_graph, []).
    
    build_graph(G) :-
        forall(species(S), make_node(G, S, [shape=diamond], _)),
        forall(isa(X, Y), (lookup_node(G, X, Xp), lookup_node(G, Y, Yp), new_edge(G, Xp, Yp))).
    
    lookup_node(G, N, Np) :-
        find_node(G, N, Np) -> true ; make_node(G, N, Np).
    

    生成此SVG文件

    enter image description here

    该接口可从github获得,需要安装Graphviz .

  • 2

    你非常接近这一点 .

    首先要考虑的是如何在没有累加器的情况下解决问题 . 累积器通常是可选的,因为它们有助于提高性能,而不是帮助您获得正确的答案 .

    从制定谓词的规范开始:如果L是S的层次结构,则分类(S,L)应该为真 .

    现在你可以写一个公理:哺乳动物的分类层次是[哺乳动物] .

    并且你可以编写一个规则:某些物种S的分类层次结构是前面带S的列表,尾部有一些值R,如果你能证明S分类为P而P的层次结构是R.或者:给定一个S我们首先找到S的类(称之为P),以及P的层次结构(称之为R),然后S的层次结构是[S | R] .

    希望这些描述足以让您编写条款 .

    现在讨论累加器:如果具有已经累积的C层次结构的S的分类层次为A,则classification_aux(S,C,A)应该为真 .

    如果您现在将此与您的子句匹配,您可以看到错误:

    classification_aux(mammalia,[H|T],[]).
    

    这说明当前等级[H | T]的哺乳动物分类是[] . 这显然与规格不符 . 你想要的是具有当前等级L的哺乳动物的分类是[哺乳动物| L]

    classification_aux(Specie, Class, Accum) :-
    isa(Specie, Y),
    classification_aux(Y, [Y|Class], Accum).
    

    这表示:如果Specie是Y,则具有当前类Heierachy类的Specie的分类是Accum,并且具有层次[Y | Class]的Y的分类是Accum . 我认为这很好 .

    但是,如果您尝试这两个,您会发现累加器版本以相反的顺序生成层次结构 . 这是由于[哺乳动物| L]和[Y | Class]将类放在列表的前面而不是结尾 . 您可以通过使用append(慢)或差异列表(更复杂)或仅使用非累加器版本来解决此问题 .

相关问题