トップページ⇒tech
983コメント289KB

Prolog でまったり

■ このスレッドは過去ログ倉庫に格納されています
0001人工無能NGNG
Cなどの言語とは全く得意分野も構造もちがうProlog。
そんなPrologについてまったり話しましょう
0232名無しさん@XEmacsNGNG
>>231
> KLCはどうですか。
> 五世代プロジェクトの

KL1 ね。で、UNIXen で動くその言語処理系が KLIC。

Prolog とはかなり趣を異にするけど、これはこれで結構面白い言語だ
わな。副作用なしで入出力が扱えたりするところとかね。
0233貼っとくNGNG
prologディレクトリ
http://dir.goo.ne.jp/computers/00941/00979/00988/
0234デフォルトの名無しさんNGNG
なローイングってあに?
0235デフォルトの名無しさんNGNG
あいーん
0236デフォルトの名無しさんNGNG
Prologのコンパイラでは
実行ファイル(.EXE)は作成されないの??
0237デフォルトの名無しさんNGNG
>>236
Turbo Prolog では作れたよ。
0238デフォルトの名無しさんNGNG
試してみます。
ども。
0239デフォルトの名無しさんNGNG
本家スレage
0240okdNGNG
SWI-PrologをWin98SEでダウンロードして使おうとしたのですが、日本語を節名や変数名に使えないのですが、何かよい方法はないでしょうか?
0241デフォルトの名無しさんNGNG
普通は、シングルクオート '' で囲う。そんで日本語フォントで表示させる。

しかし、シフトJISコードの2バイト目に \ とかがあると
モロ化けるので、フォントを設定するくらいではどうしようもないね。
0242デフォルトの名無しさんNGNG
みつけた!
ここみんな必見だよ
プロログの動作原理
http://web.sfc.keio.ac.jp/~tozaki/LP/01/handout/prolog-dousa/
0243デフォルトの名無しさんNGNG
Prologを使いこなすとハッカーだって言うけど本当ですか?
0244デフォルトの名無しさんNGNG
さあ
0245242NGNG
と思ったけど結構浅いや(汗)
スタックな図とか初めめちゃくちゃ分かりやすいと思ったんだけどね。

>>243
>>209
0246デフォルトの名無しさんNGNG
Prologを使いこなすとお金持ちになれるって本当ですか?
0247デフォルトの名無しさんNGNG
Prologを使いこなすと彼女ができるって本当ですか?
0248デフォルトの名無しさんNGNG
Prologを使いこなすと大学卒業できるって本当ですか?
0249デフォルトの名無しさんNGNG
聞いてみろ。

?- available(girl,X).
no.
0250デフォルトの名無しさんNGNG
>>246 嘘
>>247 微妙
>>248 本当
0251デフォルトの名無しさんNGNG
>>246-250
深夜に自作自演ですか?
0252デフォルトの名無しさんNGNG
閉世界仮説
0253デフォルトの名無しさんNGNG
>>250 嘘つき。
0254デフォルトの名無しさんNGNG
?- liar(>>250).
Yes.
0255デフォルトの名無しさんNGNG
今日からProlog始めますた
なかなか意味不明ですた
0256デフォルトの名無しさんNGNG
お勧めの処理系は?
0257デフォルトの名無しさんNGNG
あ
0258デフォルトの名無しさんNGNG
>>255
俺も始めたさー。
なかなか意味不明だよねん。
でも意味わからないままさくさく書けるようになってしまう自分も
意味不明なんよね。
まぁゆっくりいきましょか。

ちなみにうちはK-prologとProlog Cafeっす。
0259 NGNG
SWI-PrologとEmacsプラグイン、ダウンロードしてみた。
0260デフォルトの名無しさんNGNG
>>259
同じく。只今いろいろといじり中
0261デフォルトの名無しさんNGNG
SWI-Prolog で

Clauses of hoge/4 are not together in the source-file

というワーニングに苦しめられてます
hoge/4 はいっぱい書いてあんのになぁ

