このディレクトリの索引
%  
%  SWI-Prologに於いてfindall/3と同等の述語をmesage_queueを使って定義してみる。
%  
%  findall/3と同じ機能の述語をメッセージキューを利用して定義する。
%  

メッセージキューを使って全解を収集する(_限界数,_選択項,_副目標,_回収値ならび) :-
        message_queue_create(_キュー番号),
        スレッド上でメッセージキューに限界数までの選択項を登録する(_限界数,_キュー番号,_選択項,_副目標),
        'メッセージを待ち合わせ、回収する'(_キュー番号,_回収値ならび),
        message_queue_destroy(_キュー番号).


スレッド上でメッセージキューに限界数までの選択項を登録する(_限界数,_キュー番号,_選択項,_副目標) :-
        thread_create(メッセージキューに限界数までの選択項を登録する(_限界数,_キュー番号,_選択項,_副目標),_,[]).


'メッセージを待ち合わせ、回収する'(_キュー番号,_回収値ならび) :-
        メッセージを待ち合わせる(_キュー番号),
        メッセージを回収する(_キュー番号,_回収値ならび).

メッセージを待ち合わせる(_キュー番号) :-
        repeat,
        thread_peek_message(_キュー番号,end_of_file),!.

メッセージを回収する(_キュー番号,_回収値ならび) :-
        findall(_回収値,(
                    thread_get_message(_キュー番号,_回収値),
                    (   _回収値 = end_of_file,!,fail;
                        true)),
                _メッセージならび).

%%%%%%%%%%%%%%%%%%%% スレッド側 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


メッセージキューに限界数までの選択項を登録する(_限界数,_キュー番号,_選択項,_副目標) :-
        副目標を実行して選択項を登録する(_キュー番号,_選択項,_副目標),
        (   メッセージが限界数を超えた(_キュー番号,_限界数),!,fail;
            fail).
メッセージキューに限界数までの選択項を登録する(_,_キュー番号,_,_) :-
        thread_send_message(_キュー番号,end_of_file).
            
メッセージが限界数を超えた(_キュー番号,_限界数) :-
        メッセージの現在の度数を数える(_キュー番号,_度数),
        _度数 >= _限界数,
        thread_send_message(_キュー番号,end_of_file),!.

副目標を実行して選択項を登録する(_キュー番号,_選択項,_副目標) :-
        call(_副目標),
        重複メッセージにはならない(_キュー番号,_選択項),
        thread_send_message(_キュー番号,_選択項).

重複メッセージにはならない(_キュー番号,_選択項) :-
        \+(thread_peek_message(_キュー番号,_選択項)).

メッセージの現在の度数を数える(_キュー番号,_度数) :-
        message_queue_property(_キュー番号,size(_度数)).