このディレクトリの索引

% 以下のサイトは :- use_module(library(socket)). exec(P) :- catch(P,E,fail). サーバ :- サーバ(6013). サーバ(_ポート) :- tcpソケットの準備(_ソケット,_ポート), 接続されたらソケットを開く(_ソケット, AcceptFd, _), tcpインタプリタ(AcceptFd). tcpソケットの準備(_ソケット,_ポート) :- tcp_socket(_ソケット), tcp_bind(_ソケット, _ポート), tcp_listen(_ソケット, 5). 接続されたらソケットを開く(AcceptFd,_ソケット,_Peer,In,Out) :- tcp_accept(AcceptFd, _ソケット, _Peer), tcp_open_socket(_ソケット, In, Out). tcpインタプリタ(AcceptFd) :- repeat, 行を読みだして実行(AcceptFd), fail. 行を読みだして実行(AcceptFd) :- 接続されたらソケットを開く(AcceptFd,_ソケット,_Peer,In,Out), 一行読み出し項に変換(In,_項), インタプリタの実行(_ソケット,In,Out,_項). インタプリタの実行(_ソケット,In,Out,_項) :- 親タスクで実行(In,Out,_項), 小タスクで実行(_ソケット,In,Out,_項). 親タスクで実行(In,Out,_項) :- 項は親タスクで実行するべきもの(_項), 親タスクで実行(In,Out,_項), fail. 親タスクで実行(_,_,_項) :- 項は子タスクで実行するべきもの(_項). 項は親タスクで実行するべきもの(_項) :- _項 = findall(_,exec(_),_). 項は子タスクで実行するべきもの(_項) :- \+(_項 = findall(_,exec(_),_)). 親タスクで実行(In,Out,_項) :- catch(_項,_エラー情報,エラー発生時はfail扱い), 情報を送信する(Out,_項), ストリームを閉じる(In,Out). 小タスクで実行(_ソケット,In,Out,_項) :- tell(Out), thread_create(項を実行して結果を返す(In, Out, _項),_,[]). 項を実行して結果を返す(In, Out, _項) :- 目標評価(In, Out, _項), 情報を送信する(Out,_項), ストリームを閉じる(In,Out). 目標評価(In, Out, _項) :- catch(_項,_エラー情報,エラー情報の送信(Out,_エラー情報),!. 目標評価(In, Out, _項) :- _項=false. 一行読み出し項に変換(In,_項,_エラー情報) :- 行入力(In,_行), 行を解析して項を得る(_行,_項,_エラー情報). 行を解析して項を得る(_行,_項,_エラー情報) :- catch(read_term_from_atom(_行,_項,[]),_エラー情報,_項 = false). 行入力(In,_行) :- read_line_to_codes(In,Codes), atom_codes(_行,Codes). エラー情報の送信(Out,_エラー情報) :- format('~w\n',[_エラー情報]), format(Out,'~w\n',[_エラー情報]). 情報を送信する(Out,_項) :- write(Out,'% end_of_file\n'), 項書き出す(Out,_項). 項を書き出す(Out,_項) :- format(Out,'~w\n',[_項]), flush_output(out). ストリームを閉じる(In,Out) :- close(In), close(Out). 送信項と受信項の単一化(_項,_項). エラー発生時はfail扱い :- fail. % 以下のサイトは :- use_module(library(socket)). exec(P) :- catch(P,E,fail). サーバ :- サーバ(6013). サーバ(_ポート) :- tcpソケットの準備(_ソケット,_ポート), 接続されたらソケットを開く(_ソケット, AcceptFd, _), tcpインタプリタ(AcceptFd). tcpソケットの準備(_ソケット,_ポート) :- tcp_socket(_ソケット), tcp_bind(_ソケット, _ポート), tcp_listen(_ソケット, 5). 接続されたらソケットを開く(AcceptFd,_ソケット,_Peer,In,Out) :- tcp_accept(AcceptFd, _ソケット, _Peer), tcp_open_socket(_ソケット, In, Out). tcpインタプリタ(AcceptFd) :- repeat, 行を読みだして実行(AcceptFd), fail. 行を読みだして実行(AcceptFd) :- 接続されたらソケットを開く(AcceptFd,_ソケット,_Peer,In,Out), 一行読み出し項に変換(In,_項), インタプリタの実行(_ソケット,In,Out,_項). インタプリタの実行(_ソケット,In,Out,_項) :- 親タスクで実行(In,Out,_項), 小タスクで実行(_ソケット,In,Out,_項). 親タスクで実行(In,Out,_項) :- 項は親タスクで実行するべきもの(_項), 親タスクで実行(In,Out,_項), fail. 親タスクで実行(_,_,_項) :- 項は子タスクで実行するべきもの(_項). 項は親タスクで実行するべきもの(_項) :- _項 = findall(_,exec(_),_). 項は子タスクで実行するべきもの(_項) :- \+(_項 = findall(_,exec(_),_)). 親タスクで実行(In,Out,_項) :- catch(_項,_エラー情報,エラー発生時はfail扱い), 情報を送信する(Out,_項), ストリームを閉じる(In,Out). 小タスクで実行(_ソケット,In,Out,_項) :- thread_create(項を実行して結果を返す(In, Out, _項),_,[]). 項を実行して結果を返す(In, Out, _項) :- ( catch(_項,_エラー情報,エラー情報の送信(Out,_エラー情報)); _項=false),!, 情報を送信する(Out,_項), ストリームを閉じる(In,Out). 一行読み出し項に変換(In,_項,_エラー情報) :- 行入力(In,_行), 行を解析して項を得る(_行,_項,_エラー情報). 行を解析して項を得る(_行,_項,_エラー情報) :- catch(read_term_from_atom(_行,_項,[]),_エラー情報,_項 = false). 行入力(In,_行) :- read_line_to_codes(In,Codes), atom_codes(_行,Codes). エラー情報の送信(Out,_エラー情報) :- format('~w\n',[_エラー情報]), format(Out,'~w\n',[_エラー情報]). 情報を送信する(Out,_項) :- 項を文字列に変換する(_項,_文字列), 書き出す(Out,_文字列). 書き出す(Out,_文字列) :- format(Out,'~w\n',[_文字列]), flush_output(Out). 項を文字列に変換する(_項,_文字列) :- swritef(String,'%t',[_項]), string_to_atom(String,_文字列). ストリームを閉じる(In,Out) :- close(In), close(Out). 送信項と受信項の単一化(_項,_項). エラー発生時はfail扱い :- fail. % 以下のサイトは :- use_module(library(socket)). :- op(800,xfx,(::)). :- op(850,fx,(!)). exec(P) :- catch(P,E,fail). サーバ :- サーバ(6013). サーバ(Port) :- tcpソケットの準備(Socket,Port), 接続されたらソケットを開く(Socket, AcceptFd, _), tcpインタプリタ(AcceptFd). tcpソケットの準備(Socket,Port) :- tcp_socket(Socket), tcp_bind(Socket, Port), tcp_listen(Socket, 5). 接続されたらソケットを開く(AcceptFd,Socket,_Peer,In,Out) :- tcp_accept(AcceptFd, Socket, _Peer), tcp_open_socket(Socket, In, Out). 一行読み出し項に変換(In,Line,_項,E1) :- 行入力(In,Line), catch(read_term_from_atom(Line,_項,[]),E1,_項 = false). tcpインタプリタ(AcceptFd) :- repeat, 行を読みだして実行(AcceptFd), fail. 行を読みだして実行(AcceptFd) :- 接続されたらソケットを開く(AcceptFd,Socket,_Peer,In,Out), 一行読み出し項に変換(In,Line,_項,E1), 親タスクで実行(In,Out,_項), 小タスクで実行(Socket,In,Out,_項). 親タスクで実行(In,Out,_項) :- 親タスクで実行(In,Out,_項,E), fail. 親タスクで実行(In,Out,_項) :- \+(_項 = findall(_,exec(_),_)). 親タスクで実行(In,Out,_項,E) :- _項 = findall(_,exec(_),_), catch(_項,E,fail), 情報を送信する(Out,_項), ストリームを閉じる(In,Out). 小タスクで実行(Socket,In,Out,_項) :- thread_create(項を実行して結果を返す(In, Out, _項),_,[]). 項を実行して結果を返す(In, Out, _項) :- ( catch(_項,E2,エラー情報の送信(Out,E2)); _項=false),!, 情報を送信する(Out,_項), ストリームを閉じる(In,Out). クライアント(Host, Port, _項) :- 項にfindallを被せて目標として送信する(Host,Port,_項,Socket,ReadFd,WriteFd), 行入力(ReadFd,Line2), catch(read_term_from_atom(Line2,_項2,[]),E,(ストリームを閉じる(ReadFd,WriteFd),fail)), ストリームを閉じる(ReadFd,WriteFd), 送信項と受信項の単一化(_項,_項2). 項にfindallを被せて目標として送信する(Host,Port,_項,Socket,ReadFd,WriteFd) :- サーバと接続する(Host, Port,Socket), tcp_open_socket(Socket, ReadFd, WriteFd), 情報を送信する(WriteFd,_項). サーバと接続する(Host, Port,Socket) :- tcp_socket(Socket), tcp_connect(Socket, Host:Port). (! P) :- (keizo97:6013 :: P). Network:Port :: P :- クライアント(Network,Port,findall(P,P,L)), 全解を取り出す(P,L). 全解を取り出す(P,L) :- member(P,L). 行入力(In,Line) :- read_line_to_codes(In,Codes), atom_codes(Line,Codes). エラー情報の送信(Out,E) :- write(E),nl, writeq(Out,E), write(Out,'\n'). 情報を送信する(Out,_項) :- 項を文字列に変換する(_項,_文字列), 書き出す(Out,_文字列). 書き出す(Out,_文字列) :- write(Out,_文字列), write(Out,'\n'), flush_output(Out). 項を文字列に変換する(_項,_文字列) :- swritef(String,'%t',[_項]), string_to_atom(String,_文字列). ストリームを閉じる(In,Out) :- close(In), close(Out). 送信項と受信項の単一化(_項,_項). % 以下のサイトは スレッドとメッセージキューを使って全解を収集する(_選択項,_副目標,_回収値ならび) :- message_queue_create(_キュー番号), thread_create(スレッドで副目標を実行する(_キュー番号,_選択項,_副目標),_,[]), メッセージを回収する(_キュー番号,_回収値ならび), message_queue_destroy(_キュー番号). スレッドで副目標を実行する(_キュー番号,_選択項,_副目標) :- call(_副目標), thread_send_message(_キュー番号,_選択項), fail. スレッドで副目標を実行する(_キュー番号,_,_) :- thread_send_message(_キュー番号,end_of_file). メッセージを回収する(_キュー番号,_メッセージならび) :- メッセージを確実に得る(_キュー番号,_回収値), メッセージを回収する(_キュー番号,_回収値,_メッセージならび). メッセージを回収する(_キュー番号,end_of_file,[]) :- !. メッセージを回収する(_キュー番号,_回収値,[_回収値|R]) :- メッセージを確実に得る(_キュー番号,_回収値_2), メッセージを回収する(_キュー番号,_回収値_2,R). メッセージを確実に得る(_キュー番号,_メッセージ) :- repeat, thread_peek_message(_キュー番号,_), thread_get_message(_キュー番号,_メッセージ),!. % 以下のサイトは % % SWI-Prologに於いてfindall/3と同等の述語をmesage_queueを使って定義してみる。 % % findall/3と同じ機能の述語をメッセージキューを利用して定義する。 % メッセージキューを使って全解を収集する(_選択項,_副目標,_回収値ならび) :- message_queue_create(_キュー番号), ( call(_副目標), thread_send_message(_キュー番号,_選択項), fail; メッセージを回収する(_キュー番号,_回収値ならび)), message_queue_destroy(_キュー番号). メッセージを回収する(_キュー番号,[]) :- \+(thread_peek_message(_キュー番号,_)),!. メッセージを回収する(_キュー番号,[_回収値|R]) :- thread_get_message(_キュー番号,_回収値), メッセージを回収する(_キュー番号,R). % 以下のサイトは % % 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(_度数)). % 以下のサイトは % % 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(_度数)). % 以下のサイトは # 質問です。 # MySQL5です。 # テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。 # 各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。 # 言っていることが、よくわからなくてすみません。 # # 元テーブル # DATE, CODE, VALUE # .... # 20140401, 11, A # 20140402, 12, B # 20140403, 11, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # .... # # 欲しい結果 # 20140401, 11, A # 20140403, 11, C # 20140406, 11, F # 20140402, 12, B # 20140405, 12, E # 20140404, 13, D # # 宜しくお願い致します。 # # # 879 名前:NAME IS NULL [sage]: 2014/04/25(金) 17:41:21.67 ID:??? # >>877 # どうも質問が明確じゃないけど、 # insert into tname select 〜 # の形式にすればとりあえず解決しそうな話に見える。 # # >>878 # order by code, date ということ? # # # 880 名前:NAME IS NULL []: 2014/04/25(金) 17:47:38.30 ID:+Fb19Efw (3) # 879 # 分かりずらい # 欲しい結果にしてしまいました。 # # 第1キーは、日付です。 # # 元テーブル # DATE, CODE, VALUE # 20140401, 13, A # 20140402, 11, B # 20140403, 12, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # # 欲しい結果 # 20140401, 13, A # 20140404, 13, D # 20140402, 11, B # 20140406, 11, F # 20140403, 12, C # 20140405, 12, E # # 宜しくお願い致します。 # # # 要するに第一キーは降順、第二キーは昇順で整列する。 # 'テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。'(_DATE,_CODE,_VALUE) :- '要するに第一キーは降順、第二キーは昇順で整列する。'(L1,_第一番目の日付ならび), 情報を取り出す(_第一番目の日付ならび,L1,_DATE,_CODE,_VALUE). '要するに第一キーは降順、第二キーは昇順で整列する。'(L1,_第一番目の日付ならび) :- 第一キー順序(_逆順コードならび), setof(_第一番目の日付, [_CODE,_第一番目の日付] ^ ( 'CODEを取り出す'(_逆順コードならび,_CODE), 第二キー順序(_CODE,_,_第一番目の日付)),_第一番目の日付ならび). 第一キー順序(_逆順コードならび) :- setof(_CODE,[_DATE,_CODE,_VALUE] ^ 元テーブル(_DATE,_CODE,_VALUE),L1), reverse(L1,_逆順コードならび). 逆順に整列して取り出す(_逆順コードならび,_CODE) :- member(_CODE,_逆順コードならび). 第二キー順序(_CODE,[_第一番目の日付|R],_第一番目の日付) :- setof(_DATE,[_DATE,_CODE,_VALUE] ^ 元テーブル(_DATE,_CODE,_VALUE),[_第一番目の日付|R]). 情報を取り出す(_第一番目の日付ならび,_逆順コードならび,_DATE,_CODE,_VALUE) :- member(_DATE_1,_第一番目の日付ならび), 'CODEを決める'(_逆順コードならび,_DATE_1,_CODE), 元テーブル(_DATE,_CODE,_VALUE). 'CODEを決める'(_逆順コードならび,_DATE_1,_CODE) :- member(_CODE,_逆順コードならび), setof(_DATE,[_DATE,_VALUE] ^ 元テーブル(_DATE,_CODE,_VALUE),[_DATE_1|_]). % 以下のサイトは スレッドとメッセージキューを使って全解を収集する(_選択項,_副目標,_回収値ならび) :- message_queue_create(_キュー番号), thread_create(スレッドで副目標を実行する(_キュー番号,_選択項,_副目標),_,[]), メッセージを回収する(_キュー番号,_回収値ならび), message_queue_destroy(_キュー番号). スレッドで副目標を実行する(_キュー番号,_選択項,_副目標) :- call(_副目標), thread_send_message(_キュー番号,_選択項), fail. スレッドで副目標を実行する(_キュー番号,_,_) :- thread_send_message(_キュー番号,end_of_file). メッセージを回収する(_キュー番号,_メッセージならび) :- メッセージを確実に得る(_キュー番号,_回収値), メッセージを回収する(_キュー番号,_回収値,_メッセージならび). メッセージを回収する(_キュー番号,end_of_file,[]) :- !. メッセージを回収する(_キュー番号,_回収値,[_回収値|R]) :- メッセージを確実に得る(_キュー番号,_回収値_2), メッセージを回収する(_キュー番号,_回収値_2,R). メッセージを確実に得る(_キュー番号,_メッセージ) :- repeat, thread_peek_message(_キュー番号,_), thread_get_message(_キュー番号,_メッセージ),!. % 以下のサイトは % % SWI-Prologに於いてfindall/3と同等の述語をmesage_queueを使って定義してみる。 % % findall/3と同じ機能の述語をメッセージキューを利用して定義する。 % メッセージキューを使って全解を収集する(_選択項,_副目標,_回収値ならび) :- message_queue_create(_キュー番号), ( call(_副目標), thread_send_message(_キュー番号,_選択項), fail; メッセージを回収する(_キュー番号,_回収値ならび)), message_queue_destroy(_キュー番号). メッセージを回収する(_キュー番号,[]) :- \+(thread_peek_message(_キュー番号,_)),!. メッセージを回収する(_キュー番号,[_回収値|R]) :- thread_get_message(_キュー番号,_回収値), メッセージを回収する(_キュー番号,R). % 以下のサイトは # # 目標_1と目標_2を限界度数成功させる。 # 目標_1と目標_2を限界度数成功させる(_限界度数,_目標_1,_目標_2) :- forall_n(_限界度数,_目標_1,_目標_2). forall_n(_限界度数,_目標_1,_目標_2) :- message_queue_create(_キュー番号), ( thread_create(度数(_限界度数,_キュー番号),_,[]); forall(( thread_get_message(_キュー番号,_項), ( _項 = 0,!,fail;call(_目標_1))), call(_目標_2)). 度数(_限界度数,_キュー番号) :- between(1,_限界度数,_度数), _剰余 is _度数 mod ( _限界度数 + 1 ), thread_send_message(_キュー番号,_剰余), _度数 = _限界度数. % 以下のサイトは # # 目標を限界度数成功させて指定した蒐集項をならびとして得る # 目標を限界度数成功させて指定した蒐集項をならびとして得る(_限界度数,_蒐集項,_目標,_蒐集項ならび) :- findall_n(_限界度数,_蒐集項,_目標,_蒐集項ならび). findall_n(_限界度数,_蒐集項,_目標,_蒐集項ならび) :- message_queue_create(_キュー番号), ( '子スレッドで、生成された度数を、限界度数に達したら0をキューに送る'(_限度度数,_キュー番号); キューから限界度数を示す0を受信するまで目標を成功させて蒐集項ならびを得る(_蒐集項,_目標,_キュー番号,_蒐集項ならび)). キューから限界度数を示す0を受信するまで目標を成功させて蒐集項ならびを得る(_蒐集項,_目標,_キュー番号,_蒐集項ならび) :- findall(_蒐集項,( thread_get_message(_キュー番号,_項), ( _項 = 0,!,fail;call(_目標))), _蒐集項ならび). '子スレッドで、生成された度数を、限界度数に達したら0をキューに送る'(_限度度数,_キュー番号) :- thread_create(度数(_限界度数,_キュー番号),_,[]). 度数(_限界度数,_キュー番号) :- between(1,_限界度数,_度数), _剰余 is _度数 mod ( _限界度数 + 1 ), thread_send_message(_キュー番号,_剰余), _度数 = _限界度数. % % 先にlength/2等で解の枠が決まっている場合があるが、 % findall/3述語だと、その枠を無視して、全解を蒐集して、 % その上で第三引数のならびとの単一化を試みようとする。 % 目標の解が1000万個というように多量の場合は、 % スタックオーバーフローが生じてエラーとなって終了する。 % % これに対して、この述語は子スレッドを作り出して、ここで % 本来は現在の解数を数えさせてキュー経由で親スレッドは % これを受信する。この為には親スレッドから子スレッドに解が % 取れたことを送信するためのキューが必要であるがここでは % それを省略した。子から親への片方向の通信になっている。 % % 子スレッドは1から解の限界数まで整数をキューに一気に詰め、 % さらに、終了の合図である0を詰める。親スレッドは目標が % 達成される度にキューから一つ度数情報を取り出す。 % 解の数が限界数に達した時に子スレッドが既に送信してあった % 0を受信することになり、親スレッドのfindall_n/4の目標内の % カットが発動されて強制的にfindall_n/4を終了させることが % できる。 % % ここではfindall/3を対象にしているがsetof/3やbagof/3も % 全く同様の問題があるし、解決策も同じである。 % 以下のサイトは # # 目標を限界度数成功させてその項をリストとして得る # 目標を限界度数成功させてその項をならびとして得る(_限界度数,_目標,_目標ならび) :- findall_n(_限界度数,_目標,_目標ならび). findall_n(_限界度数,_目標,_目標ならび) :- message_queue_create(_キュー番号), ( thread_create(度数(_限界度数,_キュー番号),_,[]); findnall(_目標,( thread_get_message(_キュー番号,_項), ( _項 = 0,!,fail;call(_目標))), _目標ならび)). 度数(_限界度数,_キュー番号) :- between(1,_限界度数,_度数), _剰余 is _度数 mod ( _限界度数 + 1 ), thread_send_message(_キュー番号,_剰余), _度数 = _限界度数. % 以下のサイトは # # 目標を限界度数成功させて指定した蒐集項をならびとして得る # 目標を限界度数成功させて指定した蒐集項をならびとして得る(_限界度数,_蒐集項,_目標,_蒐集項ならび) :- findall_n(_限界度数,_蒐集項,_目標,_蒐集項ならび). findall_n(_限界度数,_蒐集項,_目標,_蒐集項ならび) :- message_queue_create(_キュー番号), ( thread_create(度数(_限界度数,_キュー番号),_,[]); findall(_蒐集項,( call(_目標), thread_get_message(_キュー番号,_項), ( _項 = 0,!,fail;true)), _蒐集項ならび)). 度数(_限界度数,_キュー番号) :- between(1,_限界度数,_度数), _剰余 is _度数 mod ( _限界度数 + 1 ), thread_send_message(_キュー番号,_剰余), _度数 = _限界度数. % % 先にlength/2等で解の枠が決まっている場合があるが、 % findall/3述語だと、その枠を無視して、全解を蒐集して、 % その上で第三引数のならびとの単一化を試みようとする。 % 目標の解が1000万個というように多量の場合は、 % スタックオーバーフローが生じてエラーとなって終了する。 % % これに対して、この述語は子スレッドを作り出して、ここで % 本来は現在の解数を数えさせてキュー経由で親スレッドは % これを受信する。この為には親スレッドから子スレッドに解が % 取れたことを送信するためのキューが必要であるがここでは % それを省略した。子から親への片方向の通信になっている。 % % 子スレッドは1から解の限界数まで整数をキューに一気に詰め、 % さらに、終了の合図である0を詰める。親スレッドは目標が % 達成される度にキューから一つ度数情報を取り出す。 % 解の数が限界数に達した時に子スレッドが既に送信してあった % 0を受信することになり、親スレッドのfindall_n/4の目標内の % カットが発動されて強制的にfindall_n/4を終了させることが % できる。 % % ここではfindall/3を対象にしているがsetof/3やbagof/3も % 全く同様の問題があるし、解決策も同じである。 % 以下のサイトは # # 目標を限界度数成功させて指定した蒐集項をならびとして得る # 目標を限界度数成功させて指定した蒐集項をならびとして得る(_限界度数,_蒐集項,_目標,_蒐集項ならび) :- findall_n(_限界度数,_蒐集項,_目標,_蒐集項ならび). findall_n(_限界度数,_蒐集項,_目標,_蒐集項ならび) :- message_queue_create(_キュー番号), 度数(_限界度数,_キュー番号), findall(_蒐集項,( thread_get_message(_キュー番号,_項), ( _項 = 0,!,fail;call(_目標))), _蒐集項ならび). 度数(_限界度数,_キュー番号) :- between(1,_限界度数,_度数), _剰余 is _度数 mod ( _限界度数 + 1 ), thread_send_message(_キュー番号,_剰余), _度数 = _限界度数. % % ?- length(L,4),findall(N,between(1,10000000,N),L). % false. % 1000万要素と4要素のリストの単一化。この結論を得るまでに数秒を要する。 % % ?- length(L,4),findall_n(4,N,between(1,10000000,N),L). % L = [1,2,3,4] % % ?- length(L,4),findall_n(5,N,between(1,10000000,N),L). % false. % % ?- length(L,4),findall_n(5,N,between(1,4,N),L). % L = [1,2,3,4] % % 以下のサイトは # # グーを0、チョキを1、パーを2とし、ユーザは自分の出す手をキーボードから入力する。 # 'グーを0、チョキを1、パーを2とし、ユーザは自分の出す手をキーボードから入力する。'(_自分の出す手) :- 入力プロセスの生成(Id,Message_queue_Id), 'グーを0、チョキを1、パーを2とし'(_自分の出す手,_自分の出す手の入力値), 'ユーザは自分の出す手をキーボードから入力する。'(Id,Message_queue_Id,_自分の出す手の入力値),!. 'グーを0、チョキを1、パーを2とし'(_自分の出す手,_自分の出す手の入力値) :- グーを0(_自分の出す手,_自分の出す手の入力値). 'グーを0、チョキを1、パーを2とし'(_自分の出す手,_自分の出す手の入力値) :- チョキを1(_自分の出す手,_自分の出す手の入力値). 'グーを0、チョキを1、パーを2とし'(_自分の出す手,_自分の出す手の入力値) :- パーを2(_自分の出す手,_自分の出す手の入力値). グーを0(グー,0). チョキを1(チョキ,1). パーを2(パー,2). 'ユーザは自分の出す手をキーボードから入力する。'(Id,Message_queue_Id,_自分の出す手の入力値) :- キーボードから(_キーボードの入力ストリーム), 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,Line), atom_number(Line,_自分の出す手の入力値). 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,_情報) :- 入力プロセスから一度得た情報(Id,Message_queue_Id,Term), 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,Term,_情報). 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,_情報) :- 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,_情報). 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,_情報,_情報). 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,_情報,_情報) :- thread_peek_massage(Message_queue_Id,_次の情報),!,fail. 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,Term,_情報) :- 入力プロセスから一度得た情報を何度も供給する(Id,Message_queue_Id,Term,_情報). 入力プロセスから一度得た情報(Id,Message_queue_Id,Term) :- thread_get_message(Message_queue_Id,Term). 入力プロセスの生成(Id,Message_queue_Id) :- thread_create(キーボードからの入力(Message_queue_Id),Id,[]). キーボードからの入力(Message_queue_Id) :- message_queue_create(Message_queue_Id), キーボードからの入力(Message_queue_Id). キーボードからの入力(Message_queue_Id) :- reapeat, キーボードから(Instream), get_line(Instream,Line), thread_send_message(Message_queue_Id,Line), fail. キーボードから(user_input). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1349545643/775 # # 【お題】 # コラッツ予想とは、「任意の0でない自然数nをとり、 # ・nが偶数の場合、nを2で割る # ・nが奇数の場合、nに3をかけて1を足す # という操作を繰り返すと、有限回で1に到達する」という主張である。 # # nからスタートして1に到達するまでのステップをsとしたとき、 # n = 1 .. 100000についてsを計算し、最長のsを出力せよ。 # # ただし、それぞれのnに対するsの計算は並列(スレッド、プロセス問わない)で行う事。 # # 'コラッツ予想とは、「任意の0でない自然数nをとり、 ・nが偶数の場合、nを2で割る ・nが奇数の場合、nに3をかけて1を足す という操作を繰り返すと、有限回で1に到達する」という主張である。 nからスタートして1に到達するまでのステップをsとしたとき、 n = 1 .. 100000についてsを計算し、最長のsを出力せよ。'(_n,_最長のs) :- findall(_Idならび,( between(1,100000,_n), message_queue_create(_Id), thread_create(コラッツの予想(_ID,_n),_,[])), _Idならび), 最長のsを出力する(_Idならび). コラッツの予想(_ID,_n) :- コラッツの予想(_n,0,_回数), thread_send_massage(_ID,_回数). コラッツの予想(1,_回数,_回数) :- !. コラッツの予想(_n,_回数_1,_回数) :- 'nが偶数の場合、nを2で割る nが奇数の場合、nに3をかけて1を足す'(_n,_n_2), _回数_2 is _回数_1 + 1, コラッツの予想(_n_2,_回数_2,_回数),!. 'nが偶数の場合、nを2で割る nが奇数の場合、nに3をかけて1を足す'(_n,n_2) :- 'nが偶数の場合、nを2で割る'(_n,_n_2). 'nが偶数の場合、nを2で割る nが奇数の場合、nに3をかけて1を足す'(_n,_n_2) :- 'nが奇数の場合、nに3をかけて1を足す'(_n,_n_2). 'nが偶数の場合、nを2で割る'(_n,_n_2) :- _n_2 is _n // 2. 'nが奇数の場合、nに3をかけて1を足す'(_n,_n_2) :- 1 is _n mod 2, _n_2 is _n * 3 + 1. 最長のsを出力する(_Idならび) :- findmax(_n,( between(1,100000,_), repeat, thread_get_massage(_Id,_n)), _最長のs), writef('最長のsは %t です。\n',[_最長のs]). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1349545643/775 # # 【お題】 # コラッツ予想とは、「任意の0でない自然数nをとり、 # ・nが偶数の場合、nを2で割る # ・nが奇数の場合、nに3をかけて1を足す # という操作を繰り返すと、有限回で1に到達する」という主張である。 # # nからスタートして1に到達するまでのステップをsとしたとき、 # n = 1 .. 100000についてsを計算し、最長のsを出力せよ。 # # ただし、それぞれのnに対するsの計算は並列(スレッド、プロセス問わない)で行う事。 # # 'コラッツ予想とは、「任意の0でない自然数nをとり、 ・nが偶数の場合、nを2で割る ・nが奇数の場合、nに3をかけて1を足す という操作を繰り返すと、有限回で1に到達する」という主張である。 nからスタートして1に到達するまでのステップをsとしたとき、 n = 1 .. 100000についてsを計算し、最長のsを出力せよ。'(_n,_最長のs) :- findmax(_回数,( between(1,100000,_n), コラッツの予想(_n,_回数)), _最長のs). コラッツの予想(_n,_回数) :- コラッツの予想(_n,0,_回数). コラッツの予想(1,_回数,_回数) :- !. コラッツの予想(_n,_回数_1,_回数) :- 'nが偶数の場合、nを2で割る nが奇数の場合、nに3をかけて1を足す'(_n,_n_2), _回数_2 is _回数_1 + 1, コラッツの予想(_n_2,_回数_2,_回数),!. 'nが偶数の場合、nを2で割る nが奇数の場合、nに3をかけて1を足す'(_n,n_2) :- 'nが偶数の場合、nを2で割る'(_n,_n_2). 'nが偶数の場合、nを2で割る nが奇数の場合、nに3をかけて1を足す'(_n,_n_2) :- 'nが奇数の場合、nに3をかけて1を足す'(_n,_n_2). 'nが偶数の場合、nを2で割る'(_n,_n_2) :- _n_2 is _n // 2. 'nが奇数の場合、nに3をかけて1を足す'(_n,_n_2) :- 1 is _n mod 2, _n_2 is _n * 3 + 1. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1337692704/188 # # 【課題】以下のようなクラス(名前は各自決める)を定義せよ。 # mainメソッドを呼び出すと、別のスレッドthを生成し、スタートさせる。 # mainメソッドは、プロンプトとして”Command> “を印字し、キーボードからの入力を待つ。 # 入力は、以下のようなadd, removeなどを先頭とするいくつかの文字列で、 # それを何らかの方法でスレッドthに渡し、ふたたび “Command> “を印字して次の入力を待つ。 # Command> add <文字列> # スレッドthでは、mainから受け取った<文字列>の部分を取り出し、 # thの中で管理するLinkedListの要素に加える(add)。一方、 # Command> remove <文字列> とすると該当する文字列をLinkedListから消す。そのほか、 # Command> print とでき、printはLinkedListにある要素をすべて印字し # Command> exit exitはスレッドを停止し、それを待ってmainメソッドを終了する # ものである。 # 上記以外の入力は無視する。 # (ヒント:書き方はたくさんありますが、たとえば前回のProducer Consumerの例を考えてください。 # 片方が生成(入力された文字列をMqueueに格納)、他方がそれを読み出すと考えます。 # もちろんもっと簡単な方法もあると思います。上記の仕様通りに動いていれば正解です。 # 【 形態 】1. Javaアプリケーション(main()で開始) # 【GUI】4.制限なし # 【 期限 】 今日(7/14)中 # 【 Ver  】 1.7.0_03 # 【 補足 】宜しくお願いします! # # 影を用いて情報を管理する :- 取り次ぎ(_取り次ぎ), コマンドを得る(_コマンド行), 影を生み出す(影(_取り次ぎ),_影,[]), 影を用いて情報を管理する(_取り次ぎ,_命令). 影を用いて情報を管理する(_取り次ぎ,exit). 影を用いて情報を管理する(_取り次ぎ,コマンド行) :- コマンドを得る(_コマンド_2), thread_send_message(_取り次ぎ,コマンド_2), 影を用いて情報を管理する(_取り次ぎ,コマンド行_2). コマンドを得る(_コマンド行) :- write('コマンド>> '), get_line(_コマンド行). 影(_取り次ぎ) :- 言伝からコマンドを得る(_取り次ぎ,_命令,R), 影(_取り次ぎ,_命令,R,[],L). 影(_取り次ぎ,_命令,_付加情報,L_1,L) :- コマンドの実行(_取り次ぎ,_コマンド,L_1,L_2), 言伝を送る(_取り次ぎ,ok), 言伝からコマンドを得る(_取り次ぎ,_命令_2,_付加情報_2), 影(_取り次ぎ,_命令_2,_付加情報_2,L_2,L). 言伝からコマンドを得る(_取り次ぎ,_命令,R) :- 言伝を取り出す(_取り次ぎ,_言伝,[]), split(_言伝,[' '],[_命令|R]). コマンドの実行(add,[_情報],L_1,[_情報|L_1]). コマンドの実行(delete,[_情報],L_1,L_2) :- ならびから削除(_情報,L_1,L_2). コマンドの実行(print,[],L_1,L_1) :- writef('%t\n',[L_1]). コマンドの実行(_コマンド,_,L_1,L_1) :- writef('%tコマンドは存在しません。\n',[_コマンド]). ならびから削除(_,[],[]) :- !. ならびから削除(_削除する要素,[_削除する要素|_残り対象ならび],_削除されたならび) :- ならびから削除(_削除する要素,_残り対象ならび,_削除されたならび),!. ならびから削除(_削除する要素,[_要素|_残り対象ならび],[_要素|_残り削除ならび]) :- ならびから削除(_削除する要素,_残り対象ならび,_残り削除ならび),!. キューを保存する(L) :- tell('キュー保存.pro'), write(L), write('.\n'), told. 影を生み出す(Term,_影,Option) :- thread_create(Term,_影,Option). 影を終わる :- thread_self(_番号), thread_detach(_番号). 取り次ぎ(_取り次ぎ) :- message_queue_create(_取り次ぎ). 言伝を取り出す(_取り次ぎ,_言伝,_限界時間) :- thread_get_message(_取り次ぎ,_言伝,[timeout(_限界時間)]). 言伝を取り出す(_言伝) :- thread_get_message(_言伝). 言伝を送る(_番号,_言伝) :- thread_send_message(_番号,_言伝). 取り次ぎを立てる(_取り次ぎ) :- message_queue_create(_取り次ぎ,[]). 取り次ぎを解消する(_取り次ぎ) :- message_queue_destroy(_取り次ぎ). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1309076891/688 # # 【 課題 】 # 1、 # data.txt→2chの1スレッドのデータが入っている。 # http://ime.nu/www.dotup.org/uploda/www.dotup.org2512848.txt.html # # dataExtraction.java→data.txtの1レスを読み込んで一枚のテキストファイルに出力していくプログラム(例:レス1はres1.txtに.......レス200はres200.txtに出力) # http://ime.nu/www.dotup.org/uploda/www.dotup.org2512850.txt.html # # このdataExtraction.javaがdata.txtの1レスを読み込んだ際に # もしURLやアンカを表す文字列(例:<a href="../test/read.cgi/bizplus/1326413757/3" target="_blank">../test/read.cgi/tech/1309076891/3</a>)があった場合 # それを削除してテキストファイルに出力する機能を追加してください。 'data.txtには2chの1スレッドのデータが入っている。1レスをずつ読み込んでレス番号をファイル名に含む一枚のテキストファイルに出力していく' :- get_chars('data.txt',Chars), 'data.txtには2chの1スレッドのデータが入っている。1レスをずつ読み込んでレス番号をファイル名に含む一枚のテキストファイルに出力していく'(Chars). 'data.txtには2chの1スレッドのデータが入っている。1レスをずつ読み込んでレス番号をファイル名に含む一枚のテキストファイルに出力していく'(Chars) :- append(_,[<,d,t,>|R1],[<,/,d,t,>|R2],Chars), append(L1,[<,d,d,>|R3],[<,/,d,d,>|R4],R2), 一枚のテキストファイルに保存(R1,L1,R3),), 'data.txtには2chの1スレッドのデータが入っている。1レスをずつ読み込んでレス番号をファイル名に含む一枚のテキストファイルに出力していく'(R4), 'data.txtには2chの1スレッドのデータが入っている。1レスをずつ読み込んでレス番号をファイル名に含む一枚のテキストファイルに出力していく'(_). 一枚のテキストファイルに保存(R1,L1,R3) :- レス番号を得る(R1,_レス番号), concat_atom(['res',_レス番号,'.txt'],_ファイル名), open(_ファイル名,write,Outstream), テキスト部分の保存(Outstream,R1,L1,R3), close(Outstream),!. レス番号を得る(R1,_レス番号) :- concat_atom(R1,S), split(S,[' '],[_レス番号|_]). テキスト部分の保存(Outstream,R1,L1,R3) :- put_chars(Outstream,[<,d,t,>|R1]), put_chars(Outstream,L1), put_chars(Outstream,[<,d,d,>|R3]), put_chars(Outstream,[<,/,d,d,>]). put_chars(_,[]). put_chars(Stream,[_文字|R]) :- put_char(Stream,_文字), put_chars(Stream,R).