一応、ちゃんと動いてくれてんだけど
0262デフォルトの名無しさんNGNG
Prologみたいな言語ってどう作ればいいんですか?
0263デフォルトの名無しさんNGNG
頑張って作ればよろしい。
0264デフォルトの名無しさんNGNG
>>261
メッセージの通り、同じ述語を定義するファクトやルールを、
同じ所に並べて書いてないんだと思われ。
hoge(1). hoge(2). hage(hage). hoge(3).
0265デフォルトの名無しさんNGNG
ちなみに、ワーニングと言うくらいならワーミングと言って欲しい
0266デフォルトの名無しさんNGNG
>>264
おお、スタイルに対して文句をいわれていたのかアレは・・・
ありがとう、おかげで綺麗に動くようにナタヨ・・・
0267デフォルトの名無しさんNGNG
パズルの本に下のようなのがあったんだけど、Prologで表現するとどうなります?

 ・Aさん、Bさん、Cさんの3人がいる。
 ・黒髪と茶髪と金髪が1人ずつ。
 ・Cさんは黒髪じゃない。
 ・金髪はCさんじゃない。
 ・黒髪はAさんじゃない。
 Q:Aさん、Bさん、Cさんの髪はそれぞれ何色?

こんな感じでいいの?

color(c, black) :- !, fail.
color(c, blond) :- !, fail.
color(a, black) :- !, fail.
color(_, _).

ans(A, B, C) :-
 select(A, [black, brown, blond], R),
 select(B, R, [C|[]]),
 color(a, A), color(b, B), color(c, C).
0268デフォルトの名無しさんNGNG
否定は \+ とか \== とかを使ったほうがいいと思うけど。

?- select(A,[black,brown,blond],_BC),select(B,_BC,[C]),A \== black, C \== black, C \== blond.

A = blond
B = black
C = brown

Yes
0269デフォルトの名無しさんNGNG
差分リストを使わないとできない事って何?
つーか、差分リストってなんか役に立つの?
0270267NGNG
おお、1行で書けちゃうんですか。どもです。>>268

>>267で書いたやつを、ちょっと直してみました。
リストも使わないようにしてみました。
前のやつと同じようにFactの部分を外に出してはあるんですが。
(改行略)
person(a). person(b). person(c).
col(black). col(brown). col(blond).

mismatch(c, black).mismatch(c, blond).mismatch(a, black).
match(Person, Color) :- person(Person), col(Color),
  \+ mismatch(Person, Color).

ans(A, B, C) :-
  match(a, A), match(b, B), match(c, C),
  A \+ B, B \+ C, C \+ A.

こういうのが大規模になったとき、例えば色が10万色くらいに
なったときってどう管理するんですかね?
Prologソースのままがいいのか、RDBがいいのか…
0271デフォルトの名無しさんNGNG
こんなのどうです?またパズルの本からですけど。
Prologやってる人ってこんなのも簡単に書けちゃうのかな。
始めたばっかなんで漏れには激しく難しかったんですけど。

 ・a、b、c、dの4人でレースをした。
 ・赤、緑、青、黒の服のうち、それぞれ違うのを着ている。
 ・w、x、y、zの形のブローチのうち、それぞれ違うのを着けている。
 ・赤服に続いてaがゴール。aに続いてyブローチがゴール。
 ・zブローチの次にb。bに続いて青服。
 ・wブローチの次に黒服のc。

 Q:1位、2位、3位、4位はだれで何色の服でなんのブローチか?
0272デフォルトの名無しさんNGNG
こういうgenerate-and-testの場合、
ふつうはまず、「順列を(全とおり)作る述語」を作ると思う。

permute(L,[Car|Cdr]) :- select(L,Car,Rest), permute(Rest,Cdr).
permute([],[]).

?- permute(['赤','緑','青','黒'],色マップ),
permute([w,x,y,z],形マップ),
permute([1,2,3,4],順位マップ).
で、a,b,c,dが1,2,3,4(リストの要素の位置)に対応してる事にする。

