最初の簡単な疑似コードを書くのに問題があります。
アルゴリズムの入力は、公理と推論セットを含むオントロジーです。正確に、推論は、前提とセットのセットを持つオブジェクトとして定義されます。
アルゴリズムの出力は、推論セットを使用して特定のオントロジーから導出できる一連の結論である必要があります。
結論として結論を導き出す推論が存在する場合、結論は導出可能であり、その前提は導出可能です。
疑似コードを作成しましたが、goto命令のため、最善の解決策ではないと思います。私はそれを削除することができ、伝播のフェーズを処理するデータ構造を追加できると思います。私は明確だったことを願っています:)
7行目では、Dに追加する新しい要素が見つかるたびに再起動しているように見えます。ただし、疑似コードと数学言語では、foreach
がIの要素を取る順序については保証されません。
したがって、foreach
の終わりまでループを継続して、外側のループを追加することもできます。
D ← { O }
repeat
retry ← false
foreach ???? ∈ I do
P ← getPremises(????)
if P ∈ D then
C ← getConclusion(????)
if C ∉ D then
D ← D ∪ { C }
retry ← true
until not retry
return D
repeat
/until
が気に入らない場合は、while
を使用することもできますが、結果としてretry
を初期化する必要があります。
評価の順序が重要な場合は、セットIを順序付きリストまたは優先度キューに置き換え、以前と同じアプローチを使用しますが、retry
をtrueに設定した後で内部ループを中断します。
!
の代わりに、より読みやすいnot
またはより包括的な∉
を使用することをお勧めします。
つまり、Oがセットであり、Dが最初にOのすべての要素を含むべきセットである場合、Oはセット要素として表示されず、1行目は次のようになります。
D ← O
Pが実際に要素ではなく集合である場合、5行目では要素演算子の代わりに集合演算子を使用する必要があります。
if P ⊂ D then
...
ルールの実行後に元のアルゴリズムを再起動すると、状況の変化によりすべてのルールを再評価することが目的であると考えられます。
ただし、コメントから、ルールはDに一度だけ影響を与える可能性があるようです。したがって、すでに実行されたルールを再度実行する必要はありません。これにより、アルゴリズムが改善される可能性があります。
D ← O
K ← I // K is the set of rules that could still fire
n ← true // n is true when new facts were added to D
while n do
n ← false
foreach ???? ∈ K do
P ← getPremises(????)
if P ⊂ D then
K ← K - { ???? } // or K ← {x∈K|x≠???? }
C ← getConclusion(????)
if C ∉ D then
D ← D ∪ { C }
n ← true
return D
現在、Kにはまだ実行されていないルールが含まれています。
ルールの数とそれらを実行する複雑さに応じて、さらに実行して、同じCを結論とする他のルールをKから削除することもできます。最終D.