特に私は、次のタイプの問題を解決するための最良の方法を決定しようとしています。論理プログラミングで何度も更新を処理する必要がありますか?
私が興味を持っている例は、Mitchell's Machine Learningの4つのトレーニング例に適用されたfind-sアルゴリズムです。
基本的な考え方は、各訓練例xと仮説hについて、hをより一般的にすることによってxを組み入れたかどうかを決定することです。トレーニングセットの各xについてhをh 'に写像する必要があります。私が抱えている問題は、これを論理プログラミング言語で最善の方法に接近させる方法です。私は、計画に埋め込まれた大まかにプロローグであるミニカンレンを使用しています。
各h 'を計算した後、私は設定する必要があります!それをグローバル変数hに変換し、次のトレーニング例xに進みます。以下のコードは、プログラムの主要部分です。
(define h '(0 0 0 0 0 0))
(define seto
(lambda (x)
(project (x)
(lambda (s) (set! h x) (succeed s)))))
(run* (q)
(fresh (x h0 h1)
(trainingo x)
(== h h0)
(find-so h0 x h1)
(seto h1)
(== h1 q)))
hはグローバル変数であり、瀬戸は(見つける-SO)のfind-Sアルゴリズムを使用してH0及びXトレーニング例から次の計算であるという仮説H1と時間を変異します。それはアサート(「仮説」(H))に(と思う)と同等になりプロローグで
各トレーニング例の後にXが(以前のものを上書き)と(「仮説」(H))後退を呼び出しますがすべてのトレーニングの例が適用された後。
もう一度私の質問は、これらの問題を解決するための最良のアプローチ(副作用による)かどうかです。
編集: 私は彼のcommentと一緒に@mat答えを受け入れました。要約すると、私は訓練の例をリストとして扱い、空リストに入るまでそのリストの前方再帰を使用する必要がありました。私が立ち往生していたのは、バックトラックの一環としてトレーニングの例を持つことでしたが、次の仮説を見つけるのではなく、空になるまで繰り返すことができます。
あなたは正確にあなたが副作用を経由してこれをしたい理由を説明する必要があります。 @matの答えは、なぜこれに副作用が必要ではないのかを説明しています。 –
ちなみに、Prologライブラリのコードには、効率の理由から副作用を使用した例があります。 [このコードはSWI-Prologのライブラリ(集約)](http://eu.swi-prolog.org/pldoc/doc_for?object=aggregate_all/3)を参照してください。いずれにしても、 'nb_ *'ファミリーの述語を使用することになります。ここで、「nb」は「バックトラック不可」を表します。 –
私はこれを@matのコメントとして述べました: "私は次の仮説を得た後、次の訓練の例に戻った後に次の仮説を失いました。可能であれば、これを解決するために副作用を使用してください。 –