【論理】Prolog【初心者】

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2010/11/06(土) 13:00:56
Prolog初心者のスレ

これは良い言語だ…
2010/11/16(火) 21:59:07
ちょっと読みにくかったですね。すみません。
<Prolog の入力述語について>

項の入力にはread/1が使われてきましたが、これは、
・ ピリオドで終わらなくてはならない。
・ シンタックス的に正しい項以外はエラーとなってしまう。
など、実務での使用に適しません。それで改行までの文字列を
入力として受け取る、get_line/1の定義をしておくのが普通です。
get_lineはget_char/1 または get_code/1を改行がくるまで、
繰り返し使うことによって定義します。例えば、

get_line(Line) :-
        get_char(Char),
        get_line_2(Char,L),
        concat_atom(L,Line).

get_line_2('\n',[]) :- !.
get_line_2(A,[A|R]) :- get_char(B),get_line_2(B,R).

get_line_2は引数が違いますから、get_lineでもいいのですが、
ちょっと理由があってこうしました。これについては後に。
2010/11/16(火) 22:09:40
ストリーム付きのget_line すなわち get_line/2

>>71 でget_line/2を使わなかったのは、この述語定義のために
残して置きたいという理由からでした。

get_line(Stream,Line) :-
        get_char(Stream,Char),
        get_line_3(Stream,Char,L),
        concat_atom(L,Line).

get_line_3(Stream,'\n',[])..
get_line_3(Stream,A,[A|R]) :- get_char(Stream,B),get_line_3(Stream,B,R).

という定義であり、
?- open(File,read,Instram),get_line(Instream,Line),close(Instream), ... の
ように使います。
2010/11/16(火) 22:17:45
タブで終了させたい場合もあるでしょう。

get_line(Line) :-
get_char(Char),
get_line_2(Char,L),
concat_atom(L,Line).

get_line_2('\t',[]) :- !.
get_line_2('\n',[]) :- !.
get_line_2(A,[A|R]) :- get_char(B),get_line_2(B,R).

のように終止節を追加します。OSによっては、入力に
newline の他にキャレッジリターンフィールが入力される
ことがあり、これは無視するために、
get_line_2('\t',[]) :- !.
get_line_2('\n',[]) :- !.
get_line_2('\r',R) :- get_char(B),get_line_2(B,R),!.
get_line_2(A,[A|R]) :- get_char(B),get_line_2(B,R).
のように一節挿入します。
2010/11/16(火) 22:44:02
業務用途ではないけどミドルウエアでは使われているよ。
あと、なぜ殆どの人はprologを言語上の述語理論でしか考えてない/られないのかね。
まるで判ってないと思う。
2010/11/17(水) 06:15:18
>>74
(工夫して)書いてみる前に判った気がしてしまう。これも、述語理論の所為から
知れないよ。
2010/11/17(水) 07:31:46
入力はなしの続きです。
Prologでは引数で値を渡す定義が普通で、標準入力からデータ受け取って、
その後の処理をするプログラムはあまりありません。しかし、C/C++の宿題は
ほとんどすべてこの形式で出題されていて、このようなスタイルのPrologに
ついて整理する機会を得ました。それで、次からは入力検査についての話を
します。
2010/11/17(水) 08:07:05
>>74
うちもWebサーバ、Proxy、メールサーバ、などはPrologだけど、
Prolog だからというよりは、自前だから便利というところだな。
2010/11/17(水) 08:08:36
CGIでなくダイレクトにアプリが応答できるのはもちろん便利だけど。
2010/11/17(水) 09:57:09
最近は、原則として以下のような入力検査を必ずすることにしている。
例として、入力データが整数であることを要求されているとする。

整数データの入力(N) :-
write('整数を入力してください : '),
get_line(Line),
整数データの入力診断(Line,N),!.
整数データの入力(N) :- 整数データの入力(N).

整数データの入力診断(Line,N) :-
atom_to_term(Line,N,_),
integer(N),!.
整数データの入力診断(Line,N) :-
write_formatted('入力された %t からは整数が得られませんでした。再入力をお願いします\n',[Line
]),
fail.

ポイントは、
・ 整数以外のデータが入力されたら、それは捨てて、再入力を要求する。
・ 入力のトップレベルつまりget_lineのある述語定義では診断をしない。
2010/11/17(水) 09:58:03
最近は、原則として以下のような入力検査を必ずすることにしている。
例として、入力データが整数であることを要求されているとする。

整数データの入力(N) :-
        write('整数を入力してください : '),
        get_line(Line),
        整数データの入力診断(Line,N),!.
