2016-05-06 5 views
2

Prologプログラミングの初心者です。私はアキュムレータで再帰的な分類述語をやっている(私はアキュムレータが必要だと思う)。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]. 

編集:私は私のコードを改善しました。今はトレースに従って動作するようです。しかし、何も返されません。

+1

[タグ:推移閉包]と['closure0/3'](http://stackoverflow.com/questions/26946133/definition-of-reflexive-transitive-closure)の定義を見てください。 。 – mat

+1

'gray_tree_frog'はファクトベースのどこにも出現しません。あなたの事例であなたが望むものを得るために必要な事実をすべて含めてください。 – mat

+0

@mat、いいえ、それはもちろん、私は私が "虎"と言うことを呼ぶことをテストしたときに使用例です) – yerassyl

答えて

1

あなたはこの権利を取得するのにかなり近づいています。

まず、アキュムレータなしで問題を解決する方法を考えます。アキュムレータは、あなたが正しい答えを得るのを助けるのではなく、パフォーマンスを助けるという点で、ほとんどの場合オプションです。

あなたの述語のためのスペックをワークアウトでスタート:LはS.

ための階層構造である場合には、分類(S、L)が真でなければ今、あなたは公理を書くことができます:哺乳類の分類heierarchyは[哺乳類であります]。

あなたはルールを書くことができます:ある種の種別Sの分類階層は、Sが前にS、後尾にRの値を持つリストです。もしSがPとして分類され、Pの階層がRあるいは、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).  

これは言う:正金はYと分類された場合、現在のクラスheierachyクラスと正金の分類はACCUMですYの階層[Y |クラス]はAccumです。私はそれがいいと思います。

しかし、これらの両方を試してみると、アキュムレータバージョンでは逆の順序で階層が生成されることがわかります。これは[mammalia | L]と[Y | Class]がクラスを終わりの代わりにリストの前に置くためです。代わりに(遅い)または差異リスト(より複雑)を追加するか、非アキュムレータバージョンを使用することでこれを修正できます。唯一の階層的記述に基づいて

2

(種/ 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のがインストールが必要です。