ルールを再度起動する前に、ルールが既に「起動」されているかどうかを確認する必要があります。つまり、新しいファクトをアサートする前に、前のループ反復で同じファクトが既にアサートされているかどうかを知る必要があります。
リストを使用しようとしましたが、私の問題にはあまり「友好的」ではないと思います。これを行うために他に何が使えますか?
ルールを再度起動する前に、ルールが既に「起動」されているかどうかを確認する必要があります。つまり、新しいファクトをアサートする前に、前のループ反復で同じファクトが既にアサートされているかどうかを知る必要があります。
リストを使用しようとしましたが、私の問題にはあまり「友好的」ではないと思います。これを行うために他に何が使えますか?
上記のコメントを、もう少し詳しく説明するための回答として言い換えています。
ソリューションを生成した後に失敗する失敗駆動型ループを検討し、Prolog をバックトラックさせて他の可能性を探らせることができます。
failure_driven_loop(Info):- generate(Info,Term), fail.
failure_driven_loop(Info).
(例はPaul Brna の本からのものです)。この例Term
では、ソリューションを記録し、指定された のソリューションをgenerate/2
生成しますInfo
。2 番目の句は、すべてのソリューションが使い果たされたときにループを成功させるために必要です。
解決策が生成されると、最初の節は失敗し、実行は後戻りします。つまり、Prolog は の別の証明を見つけようとします。これには通常、それ自体または によって直接的または間接的に呼び出される述語の 1 つgenerate(Info,Term)
に対するさまざまな節が含まれます。一度その句の 1 つを使用したことを確認したい場合は、同じ句を再利用しようとしないようにする必要があります。つまり、代わりにカットを追加する必要があります。generate/2
generate/2
generate/2
generate(Info,Term) :- solve_somehow(Info,Term).
generate(Info,Term) :- solve_in_some_other_way(Info,Term).
あなたは書くべきです
generate(Info,Term) :- solve_somehow(Info,Term), !.
generate(Info,Term) :- solve_in_some_other_way(Info,Term), !.
で見つかったソリューションは、generate/2
で記録できますassert
。@CapelliC が指摘したように、プログラムがバックトラックした場合、アサーションは元に戻されないため、失敗駆動ループはソリューションを保持します。
:- dynamic solution/1.
failure_driven_loop(Info):- generate(Info,Term), assert(solution(Term)), fail.
failure_driven_loop(Info).