整数データの入力(N) :- 整数データの入力(N).

整数データの入力診断(Line,N) :-
        atom_to_term(Line,N,_),
        integer(N),!.
整数データの入力診断(Line,N) :-
        write_formatted('入力された %t からは整数が得られませんでした。再入力をお願いします\
n',[Line]),
        fail.

ポイントは、
・ 整数以外のデータが入力されたら、それは捨てて、再入力を要求する。
・ 入力のトップレベルつまりget_lineのある述語定義では診断をしない。
2010/11/17(水) 09:59:48
入力のトップレベルと診断してしまうと、そこでfailになった場合、
get_line/1でせっかく入力された文字列とLineの束縛がそこで解かれて
しまって、

整数データの入力(N) :- 整数データの入力(N).

の引数を増やしてみても、Lineを受け取ることはできません。このため、
診断結果の表示はLineを渡された述語の中で行います。

atom_to_term は parse_atom という処理系もあり、文字列からPrologで
認識できる項を切り出す述語です。第三引数については後に説明します。
2010/11/17(水) 10:04:42
表現が適切でない部分があったため、重複しますが、書き直しました。

ポイントは、
・ 整数以外のデータが入力されたら、それは捨てて、再入力を要求する。
・ 入力のトップレベルつまりget_lineのある述語定義では診断をしない。

入力のトップレベルで診断してしまうと、failになった場合get_line/1で
せっかく入力された文字列とLineの束縛がそこで解かれてしまって、

整数データの入力(N) :- 整数データの入力(N).

の引数を増やしてみても、Lineを受け取ることはできません。このため、
診断結果の表示はLineを渡された述語 整数データの入力診断/2の中で
行います。

atom_to_term は parse_atom という処理系もあり、文字列からPrologで
認識できる項を切り出す述語です。第三引数については後に説明します。
83デフォルトの名無しさん
垢版 |
2010/11/20(土) 16:36:40
ちょっとしたシナリオの検証をするのに役に立つなー
2010/11/22(月) 19:04:17
>>58
この問題を蒸し返しますが、今日、私が要求されている
業務処理の大半が、Webからの情報の安定した抜き取りで
あり、そこで得られた情報の組み合わせを、保存する
ことです。いわゆる、計算はほとんどありません。
このような業務処理への適性では Prolog はスーパーの
クラスの中にいることは間違いありません。
2010/11/22(月) 19:12:52
昨日から Prolog を始めた初心者です。まるきり興味本位でやっています。
環境は Java6+PrologCafe1.2.5 です。

宿題スレにあった設問を自分なりに解いてみました。
http://www.dotup.org/uploda/www.dotup.org1263511.txt.html
パターンの数え上げ手法はあるソースを参考にしました。
あんまりあちこち見てて、どこだったかは分からなくなってしまいました。

その他いろいろ資料をあさってやってみたのですが、
switch文だの3項演算だのが頭にちらついて、どうも汚い感じにしか組めません。
とてもじゃないけどこれを「宿題だ持って行け」とは言えない・・・

メモリ足らずで JVM様が例外はいたりするので、
計算回数減らすための処理もこちょこちょ書いてるんですが、
たぶんすごく回りくどいことしてるんだと思います。
! もよく分からないので避けちゃってます。
もし簡単に改善できるところがあれば教えていただけると幸いです。
2010/11/23(火) 06:22:55
>>58
わが社の業務処理時の手動でのPrologインタプリタの負節入力(?- から始まる質問)の
累積数は18年間に70万を超えています。ほとんどが売上伝票入力ではありますが、
不自然さは全くありません。トランザクションとしては、別にPOS経由のものがあり、
こちらの累積は21年間で3000万くらいになります。Prologとの相性という点では、
従業員30-60名くらいの小企業だからこそと言うことができるかもしれない。よくぞ
小企業でいてくれた!,が正直な感想ですね。
2010/11/23(火) 06:50:46
>>85
恐縮ですが、書き込まれた解答を、
http://nojiriko.asia/prolog/prolog_177_1.html に勝手に転記させていただきました。
uploadサイトの掲載時間に制限があるためであり、著作権については可能な処置を
したつもりです。
2010/11/23(火) 07:04:41
>>85
ストレートフラッシュを除くフラッシュが一回目の配札で出現する確率は
_確率 is 4 * (13/52) * (12/51) * (11/50) * (10/49) * (9/48).

