特に、次のタイプの問題を解決するための最良のアプローチを決定しようとしています。
私が興味を持っている例は、Mitchell の機械学習の本にある find-s アルゴリズムで、4 つのトレーニング例に適用されます。
基本的な考え方は、各トレーニング例 x と仮説 h について、h' を決定することです。これは、x をより一般的にすることによって 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 はグローバル変数であり、seto は h0 から次に計算された仮説である h1 で h を変更し、find-s アルゴリズム (find-so) を使用して x のトレーニング例を作成します。
プロローグでは、各トレーニング例 X (前のものを上書き) の後にassert('hypothesis'(H))を呼び出し、すべてのトレーニング例が終了した後にrettract('hypothesis'(H))を呼び出すことと同等です (私が思うに)。適用。
繰り返しますが、私の質問は、これがこの種の問題を解決するための (副作用による) 最良のアプローチであるかどうかです。
編集: @mat の回答を彼のコメントと共に受け入れました。要約すると、トレーニング例をリストとして扱い、空のリストに到達するまでそのリストで前方再帰を使用する必要がありました。私が立ち往生していたのは、空になるまで繰り返すことができるリストにそれらを含めるのではなく、次の仮説を見つけることと一緒にバックトラックの一部としてトレーニングの例を持っていたことでした.