例:条件「赤服に続いて a がゴール」
nth1(赤服,色マップ,'赤'), % 「赤服は誰か?
nth1(赤服,順位マップ,赤服の順位), % その順位は?
赤服の次の順位 is 赤服の順位 + 1, % その次の順位は?」まで調べて、
nth1(1,順位マップ,赤服の次の順位), % 「赤服の次はa(=1)である」
0273デフォルトの名無しさんNGNG
もちろん、ちゃんと述語で抽象化したほうがいい
0274デフォルトの名無しさんNGNG
SWI-Prologのcopy_term/2はループした節に使えないんだな。
?- S = s(S), copy_term(S,T).
ひょっとして使える方が変なのか
0275271NGNG
>>272
最初に条件同士が成り立つ組み合わせを求めて、あとで並べ替えを
当てはめてみる感じでやってみました。(test-and-generate?)

condition/1を通った時点で[X1,X2,X3,X4]が
[[○,○,z],[b,red,○],[a,blue,w],[c,black,y]]
の一通りだけに定まって、あとは単に空白を埋めるだけになると。

ちなみにもっと複雑な問題でも試してみたんですが、
最初に並べ替えを作ってから条件を通すより、かなり早いです。

?- ans([X1, X2, X3, X4]).
X1 = [d, green, z]
X2 = [b, red, x]
X3 = [a, blue, w]
X4 = [c, black, y]

次レスにソース。
0276271NGNG
ans([X1, X2, X3, X4]) :-
condition([X1, X2, X3, X4]),
result([X1, X2, X3, X4]).

condition([X1, X2, X3, X4]) :-
subseq([[_, red, _], [a, _, _], [_, _, y]], [X1, X2, X3, X4]),
subseq([[_, _, z], [b, _, _], [_, blue, _]], [X1, X2, X3, X4]),
subseq([[_, _, w], [c, black, _]], [X1, X2, X3, X4]).

result([[P1, D1, B1], [P2, D2, B2], [P3, D3, B3], [P4, D4, B4]]) :-
perm(person, [P1, P2, P3, P4]),
perm(dress, [D1, D2, D3, D4]),
perm(brooch, [B1, B2, B3, B4]).

subseq(X, Y):- append(X, _, Y).
subseq(A, [_|B]) :- subseq(A, B).

perm(_X, []).
perm(X, [H|T]) :- perm(X, T), call(X, H), \+member(H, T).

person(a).(略) dress(red).(略) brooch(w).
0277デフォルトの名無しさんNGNG
>>269 計算量O(1)でappendとかできるじゃん
0278デフォルトの名無しさんNGNG
例えばlotate([1,2,3], X)に対して、
X=[1,2,3];
X=[2,3,1];
X=[3,1,2];
X=[1,2,3];
と答えるような述語が、
lotate(A, X) :- append(M, N, A),append(N, M, X).
って書かれてるとして、
こういうのも差分リストで効率化できる?
0279278NGNG
スマソ
rotateの間違い。
0280デフォルトの名無しさんNGNG
面白そうだが、理解できない
0281デフォルトの名無しさんNGNG
リストから要素の重複をなくしたリスト(集合)を得る述語が書けません…
getSet(LIST,SET).=LISTの要素の集合はSETである
addSet(OLD,X,NEW) =集合OLDの要素にXを追加したものが集合NEWである

getSet([],_).
getSet([X|XL],OLD):- addSet(OLD,X,NEW), getSet(NEW,XL).
/*OLDにXを追加して、残りの分を処理*/

これでgetset([a,b,c,b,a],X).すると
X=[a,b,c|_210],
みたいにうしろにごみが。どうすればいいのでしょう。
addSet/3の動作に不備はないのですが。
setof/3のない処理系なんで困ってます。

>>278
ううん、それで十分効率的だと思うのですが。
0282281NGNG
ああっと。自己解決しました。
getSet(SET,[],SET).
getSet(OLD,[X|XL],NEW2):- addSet(OLD,X,NEW), getSet(NEW,XL,NEW2).