ですよね。仮に、全知全能というよりも予言者的なプレーヤーがつぎに
配られる5枚のカードを分かってしまって、フラッシュになるに相応しい
手札の取り替え戦略をとったとすると、確率はどうなるんですか?
8988
垢版 |
2010/11/23(火) 07:06:00
ごめん、ストレートフラッシュを含んだでした。
2010/11/23(火) 11:11:43
4枚同じマークが配られて、一枚交換して、フラッシュになる確率は、
_確率 is 4 * ((13/52) * (12/51) * (11/50) * (10/49) + (1/47)).

でいいのかな?
9190
垢版 |
2010/11/23(火) 11:14:46
あ、大間違いw
これから、夕方まで出かけるから、
その後で直します
2010/11/23(火) 11:31:43
_確率 is 4 * ((13/52) * (12/51) * (11/50) * (10/49) * (39/48) * (9/47)).
となるのかな? これを2-5枚とやっていって、合計がフラッシュの確立かな。
本当かね。
9392
垢版 |
2010/11/24(水) 06:58:29
>>92 これまた、大間違い。判りません。
2010/11/29(月) 22:45:09
論理プログラミングに最近強い関心があるので質問

1.学ぶ際にPrologを選んでも大丈夫?(念の為)
2.Wikipediaに目を通した感じではAZ-PrologやSWI-Prologが良さそうだけど、お勧めの処理系は?
2010/11/30(火) 05:10:29
1..それ以外の選択はむずかしいのではないかな。
2.. 日本語マニュアルが必要なら、AZ=Prolog。この処理系は1980年代に一世を風靡した
  Prolog-KABAの後継を目指して開発されたもので、オンラインマニュアルの他、
  Prolog-KABAの解説本も参考書になります。
  今後、多くの仲間とライブラリを分け合ったりしながら発展していくには、
  SWI-Prologがお勧めです。2000年代に入って最も活性のある処理系だと思います。
  以前はバージョンによっていろいろ問題がありましたが現在は日本語も制限なく使えます。
おまけ.. Prologに慣れたら、Progol(誤植ではない)という処理系をインストールて
  機能論理Prologで遊んでみるといいと思います。すでに定義された節から、
  どうやったら新しいルールをProgolに生成させることができるか。大変興味い
  テーマを楽しめます。
9695
垢版 |
2010/11/30(火) 05:12:33
機能論理Prolog は 機能論理プログラミングの間違いでした。
9795
垢版 |
2010/11/30(火) 05:13:53
それから AZ=Prolog -> AZ-Prolog
2010/11/30(火) 06:33:50
>>95
もしProgolに手を出すなら
帰納論理プログラミングの入門書もどうぞ。

帰納論理プログラミング
http://furukawa.sfc.keio.ac.jp/book/
http://www.amazon.co.jp/dp/4320120140/
2010/11/30(火) 07:23:30
大変! ^ wwww
機能論理プログラミングになっている。
帰納論理プログラミングの間違いです。
2010/11/30(火) 08:27:40
>>95-99
レスありがとう
処理系は俺の場合は既存の資産もないし、英語マニュアルに抵抗もないからSWI-Prologにする
帰納論理プログラミングも面白そう
ちょっと違うかもしれないが論理プログラミングにおけるメタプログラミングみたいな感じ?
2010/11/30(火) 08:40:23
>>100
関数型のメタプログラミングはあまり詳しくないから、そうだとも違うともいえませんが、
帰納論理プログラミングは(集合の)外延定義にヒントを与えてやると内包定義つまりルールを
生成してくるというような感じです。もちろん、外延だけでなく、内包も考慮しますから、
かなり複雑なルールの生成も可能なようです。しかし、一種のリバースエンジニアリング的な
ものですから、生成されるルールの可能性が大きく成りすぎて、収拾がつかない。というのが
私のレベルですね。
102101
垢版 |
2010/11/30(火) 08:48:01
リバースエンジニアリング的という表現は適切でなかったので撤回します。
どういう表現が適切であるかは、もう少し考えます
2010/11/30(火) 12:56:16
メタプログラミングは「ロジックを生成するロジック」または「プログラムを生成するプログラム」
帰納的にルールを導出するというのがメタプログラミング的だと思ったけど
よく考えたら帰納も演繹もそうありうるような気がしてきた……
104デフォルトの名無しさん
垢版 |
2010/12/07(火) 03:33:25
むつかしい
2010/12/07(火) 09:05:15
>>103
ロジックを生成する事と、隠された
ロジックを発見する事は違うんじゃ
ないか。
2010/12/07(火) 10:52:10
隠されたは言い過ぎだな。
せいぜい、隠れたロジック。
2010/12/07(火) 11:20:40
定義節集合から新たに論理式(述語定義)を発見するのが
帰納論理プログラミングであり、一方、我々の日常的な
プログラミングの目標は、課題(仕様)の自然言語表現から、
論理式(述語定義)を発見して、Prologプログラムとして
書くこと。
仮に、コンピュータを自然言語で操作することを目標と
した場合には、Prologの次善の言語としての地位は現在
も揺らいではいない。
108デフォルトの名無しさん
垢版 |
2010/12/23(木) 15:02:41
あげなさい
2011/01/01(土) 18:44:51
swi-Prologを使用しています。
listingでプログラムをセーブするとき、tell(出力先)を使うしかないのでしょうか?

