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

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


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


メッセージを回収する(_キュー番号,L) :-
        thread_peek_message(_キュー番号,end_of_file),
        thread_get_message(_キュー番号,_回収値_1),
        メッセージを回収する(_キュー番号,_回収値_1,L),!.
メッセージを回収する(_キュー番号,L) :-
        メッセージを回収する(_キュー番号,L).

メッセージを回収する(_キュー番号,end_of_file,[]) :- !.
メッセージを回収する(_キュー番号,_回収値,[_回収値|R]) :-
        thread_get_message(_キュー番号,_回収値_2),
        メッセージを回収する(_キュー番号,_回収値_2,R).


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


メッセージキューに限界数までの選択項を登録(_限界数,_キュー番号,_選択項,_副目標) :-
        副目標の実行と選択項の登録(_キュー番号,_選択項,_副目標),
        (   メッセージが限界数を超えた(_キュー番号,_限界数),!,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(_度数)).