答えはgetSetにもOLD,NEWふたつつけることでした
0283デフォルトの名無しさんNGNG
>>278 分割と結合を分けたらできた。しかしややこしい。。
--------------------------------------
split_d(A-AX,L-L,R-R) :- A == AX, !.
split_d(A-AX,L-L,A-AX).
split_d([AH|AT]-AX,[AH|LT]-LX,R-RX) :- split_d(AT-AX,LT-LX,R-RX).
append_d(L-R,R-RX,L-RX).
rotate_d(A-AX,B-BX) :- split_d(A-AX,L-LX,R-RX), append_d(R-RX,L-LX,B-BX).
rotate(A,B) :- append(L,R,A), append(R,L,B).
sample_dlist(0,LX-LX) :- !.
sample_dlist(N,[N|LT]-LX) :- succ(NT,N), sample_dlist(NT,LT-LX).
test_rotate(N,R) :-
sample_dlist(N,L-[]), sample_dlist(N,DL-DLX),
( time(( between(1,R,_K), rotate(L,_B),
fail, writeln(_B), fail )) ; true ),
( time(( between(1,R,_K), rotate_d(DL-DLX,_DB-[]),
fail, writeln(_DB), fail )) ; true ),
true.
--------------------------------------
?- test_rotate(100,1000).
% 5,253,001 inferences in 8.51 seconds (617274 Lips)
% 404,001 inferences in 0.99 seconds (408082 Lips)
--------------------------------------
0284283NGNG
簡略化してみた
split_lld([],[],R-R).
split_lld([H|T],[],[H|RT]-RX) :- split_lld(T,[],RT-RX).
split_lld([H|T],[H|LT],R-RX) :- split_lld(T,LT,R-RX).
rotate_using_dl(A,B) :- split_lld(A,L,B-L).
0285283NGNG
う。。284じゃ意味ないじゃん。。なかったことに
0286283NGNG
append_d(L-R,R-RX,L-RX).
つーかこんなの↑使わないか。
rotate_d(A-AX,B-BX) :- split_d(A-AX,L-BX,B-L).
さらにややこしく
0287デフォルトの名無しさんNGNG
prologの日本語の優しい解説サイトありませんか?
0288デフォルトの名無しさんNGNG
http://bach.scitec.kobe-u.ac.jp/prolog/
ここはやさしくないのかな
0289278NGNG
>>283
お疲れ様でした。

rotate_dに与えるAが[回転させたいリスト|Ax]になってて、
rotateの仕事量の一部を外に出して前処理しているように
見えるのがちょっと気になったんで、

rotate_d2(A, B) :- append(A, AX, As), split_d(A-AX,L-[],B-L).

こんなの追加して試行してみたんだけど、やっぱそれでも早いんですね。

?- test_rotate(100,500).
% 2,626,501 inferences in 3.79 seconds (693008 Lips)
% 151,501 inferences in 0.29 seconds (522417 Lips) <== >>286の修正版
% 202,501 inferences in 0.36 seconds (562503 Lips) <== rotate_d2

inferencesの増加が約5万なんで辻褄は合うから、てことはやはり元の
rotateの効率がよくなかったってことか。

それにしても難解…
幾何の補助線みたいに考えればいいのかな。
0290278NGNG
たびたびスマン。・・・何やってんだ俺・・・
rotate_d2(A, B) :- append(A, AX, As), split_d(As-AX,L-[],B-L).
0291デフォルトの名無しさんNGNG
>>288
日本語訳があるのはいいね(笑)
あと主要なbuiltin predicateが書いてあったらもっと良
0292デフォルトの名無しさんNGNG
日本語の入門だったらこんなのはどう?
http://web.sfc.keio.ac.jp/~tozaki/LP/02/handout/theory/lp.html

難しめの事もわりと平易に書いてる気がするんだけど。
0293デフォルトの名無しさんNGNG
[a,b,c] なんてリストから
[a,b,c|T]-T なんて差分リストを作りたいのだけど
どしたらいいんでしょ??
逆なら簡単なんだけど・・・
0294293NGNG
自力解決しますた・・・逝って来ます
0295デフォルトの名無しさんNGNG
>>293
Tの頭にc,b,aと足し込んで行くしか思い浮かばないんですが、
O(1)でやりたいってことですよね。きっと。