2011/01/01(土) 19:38:50
>>109
open/3,listing/2,close/1などが使えないものか、
ということですね。私はtell/1でしか使ったことが
ながったので、確かめてみました。
結論からいうと、ストリームの使用はできないようですね。
111デフォルトの名無しさん
垢版 |
2011/01/01(土) 23:19:30
迷路で全ての経路探索とか出来るのん?
2011/01/02(日) 01:17:51
方程式を自動で解くことはできるのん?
2011/01/02(日) 06:59:51
>>111
Prologでまったりスレでも何回となく示された述語先祖で考えてみます。
親子(為義,義朝).
親子(義朝,頼朝).
の関係が定義されている時、先祖関係は、

先祖(A,B) :- 親子(A,B).
先祖(A,B) :- 親子(A,C),先祖(C,B).

で定義できます。
これは 為義 --- 義朝 --- 頼朝 の関係ですが、
これを 為義 --- 義朝 --- 義平
       |- 為朝 |- 頼朝 --- 範頼
と定義し直します。
親子(為義,義朝).
親子(為義,為朝).
親子(義朝,義平).
親子(義朝,頼朝).
親子(頼朝,範頼). ですね。先祖関係の定義もちょっとだけ手を入れて、
先祖(A,B) :- 親子(A,B),write_formatted('%t-%t\n',[A,B]),!.
先祖(A,B) :- 親子(A,C),write_formatted('%t-%t\n',[A,C]),先祖(C,B). ここで、

?- 先祖(為義,範頼). を実行してみます。
為義-義朝
義朝-義平
義朝-頼朝
頼朝-範頼
yes で終了となります。あとで続きを書きます。
2011/01/02(日) 07:04:12
系図が歪んでしまいました。書き直し。

これは 為義 --- 義朝 --- 頼朝 の関係ですが、
これを 為義 --- 義朝 --- 義平
         |- 為朝  |- 頼朝 --- 範頼
2011/01/02(日) 07:15:36
>>113
で示した親子関係が迷路の回路選択を抽象したものになっていると思います。
分岐点(例えば為義)から開路である義朝に進むか、為朝に進むかの選択があります。
Prologは深さ優先選択という戦術で、次に義朝-義平の順で進んで行きます。
義平には子はいないようなので、諦めて、義朝分岐点に戻り、頼朝を選択する。
こうして、範頼にたどり着きます。
2011/01/02(日) 07:18:02
最後に強調されるべきことは、この経路選択
プログラムが

先祖(A,B) :- 親子(A,B).
先祖(A,B) :- 親子(A,C),先祖(C,B).

という極めて簡素な定義によって書き切られていると
いう点です。
2011/01/02(日) 14:24:42
AZ-Prologの64bit版は、6Gbyte以上のメモリーを推奨していますが、SW-Prologの64bit版は、どうなんでしょうか?
4Gbyteだと、問題があるでしょうか?
2011/01/02(日) 14:44:59
>>117
SWI-Prologの64bit版は使ったことがないので、
これは回答ではありません。
AZ-Prologの64bit版についてですが、これは新しい
版がマルチコア対応の並列処理機能を目玉にして
いるため、必ずこの機能が使われるに相違ないとして、
保険をかけた感じで、大きなメモリーを推奨しているに
過ぎないと思います。小さいと動かなくなる理由はない
はずです。
2011/01/02(日) 14:57:01
>>112
これに答えるのは私の能力を超えるので簡単に。
現在のPrologの仕様で引数の評価に大きな力を持た
せることは、ユニフィケーションが邪魔をして無理です。
さらに、現在のPrologの基本的に持っている能力は
変数の変域が離散的でごく限られた数である場合に、
虱潰しに変数に候補要素をあてはめて、確かめること
だけだと思います。変数制約を解消していくどんな機構も
持っていません。これを解決するには、この目的のために、
開発された、制約論理型プログラム言語を利用する他ない
のではないでしょうか。
多くの制約論理型言語はそのサブセットとして、Prologを
持っていますから、そういう利用が多いユーザは最初から
制約論理型言語を選択するべきでしょう。
120デフォルトの名無しさん
垢版 |
2011/01/02(日) 23:44:13
おお説明来てる
が、むずい
勉強しよう
2011/01/03(月) 02:58:48
>>119
詳しい解説があったのでリンクします。

