私はPrologでタスクスケジューラを開発しています。まず、私のコードの簡略化されたバージョンを紹介します。こんなふうになります:
handle_activable(As) :-
reset_flags,
findall(A,catch(activable(A),Exception,flag(marked_activable,A)),As),
activate_all(As).
には2つのバージョンがありますactivable/1
が、最も関連性の高いものは(ここでも簡略化されています):
activable(T) :-
task(T), /* T is a task */
inactive(T), /* The task is currently inactive */
(\+checked(T) ->
mark_checked(T),
!,
/*
Here would go the set of conditions
and statements to determine if task T
is activable or not. They may internally
call activable/1.
*/
asserta(flag(marked_activable,T))
;
/*
This task was already checked and the
result is stored in flag(marked_activable,T)
fact.
*/
throw(exception(already_checked,T))
).
問題は、「条件セットチェック」内で、activable/1
間接的に呼び出される可能性があるということです。そのchecked/1
ため、不要なループを回避するために、を使用する必要があります。私の使い方findall/3
は大丈夫だと思いましたが、As
常に空のリストとしてインスタンス化されているので、[]
何か問題があると思い始めています。
最初にお願いしたいのは、catch(...)呼び出しです。それが正しいか?つまり、activable/1
呼び出し中に、タスクがすでにチェックされているためにプログラムが例外をスローした場合A
でも、インスタンス化されます(で使用できるようにflag(marked_activable,A)
)?そうでない場合は、その回避策を知っていますか?
次にお聞きしたいのは、私のアルゴリズムの正しさです。私はこれに長い間取り組んできましたが、効率的で堅牢で信頼性の高いコードを作成するために最善を尽くしました。本当に難しいのは、条件セットのチェックの範囲内です。ここでは、タスクの関係が大きな役割を果たし、複雑な制約を作成します。「アクティブなタスクを見つける」方法は良いと思いますか?