できるとしたらその解でも、できないならその証明でも
どっちでも面白そうなんで、識者の方、ご教示おながいします。
0296295NGNG
げっ。
どう解決したんですか?>294
まさかappendとか・・・
0297293NGNG
>>296
appendデス(笑)
とは言え、私の使ってる奴は
appendが組み込みで、リストの分解
とかには使えないんで、
myappend([],L,[]).
myappend([X|L1],L2,[X|L3]):-myappend(L1,L2,L3).
list_dlist(L,H-T):-myappend(L,T,H).
です。
効率は悪いけど、殆どの処理を差分リストを用いて、
必要な部分だけ上のを使うってのでいいかなーって
思ってるのですが・・・
0298デフォルトの名無しさんNGNG
Mercuryの悪口とか、ここに書いていいの?
0299デフォルトの名無しさんNGNG
保守
0300300NGNG
>>299
なんかネタだせ。
0301デフォルトの名無しさんNGNG
大学の授業でPrologがあるんだけど、意味不明、、、
0302デフォルトの名無しさんNGNG
常識かもしれないけど、SonyのAIBOの処理系はPrologで記述されてますよ。

知ってた?
0303デフォルトの名無しさんNGNG
Prologもマンセー
0304デフォルトの名無しさんNGNG
>>302
知らんかった。<LISPとかだと思った。
0305デフォルトの名無しさんNGNG
知らなかった香具師がおれの他にもいた。よかった。
0306デフォルトの名無しさんNGNG
>>302
知らんかった。<Cとかだと思った。
0307デフォルトの名無しさんNGNG
>>302
しらんかった。<中に本物の犬が入ってると思ってた。
0308デフォルトの名無しさんNGNG
知らんかった。<中にバイト君が入ってると思った。
0309デフォルトの名無しさんNGNG
座布団全部持って逝け
0310デフォルトの名無しさんNGNG
ソリャネーヨ
0311デフォルトの名無しさんNGNG
Prologで文字列のマッチングをするのはどういう方法がいいんでげしょ?
文字列もリスト構造になってるんで、有名なKMPとかを使ってもあんまり効率
は改善できそうにないし・・・