制約論理プログラミング
http://ja.wikipedia.org/wiki/%E5%88%B6%E7%B4%84%E8%AB%96%E7%90%86%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
制約プログラミングのページ
http://www.constraint.org/constraint_org.htm
2011/01/07(金) 09:21:23
Prologの入門本の学習順序の提案

杉崎昭生著「Prologを学ぶ」(http://www.amazon.co.jp/dp/4303716901/)
->
古川康一著「Prolog入門」(http://www.amazon.co.jp/dp/4274073084/)
2011/01/08(土) 00:35:13
素人ですが、事例を検索するプログラムを考えています。
例えですが、文字列と、それを含むページについて考えます。
記号aを、この文字列として表すときは"a"とし、変数とするときはそのまま裸のaで表すことにします。
あいまいな表現になりますが、「aを含むページである」というのをPg(a)と表すと、
「Pg(a) ならば Pg(b)」 というのは、「aを含むページなら、bを含むページである」ということになります。
この式の値として、式を変形し、「¬(Pg(a)) または Pg(b)」 とし、aを含まないページの集合とbを含むページの集合の和集合を求め、そのページ数を全ページ数で割った値とします。この式の否定の値は、1との差の値になります。
式の値をこのようにするのは数学的に妥当なものなのでしょうか?
2011/01/08(土) 05:15:34
>>123
「全ページのうち、命題を否定しないページと否定するページの割合」を計算しています。
数学的に妥当でない操作は行われていません。
でもaを含まないページは事例検索の利用者にとって無関係な事例でしょう。
必要なのは「aを含むページのうち、bを含むページと含まないページの割合」なのでは?
2011/01/08(土) 08:34:44
>>123
Pg(a) を太宰治が現れるページ Pg(b) を文学という語が
現れるページとすると、
「この式の値として、式を変形し、「\+(Pg(a)) または Pg(b)」
とし、aを含まないページの集合とbを含むページの集合の
和集合を求め、そのページ数を全ページ数で割った値」とは

(全ページ数 + 太宰治という語が現れないが文学という語の現れるページ数) / 全ページ数
ですね。この比率 - 1 は

( Pg(a),\+(Pg(b))のページ数 / 全ページ数 ではなくて
( \+Pg(a),pg(b))のページ数 / 全ページ数 なのではないか。
126124
垢版 |
2011/01/08(土) 10:00:12
>>125
A=太宰治がなく文学がないページ
B=太宰治があり文学がないページ
C=太宰治がなく文学があるページ
D=太宰治があり文学があるページ
とおくと、

全ページ = A+B+C+D
¬(Pg(a)) = A+C
Pg(b) = C+D
¬(Pg(a)) または Pg(b) = A+C+D
になります。

「aを含まないページの集合とbを含むページの集合の
和集合を求め、そのページ数を全ページ数で割った値」は
(A+C+D) / (A+B+C+D) です。
全ページのうち、「太宰治を含むなら文学を含む」を否定しないページの割合です。
これは1以下になります。この割合-1は無意味です。

1-この割合は B / (A+B+C+D) です。
全ページのうち、「太宰治を含むなら文学を含む」を否定するページの割合です。

>>123
事例検索の利用者にとっては太宰治を含まないページはどうでもいいから
役に立つのは「太宰治を含むページのうち、文学をを含むページの割合」と
「太宰治を含むページのうち、文学を含まないページの割合」ではないでしょうか。
127125
垢版 |
2011/01/08(土) 10:12:56
確かにそうですね。ありがとう。
2011/01/08(土) 10:14:57
>>126
レスにし損なりました。もう一度、
確かにそうです。ありがとうございました。
2011/01/08(土) 10:53:31
「Prologの宿題片付けます」スレで出ている、Prologの
解説本の中に8クィーンアルゴリズムは何種類くらい
あるかな、という話は現在まとめ中です。あまり、この
言語向きの課題とは思えないけど。
この言語向きの課題といえば、20年くらい前にProlog
を買っていた時、本屋の立ち読みの評価基準に使って
いたのが、経路問題の多寡。もちろん多いほど読み応え
がある。この基準でどんな本を復活できるかやってみま
しょう。
2011/01/08(土) 11:08:44
どんな本を復活できるか、とは妙な言い回しですが、
もう五年以上前になりますが、本棚に眠っていた、
「Prologを学ぶ --文化とその実践--」という本を
読んでみて、気に入ったというよりよく書けているのに
感心した。Amazonで確認してみるとほとんど売れ行き
は最下位近くに低迷していた。そこで、読み直したら
赤面ものの内容のないカスタマーレビューを書き、
星五つの評価を付けた。驚くべきことに、それ以降、
この無名本は常時Prolog本の売れ行き上位に入り続け
今日でも絶版にもならず、Amazonでは売り切れては
入荷をくり返している。こんなことで、忘れ去られた本
たちが復活できるなら、いくらでも労は惜しみません。
131123
垢版 |
2011/01/08(土) 12:30:04
経験の事例を単純に選言標準形で表したプログラムを考えていますが、
その世界での論理値を0から1までの値にして数学的な破綻がないかどうかが気になっていました。
意味のある検索とか、推論とかも、比の論理値で色々考えてみるつもりです。
2011/01/08(土) 13:02:44
ファジィ論理?
133123
垢版 |
2011/01/08(土) 13:25:09
>>132
初歩的な統計学の範囲だと思います。
2011/01/09(日) 08:49:36
手続きを書くのではなくて、
ぷろろぐに手続きを任せるって認識でいいのだろうかー
PGは関係を定義しておくだけという
で、がらがらと処理して真か偽かと
2011/01/09(日) 10:45:34
2ch ヘッドラインニュースBBY(一覧性が秀逸)http://headline.2ch.net/bbynews/

どんな難解ニュースでも掲示板の書き込みでオモシロおかしく簡単理解。
ニュースを勢い順にカテゴリー別で表示する"2NN"(2ちゃんねるニュース速報+ナビゲーター)もどうぞ。
2011/01/11(火) 18:07:30
>>134
Prologはプログラムには確実に実行順序があります。
この実行順序を"意識"すると手続きになり、意識しない限りは
宣言的である(宣言的に読んでいる)といえます。

Prologの副目標(subgoalともいう)は真偽値しか返しません。これが
Prologプログラミングの核心であって、プログラマは、実際には、
全部真であるに違いないという姿勢でこの本体の記述を読みます。
つまり真偽値さへも意識しないのです。そして引数の変数の遷移を
一瞥します。
Prologを読むときにすることはこれだけです。そう、これだけです。
返り値のこともあるいはそのデータ型やクラスについて思いめぐら
すことは全く、ありません。
137デフォルトの名無しさん
垢版 |
2011/01/12(水) 23:53:14
ふm
肝はデータベースと見た
2011/01/13(木) 05:25:54
>>137
そうです。条件のない、命題だけからなる
Prologプログラミングが"理想"ですね。
2011/01/14(金) 12:45:05
別解を求めていくためにカットを使わないところがあると、別解を求めていくとき、
節を選択する条件を兼ねた命題が失敗して次の節が選ばれればいいのですが、失敗でないのに次の節に移るときがあります。
そのために、条件の否定を加える必要があるのですが、
一般的に、カットを使わないときは、カットによって省略できていた命題を加えればいいということなのでしょうか?
2011/01/14(金) 16:24:02
>>139
必要なことは、a,bが条件だとすると、

p(X) :- a,b,X=1.
p(X) :- a,\+(b),X=2.
p(X) :- \+(a),b,X=3.
p(X) :- \+(a),\+(b),X=4.

のような定義を「気楽」にできること。
実際には、a,b,の中に副作用があったりして
このような記述が不可能の場合もありますが。
我慢して、このような冗長なコードを書いて
いると、ご利益として、ブール代数的直感が
鋭くなってきていつの間にか以前よりも正確
なコード書くことができるようになります。
2011/01/15(土) 22:48:50
問題 3つの整数があります。AとBとCの和が160,Aの2倍とBの3倍とCの和が297,Bの2倍とCの和が149で
す。Bはいくつですか。

'Bはいくつですか'(N) :-
    length(D,160),
    append(A,B,C,D),
    length(E,297),
    append(A,A,A2),
    append(B,B,B,B3),
    append(A2,B3,C,E),
    length(F,149),
    append(B,B,C,F),
    length(B,N).

?- 'Bはいくつですか'(N).

N = 42

の解がでるまでにIF/Prologインタプリタで
6分30秒かかった。
142141
垢版 |
2011/01/19(水) 08:31:21
間違い。2.2GhzCPU Ubuntu10.10で242秒でした。
2011/01/21(金) 13:07:46
['X']というアトムのリストを、[X]という変数のリストにするにはどうすればいいのでしょうか?
144143
垢版 |
2011/01/21(金) 14:59:50
一応、外部にリストの形の文字列を出力してから、入力しています。
2011/01/24(月) 06:45:38
>>143
どういう局面で変数ラベルがプログラマの期待通り
表示されるのかという問題と考えよう。
処理系によって異なるとおもうけれど、Heap領域に
元々の変数のラベルと現在の変数の一意名(大きの
場合番号)の対応表が確保される。この対応表が
Prologの処理系によって参照されるのは、
・listingなど定義節の表示(これは否応なくHeap
   領域の参照が生じる。そのついで)
・インタプリタのトップレベルのインタプリタ側が
サービスとして表示する変数名。
であって、
?- atom_to_term('X',A,Varlist),write(A),nl.
を実行しても、
このトップレベルには変数Xが存在しないため、
_G24689
A = _G24689
yes としか表示されない。
つまり、トップレベルに現れる変数は例外として、
反駁途中stack領域内でのユニフィケーションに
よって生じた当然の変数名は処理系がプログラマ
がこの変数名に何を期待しているかというような
推論を行わなわず、したがって、スタック内の
変数ラベルをこれに置き換えるというようなコスト
のかかる作業を行わないため表示されることがない。
あとで続きを書きます。
146自己レス
垢版 |
2011/01/24(月) 07:05:00
>>145
ごめんなさい。まちがえました。

?- atom_to_term('X',U,Varlist),write(U),nl. を実行すると、
_G24689
Varlist = ['X' = U]
となります。注目はwriteで表示される変数はUでもXでもなく、
_G24689であるという点です。
2011/01/24(月) 11:43:29
consult/1やreconsult/1でファイルからソースプログラムを
読み込むときは、読み込んだ文字列をparse_atomして、第三
引数のVarlistをヒープ領域に、変数名と定義した節構造の
中の変数Idのペア、として登録します。
ユーザがreadしてからassertする場合は、処理系によります。
assertz_with_namesのようなVarlist処理をオプションに
持った処理系の場合は,
?- ... read_with_names(P,V),assertz_with_name(P,V), ...
としておくことで、後にユーザが指定したかった変数名を
あくまで字面だけの問題ではありますが、「復元」するこ
とができます。
このようなオプションがあれば、より高度なインタプリタを
構築したり、マクロ処理を取り入れる場合には、この復元
を使うことによって、使い易い、分かりやすい、インタブリタ
やデバッガを作成することができます。
しかし、これらのことはあくまで変数を表示する際の「字面」
だけの問題であり、Prolog実行時のユニフィケーションに
よる、スタックの書き換え処理では、そのすべてが無機的な
変数Idの単一化だけで処理されている、ということを理解
する必要があります。
148143
垢版 |
2011/01/24(月) 22:53:06
>>147
質問が不適切だったと思います。
一般的に言うと、文字列として表現した節を、プログラムとしての節に変換するにはどうすればいいかということです。
外部のテキストをプログラムとして読み込めるなら、内部で「']と「']で囲まれた文字列をプログラムとして読み込めてもいいと思います。
149148
垢版 |
2011/01/24(月) 23:10:15
atom_to_termという述語を使えばいいと分かりました。
まったくの素人レベルのことです。
2011/01/25(火) 18:57:10
>>148
この言語で説明が最も難しい問題のひとつです。
よい質問だったと思います。
私の回答も不十分あるいは不適切なものでしたね。
151デフォルトの名無しさん
垢版 |
2011/03/03(木) 19:28:07.67
あげるべきだろう
2011/03/08(火) 07:50:13.35
http://nojiriko.asia/prolog/mojiretsu.pro

このサイトの後半部分は正規表現で書くことが
できるものをProlog述語で定義するとどうなるかと
いう課題への解答が集められています。

やはり、正規表現では1行で済むところが述語定義
では7-8行、場合によると10行以上になる場合も
少なくありません。しかし、ここで私が問いかけたいのは、
記述の効率性の問題だけではなく、これらの述語の名前と
して、正規表現として正解の表現を置いたとすると、この
述語名の解説としてPrologコードがどの程度有効な
ものになっているか、と言う観点です。(注1)
この観点からは、Prologは相当に優秀な言語だといえる
のではないか。そうであるといいなと思っています。

(注1) 残念ながら、正規表現の正解が元サイトでも
今ひとつはっきりしないため、述語名は日本語での
表現になっています。
2011/03/08(火) 20:45:35.91
同じサイトのこちらでは、
http://nojiriko.asia/prolog/onmemory_database.html

Prolog単位節をオンメモリデータベースに見立てて、
SQLによる問い合わせと等価なProlog述語定義を
試みています。
2011/03/08(火) 21:29:14.81
>>153
ピーター・グレイの名著 「論理・代数・データベース --知の工学の基礎--」 の
下支えとして位置付けて、このサイトを読まれるとよいと思います。
2011/03/13(日) 04:44:42.40
「いろんな言語で宿題スレ」での出題に
対するProlog解答を集めたWebサイト

http://nojiriko.asia/prolog/

は現在1600解答を集めました。
先週、主要述語の用例集をこのサイトに集めた
解答から抜き出して追加しました。
各用例の題材は現在は出現順にならんで
いますが、今後のこれを意味別に並べ直すつもりです。
解説も極く一部しかついていませんが、意味別に
大分して、それに対して解説を追加する予定です。
最終的には、さらに主要Prolog処理系の互換性を
取るための述語などをここにします。
156155
垢版 |
2011/03/13(日) 04:46:48.84
訂正 最終行 ここにします。 -> ここに追加します。
2011/04/17(日) 09:16:01.11
x-euc-jpはeuc-jpにして欲しい…
158デフォルトの名無しさん
垢版 |
2011/04/23(土) 15:05:55.54
エキスパートシステムとか書けたりする?
2011/04/23(土) 17:33:12.15
>>158
Prologはエキスパートシステム記述するための
言語のひとつということになっている。

私が書いたことがあるか、とか、今書けるかという意味だと
すると、答えは、
20年前には結構書いた。業務用も含めて。
対象が定まれば、サンプル的な短いものなら今でも書ける。

大別して前向き推論によるものと後ろ向き推論のものが
あるが、私は全て後ろ向き。
Prologにとってはこちらの方が自然ということらしい。
2011/04/25(月) 23:18:32.73
エキスパートシステム書けるのですか。
…冷静に考えればprologなればこそ書けなきゃおかしいか。

IBMがprologで自然言語処理がうんたらかんたらしてるらしいので
もっと注目されてほしいなぁ。
2011/04/27(水) 18:00:50.94
>>160
急に注目されはじめたようですよ。
2011/04/27(水) 19:57:36.82
エキスパートシステムなんてどんな言語でも簡単に書ける。
prologはファクトの無限導出を副作用をつかって
避ける必要があるので、むしろ面倒なくらいだ。
2011/04/27(水) 20:58:39.35
>>162
「どんな言語でも」書けるもんなら書いてくれ。
2011/04/28(木) 11:32:17.24
どんな言語でもというと語弊があるだろうけど、そんなに難しいものでは
ないという点には同意。
Prologだとappendだけで書けるレベル。かってはスタックオーバーフローや
GCの頻発に悩みながらだったが、現在は、2GB以上のプロセスが当たり前で
データをすべて引数で持ち回っても問題はない。
Prologの利点は、何といっても作り込みが容易なこと。業種、企業、生産現場に
よって、全く異なるデータのサンプリングの方法を仕様がしっかり文章化されて
いれば、簡単に述語として追加・変更できることだろう。
2011/04/28(木) 11:50:39.82
最近のエキスパートシステム事情には疎いのだけれど、
かっては確かにルールをシンボル化してその論理式を
assert,retractしながら利用するというような手法が
使われていたと思うけど、今は、
非決定性のappend/3 を ...,apppend(L1,[A|L2],L),filter(A,B), ...
のように使って、例えば、Bの排他的要素がL1,L2に存在
するか確かめながら(これもappend/3)進むというような
ものがほとんどだと思う。
2011/04/28(木) 23:29:22.17
>>164
私が今書くとすると、"Prolog Programming For Artificial Inteligence" の14章を
一度読みなおしてからということになるが、十分に難しいよ。
他の言語でやさしいかどうかは知らないが。
2011/04/29(金) 00:45:50.54
Prolog全然使えん。簡単なループ文書くのですら一苦労だ。
2011/04/29(金) 12:35:51.70
斬新な用途ですね。

2011/04/29(金) 21:02:38.40
prologが得意な人は行列積とかどんな風に書くのかな

自分で書くと、とても綺麗とはいえないコードになる
2011/04/29(金) 22:04:54.18
線形代数関係は、LAPACKに処理を投げるのがプログラミングの定石では?
PrologからLAPACKにどうやって処理を投げるのか知らないけど。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況