0312デフォルトの名無しさんNGNG
>>311
Cでかく
0313デフォルトの名無しさんNGNG
AIBO蹴ったら「イテ」って低い声がしたけどな。
0314デフォルトの名無しさんNGNG
>文字列もリスト構造
そうなの?
0315デフォルトの名無しさんNGNG
Prologコンパイラについて全部教えて
0316デフォルトの名無しさんNGNG
バカだね
0317デフォルトの名無しさんNGNG
>>315
http://www.t.ring.gr.jp/pub/GNU/gprolog/gprolog-1.2.13.tar.gz
その情報ならここにあるよ。変なURLかも知れないけれど、確実。
0318デフォルトの名無しさんNGNG
Prologマンセー
0319デフォルトの名無しさんNGNG
gprologは、prologソースをprologを使ってwamにしてるんですか?
prologの研究をしてる振りなのでprologが読めなかったり(苦笑
0320318NGNG
Prologやろうと思うんだどVC++が一段落しねえな。
0321デフォルトの名無しさんNGNG
激しくなつかすぃ「Prologの冒険」
http://www.amzi.com/AdventureInProlog/
0322デフォルトの名無しさんNGNG
リストカット
0323デフォルトの名無しさんNGNG
お前ら今週prologの勉強を始めた俺が初めて自力で
書いたプログラムを添削して下さいませんか?

/* 犬と、犬の主人と、
ヒンズー教の男と、牛が2頭、
イスラム教の男と、豚が2匹。
ボート(定員2)で河を渡ります。
最低一人は人間が乗らなければなりません。
主人がいないと、犬は見境無く噛み殺します。
イスラム教の男がいないと、ヒンズー教の男は豚を食べます。
ヒンズー教の男がいないと、イスラム教の男は牛を食べます。
河を渡る手順はどのようになるでしょうか? */

human( man ).
human( hindu_man ).
human( islamic_man ).

animal( dog ).
animal( cow ).
animal( pig ).

move_boat( Ca, NewCa, Cb, NewCb ) :-
select( boat, Ca, NewCa ),
append( [ boat ], Cb, TempNewCb ),
msort( TempNewCb, NewCb ).
0324デフォルトの名無しさんNGNG
move_human( Ca, NewCa, Cb, NewCb ) :-
select( Human, Ca, NewCa ),
human( Human ),
append( [ Human ], Cb, TempNewCb ),
msort( TempNewCb, NewCb ).

move_animal( Ca, NewCa, Cb, NewCb ) :-
select( Animal, Ca, NewCa ),
animal( Animal ),
append( [ Animal ], Cb, TempNewCb ),
msort( TempNewCb, NewCb ).

move_other( Ca, Ca, Cb, Cb ).

move_other( Ca, NewCa, Cb, NewCb ) :-
move_human( Ca, NewCa, Cb, NewCb ).

move_other( Ca, NewCa, Cb, NewCb ) :-
move_animal( Ca, NewCa, Cb, NewCb ).
0325デフォルトの名無しさんNGNG
fail_by_dog( C ) :-
member( dog, C ),
not( member( man, C ) ),
length( C, X ),
(member( boat, C ) -> 2 < X ; 1 < X).

fail_by_hindu_man( C ) :-
member( hindu_man, C ),
not( member( islamic_man, C ) ),
member( pig, C ).

fail_by_islamic_man( C ) :-
member( islamic_man, C ),
not( member( hindu_man, C ) ),
member( cow, C ).

print_answer( [], [] ) :- !.

print_answer( [CR | CRH], [CL | CLH] ) :-
print_answer( CRH, CLH ), write( CL ), write( CR ), nl.

solve( Sa, [ Ca | CaH ], _Sb, [ Cb | CbH ] ) :-
Sa == rightSide,
Ca == [], !, print_answer( [Ca | CaH], [Cb | CbH] ), nl.
0326デフォルトの名無しさんNGNG
solve( _Sa, [ Ca | CaH ], Sb, [ Cb | CbH ] ) :-
Sb == rightSide,
Cb == [], !, print_answer( [Cb | CbH], [Ca | CaH] ), nl.

solve( Sa, [ Ca | CaH ], Sb, [ Cb | CbH ] ) :-
move_boat( Ca, Ca2, Cb, Cb2 ),
move_human( Ca2, Ca3, Cb2, Cb3 ),
move_other( Ca3, NewCa, Cb3, NewCb ),
not( fail_by_dog( NewCa ) ),
not( fail_by_dog( NewCb ) ),
not( fail_by_hindu_man( NewCa ) ),
not( fail_by_hindu_man( NewCb ) ),
not( fail_by_islamic_man( NewCa ) ),
not( fail_by_islamic_man( NewCb ) ),
not( member( NewCa, CaH ) ),
not( member( NewCb, CbH ) ),
solve( Sb, [ NewCb, Cb | CbH ], Sa, [ NewCa, Ca | CaH ] ).

river_problem :-
msort( [ boat, man, dog, hindu_man, cow, cow, islamic_man, pig, pig ], Init ),
solve( rightSide, [ Init ], leftSide, [ [] ] ).
いじょ。
0327デフォルトの名無しさんNGNG
323> 初めて自力で書いたプログラム
レベル高すぎ。俺は
mortal(ore).
mortal(omae).
とかだったぞ。
?-mortal(X)
とかやって、動いた、感動した、単位取れた、終わり、だったな。
0328デフォルトの名無しさんNGNG
cかc++かjavaで書かれたprolog->wamコンパイラ募集中♪
0329318NGNG
>>323
おお、激しく面白そうだ。
さすがProlog
0330デフォルトの名無しさんNGNG
>>323
だれ(どれ)が、(安全に?)川を渡ればいいの?
ふれーむもんだいかな?
0331デフォルトの名無しさんNGNG
>>327

mortal っすか。
■ このスレッドは過去ログ倉庫に格納されています