PrologでまったりPart 2

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
2デフォルトの名無しさん:04/12/10 16:44:50
2
3デフォルトの名無しさん:04/12/10 19:37:52
こんにちは。
SWI-Prolog version 5.2.13 for i386-freebsd5.0を使ってます。

foreign_t
pl_d (term_t t)
{

PL_unify_atom_chars (t, "hoge");

PL_succeed;
}

xx :-
thread_create(d(X), Id,[]),
thread_join(Id, Exit),
print(X).

?- dx.
_G186

Yes

となります。dでXをユニファイしてprintでXの値を表示したいの
ですが、方法がありますか?
4デフォルトの名無しさん:04/12/10 19:40:59
         ヘ  o ,    ── /   __,   /  _,   /_/_/       __,   /
          /  \ ´   ── /        /   ─'  /    _       / 
         _/    \   __ /   ___/   ___/     /   ___/
                                     ̄ ̄ ̄
                    _ , ― 、
                  ,−'  `      ̄ヽ_
                 ,'            ヽ
                (   `ー'ー'ヽ`ー'ー'ヽ  )        
               (  ノ ''''''   '''''':::::::ヽ  )
               ( . )(●),   、(●)、.:( ) +
               ( )   ,,ノ(、_, )ヽ、,, .::::( )    <ヨン様が華麗に4get!
               . ヽ )   `-=ニ=- ' .:::::::|ノ  +
                  \  `ニニ´  .:::::/      +
               ,,.....イ.ヽヽ、ニ__ ーーノ゙-、.
               :   |  '; \_____ ノ.| ヽ i












5デフォルトの名無しさん:04/12/10 19:41:16
?- dx. -> ?- xx.
でした。
6デフォルトの名無しさん:04/12/10 23:32:43
はずかしくないんですか?
7デフォルトの名無しさん:04/12/10 23:33:50
なにがですか
8デフォルトの名無しさん:04/12/11 05:29:02
>>3
なんでthreadを使っているのかわからんが、thread_joinとprintの順序を入れ替えてみたら?
9デフォルトの名無しさん:04/12/13 16:37:34
SWI-Prologで変数に漢字を使用する方法はあるのですか。
_漢字コード = 'EUC'. のように。
10デフォルトの名無しさん:04/12/14 02:08:26
>>8
thread_createに渡した述語がunifyしたら反映されるか知りたかっただけです。
Prologエンジンが起こされて、独自のスタックを持つからダメなんですね。
11デフォルトの名無しさん:04/12/15 17:35:25
9 に質問を書いたものです。
SWI-Prologのソースを見るとpl-read.c の中にcheckASCII()と
いう関数があります。これを常に真になるようにして、
コンパイルするだけでよいのでしょうか。
12デフォルトの名無しさん:04/12/15 17:40:37
そう思ったらやってみろよ。
13デフォルトの名無しさん:04/12/15 18:11:40
やってみたところ、インタプリタのトップレベルではうまくいきましたが、
肝心の ?- read(X)で '社員'(_氏名). や 
?- assertz(('基本給'(_年齢,_給与) :- _年齢 > 62, '定年後給与'(_年齢,_給与))).

はうまく行かないようです。pl-read.cを直したのでread(X)の方は
うまくいくかと思ったのですが・・・。

14デフォルトの名無しさん:04/12/15 18:56:05
たびたびすみません。実行ファイルを間違えていました。
上の二つとも上手くいきました。
15デフォルトの名無しさん:04/12/25 09:12:09
> 13-14 自己(訂正)レス。最終的に、
書き換えたのはpl-type.c の _PL_char_types[]という文字テーブルと
initCharTypes() というそのテーブルの初期化関数だけです。

16デフォルトの名無しさん:04/12/25 09:23:49
>15 pl-ctype.c の間違いでした。
17デフォルトの名無しさん:04/12/28 15:27:26
独学でPrologを勉強している者です。
練習問題に解答が載っていないので困っています。

Convert the following information into a Prolog program:

Everyone born in Australia is an Australian citizen.
オーストラリアに生まれた者はみなオーストラリアの国民だ
Children of Australian citizens are Australian citizens.
オーストラリアの国民の子供はオーストラリアの国民だ
Peter is John's father and was born in New Zealand.
ピーターはジョンのお父さんで、ニュージーランドで生まれた
Mary is John's mother and was born in Australia.
メアリーはジョンのお母さんで、オーストラリアで生まれた

他の例題見ながら自分で考えてみたんですが

citizen(X) :- born(X, Y), australia(Y).
citizen(X) :- child(born(X, Y), australia(Y)).
new_zealand(father(peter, john)).
australia(mother(mary, john)).

JohnがMaryやPeterのchildであると示す方法が分かりません。
というか上ので大方合っていますか?
全然分からないので手助けお願いします。m(__)m
18デフォルトの名無しさん:04/12/28 16:56:25
/* 最終行から */
:- op(700,xfy,は).
:- op(700,xfy,の).
:- op(700,xfy,で).
メアリー は ジョン の お母さん で オーストラリア で 生まれた.

/* 上は冗談 第一行目は */
citizen(X,australia) :- born(X,australia). /* でしょう */
19デフォルトの名無しさん:04/12/28 17:51:50
ありがとうございます。(上の冗談がちょっと分からないですが(^^ゞ)

そのヒントを基に考えてみたのですが・・・

citizen(X,australia) :- born(X,australia).
citizen(X,australia) :- child_of(Y,citizen(X,australia)).
child_of(john,peter).
child_of(john,mary).
born(peter, new_zealand)).
born(mary, australia)).

第二行目の左辺と右辺で同じatomic formula(=citizen(X,australia))が出てきていますので
無限ループみたいになってしまうのでしょうか。
以下のような警告が出ます:
% Scanning references for 1 possibly undefined predicates
Warning: The predicates below are not defined. If these are defined
Warning: at runtime using assert/1, use :- dynamic Name/Arity.
Warning:
Warning: citizen/2, which is referenced by
Warning: 1-st clause of child_of/2
Warning: 1-st clause of born/2

どうしたらよいのでしょう?
20デフォルトの名無しさん:04/12/28 17:55:54
citizenってのは述語だから値を返すとするなら真理値を返すんだろ。
真理値の子供Yはオーストラリア国民であるってのは変だろ?
21デフォルトの名無しさん:04/12/28 18:10:51
ということは第二行目は

citizen(X,australia) :- child_of(Y,X).

でしょうか?一つ警告が消えました。

% Scanning references for 1 possibly undefined predicates
Warning: The predicates below are not defined. If these are defined
Warning: at runtime using assert/1, use :- dynamic Name/Arity.
Warning:
Warning: born/2, which is referenced by
Warning: 1-st clause of citizen/2

もしくはこれはどうでしょう?

citizen(X, australia) :- child_of(Y, Z), citizen(Z, australia).

・・・上とまったく同じ警告が出ます・・・なぜでしょう?
22デフォルトの名無しさん:04/12/28 18:22:56
あ゛ーーっ!!
すみません、さっき第五行目と第六行目に一つずつ括弧が多かったです。

citizen(X, australia) :- born(X, australia).
citizen(X, australia) :- child_of(Y, X), citizen(X, australia).
child_of(john, peter).
child_of(john, mary).
born(peter, new_zealand).
born(mary, australia).

で今は正常に動いているように見えるんですが・・・
2 ?- citizen(john, australia).

No ←!?
3 ?- citizen(mary, australia).

Yes
4 ?- citizen(peter, australia).
ERROR: Out of local stack
・・・えっ、JohnはCitizenですよね?お父さんは違うでしょうけど。
どうでしょうか・・・
23デフォルトの名無しさん:04/12/28 18:23:06
警告読め。
24デフォルトの名無しさん:04/12/28 18:34:54
それがSingleton意外の警告はすべて消えてしまいました。

% Waiting for editor ...
% Running make to reload modified files
Warning: (c:/documents and settings/john petrucci/my documents/prolog/australian.pl:2):
Singleton variables: [Y]
% c:/documents and settings/xxxxxxx/my documents/prolog/australian.pl compiled 0.00 sec, 0 bytes

問い合わせるとこんな感じです:

21 ?- citizen(john,australia).
No
22 ?- citizen(mary,australia).
Yes
23 ?- citizen(peter,australia).
ERROR: Out of local stack
24 ?- born(peter,australia).
No
25 ?- born(peter,new_zealand).
Yes
26 ?- born(mary,australia).
Yes

PeterがCitizenかと訊いたら何故Noと答えずにErrorが出るんでしょうね・・・
25デフォルトの名無しさん:04/12/28 18:38:55
釣りか? 当たり前だろ。
> citizen(X, australia) :- child_of(Y, X), citizen(X, australia).
26デフォルトの名無しさん:04/12/28 18:44:32
http://game10.2ch.net/test/read.cgi/game/1104208080/l100
このスレ荒らしてあげて下さい。
ウイルス貼りまくっていいですよ。
歓迎します。
27デフォルトの名無しさん:04/12/28 18:45:13
あ゛ーーーーっ!
分かりました。
そりゃそうですよね。すみません。Yでした。釣りじゃないです。

citizen(X, australia) :- born(X, australia).
citizen(Y, australia) :- child_of(Y, X), citizen(X, australia).
child_of(john, peter).
child_of(john, mary).
born(peter, new_zealand).
born(mary, australia).

33 ?- citizen(john,australia).

Yes
34 ?- citizen(mary,australia).

Yes
35 ?- citizen(peter,australia).

No

完成です! ありがとうございました!!!
28デフォルトの名無しさん:04/12/28 18:47:43
おめ。
29デフォルトの名無しさん:04/12/29 21:14:13
John likes all kinds of food.
ジョンは食べ物なら何でも好き。
Apples are food. Oysters are food.
林檎は食べ物。牡蠣も食べ物。
Anything anyone eats and still alive is food.
食べれるもので生きているものは何でも食べ物。
Tom eats snakes and still alive.
トムは蛇を食べるし、蛇は生きている。
Sue eats everything Tom eats.
スーはトムが食べるものは何でも食べる。

likes(john,X) :- food(X).
food(apples).
food(oysters).
food(X) :- eats(Y,X), alive(X).
eats(tom,snakes).
alive(snakes).
eats(sue,X) :- eats(tom,X).

他は合っていると思うんですが
最後のeats(sue,X) :- eats(tom,X).だけうまくいっていません。続く。
30デフォルトの名無しさん:04/12/29 21:15:07
問い合わせた結果:

19 ?- likes(john,snakes).
Yes
20 ?- eats(sue,snakes).
No ←!?
21 ?- eats(tom,snakes).
Yes
22 ?- food(X).
X = apples ;
X = oysters ;
X = snakes ;
No

トムが蛇を食べるんだからスーも食べますよね?
なぜスーは食べないんでせう?
31デフォルトの名無しさん:04/12/29 22:40:43
昨日の続きかな?

>>29
> Anything anyone eats and still alive is food.
> 食べれるもので生きているものは何でも食べ物。

違う。それを食っても生きていられりゃそれは食い物だ。
32デフォルトの名無しさん:04/12/30 00:55:35
>30 Noになるとは考えられない。
最後の節 eats(sue,X) :- eats(tom,X). は
本当にassertされているだろうか。
33デフォルトの名無しさん:04/12/30 04:36:55
>>30
SWI-Prologでやったら、ちゃんとスーが蛇をたべたよ。
関係ないかもしれないけど、eatsの定義が分離しているから、くっつけてみたら?
34デフォルトの名無しさん:04/12/30 04:44:55
Prologやってる人ってどんなプログラム書いてる
んですか?やっぱパズルの解法プログラムとか
そういう用途ですか?
35デフォルトの名無しさん:04/12/30 05:23:00
>>34
うん、ズバリその通り。
コードを一般の手続き型言語よりもスマートに記述できたときは、無茶苦茶感動するんだな、これが。
3630:04/12/30 06:16:01
>>31
はい、昨日の続きです。
英語の間違いまで指摘してくださってありがとうございます。
その指摘通りに直してみました。

likes(john,X) :- food(X).
food(apples).
food(oysters).
food(X) :- eats(Y,X), alive(Y).
eats(tom,snakes).
alive(tom).
eats(sue,X) :- eats(tom,X).

すると、スーも蛇食べました。(~o~)

7 ?- food(X).
X = apples ;
X = oysters ;
X = snakes ;
No
8 ?- eats(sue,X).
X = snakes ;
No
9 ?- eats(sue,snakes).
Yes
10 ?- eats(tom,snakes).
Yes
3730:04/12/30 06:16:45
>>32
ありがとうございます。
あれ、もう一度、元に戻してみたらスーは蛇を食べました。
読み込めてなかったんでせうか・・・。

>>33
ありがとうございます。
私のもSWI-Prologです。
eatsの定義をひっつけるというのはどうやるのでしょうか?
下のようにしたら蛇を食べ物として認識しなくなりました。

likes(john,X) :- food(X).
food(apples).
food(oysters).
food(X) :- eats(Y,X), alive(Y).
eats(tom,snakes), alive(tom). ←ひっつけました。
eats(sue,X) :- eats(tom,X).

4 ?- food(X).
X = apples ;
X = oysters ;
No
38デフォルトの名無しさん:04/12/30 07:49:00
>34 私の会社では、16年間事務処理(販売管理、給与、財務)は
全てPrologで書かれたプログラムによって運用されています。
現在使っているのコードの過半は16年前に書かれたものです。
インタプリタをTelnetで使用してきましたが、7年前からWeb経由でも
使用しています。ちょっとだけトップレベルのlogを見せましょう。
/* 2004/12/29 9:55:16 */ ?- 12/24+60160+1392870.
/* 2004/12/29 9:55:22 */ ?- 12/24+60293+37800.
/* 2004/12/29 9:55:37 */ ?- 60400++12/27+952+['10000L']+321000.
/* 2004/12/29 10:16:46 */ ?- 2 :: 回収表発行(本部,'20041220').
/* 2004/12/29 10:18:12 */ ?- 2 :: 回収表発行(東京営業所,'20041220').
/* 2004/12/29 10:22:42 */ ?- 12/29+17392+328230.
エッ、コレガ Prolog? っていう感じですね。
39デフォルトの名無しさん:04/12/30 10:06:07
補足説明。例えば、 ?- 12/24+60160+1392870. が呼び出す述語の定義節は
A / B + C + D :- insert into 売上 values (A,B,C,D).

実際にはデータベースの列数はもっと多く、ここまで単純ではありませんが、
このような入力パターンが売上伝票の種類分だけ定義されていると思って
ください。簡単でしょう。
"/" や "+" のようなオペレータの位置によってインタプリタがパターンを
判断しています。
>18 で冗談としたのものは、このようなプログラミングの可能性を仄かに
見せたかったのです。
4030:04/12/30 14:41:17
えーっ、事務処理用のプログラムをPrologで、ですか。
なぜCOBOLやCではなかったのか気になります。
それと>>18の冗談がようやく分かりました。
は、の、で、は文節を分けるための区切り文字だったんですね。
(私も前々学期に簡単なインタプリタをCで作りましたので少し分かります。)
私の夢はPrologでエキスパート・システムと自然言語処理をすることです。
この本では第九章と第十章に載っています。
でも私は今第一章を読み終わったところです。これからまた読みまする・・・。
41デフォルトの名無しさん:04/12/30 15:32:38
>40 事務処理とは企業の活動を記録することです。未来を語ることも
含みます。このような対象のプログラミングには記号処理言語が最も
ふさわしいのではないかと考えました。
記号処理言語の中でも何故Prologを採用したかですが、我々は最終的に
自然言語でのプログラミングを目指しているという仮説のもとに、
その時点での、すなわち約20年ほど前ですが、次善のものを論理式に
求めました。このような観点からプログラム言語を選択すると
当時の流行でもあり、Prolog以外に考えられなかったのです。



42デフォルトの名無しさん:04/12/30 15:53:55
>37 eats(tom,snakes),alive. これはホーン節ではありません。
syntax errorになっている筈です。 >33 で云われているくっつけるとは
eats(tom,snakes).
eats(john,X) :- eats(tom,X). のように間に他の定義節を入れないことでしょう。

ただ私がSWI-prologで確かめたところ、これが原因ではないようです。

4330:05/01/01 16:54:14
あめましておけでとうございます。(^^)
今年もよろしく。

>>41
今までの記録から未来の傾向を予測するということですか。
そんなことを20年くらい前に考えていたんですね。
そうそう、このPrologの本にも1981年の
日本でのFifth Generation Computer Project (or Systems)について少し書かれてます。
これを契機にPrologが世界に知れ渡ったんですよね。
日本が世界に与える影響って大きいんだなぁ、と思いました。誇りに思います。

>>42
はい、私の方でもそのようにくっつけてみましたがうまくいきませんでした。
でも、不器用ですが>>36でなんとか動いたので一応よしとします。
ありがとうございました!
44デフォルトの名無しさん:05/01/05 12:40:02
またまた、お世話になります。
The Pizza-House chalkboard that lists various types of pizza with their ingredients and prices
was wiped out by the rain. You are asked to rewrite the board using the following information.
There are five types of pizza with completely different toppings and prices. Each type of pizza has two toppings:
one from the list of ham, mussels, prawns, salami, and tuna;
the other from the list of avocado, corn, olive, pineaplle, and tomato.
Five prices are $5.00, $6.50, $7.00, $8.50, and $10.00. Other clues are given below.

Hawaiian pizza has mussels and costs over $6.50. Marco-Polo has tomato, but no ham,
which is on the pizza that costs $8.50. Pepperoni costs $7.00 and Super-Supreme has no pineapple.
The price of the pizza that has tuna and corn is not $6.50, and the pizza that costs $5.00 has olive but no salami.
The price of the pizza that has pineapple is not $10.00. The last type of pizza is called Ninja pizza.
You need to determine which pizzas have what toppings and prices.
45デフォルトの名無しさん:05/01/05 12:40:25
ピザ屋の黒板が雨に濡れて一部消えたそうです。
それを書き直すのが今回の仕事です。
トッピングと値段が完全に異なる5種類のピザがあります。
それぞれのピザには2種類のトッピングが載っています。
一種類目は肉類でham, mussels, prawns, salami, tunaです。
もう一種類は野菜類でavocado, corn, olive, pineapple, tomatoです。
値段は$5.00, $6.50, $7.00, $8.50, $10.00です。

Hawaiian pizzaはmusselsが載っており値段は$6.50よりも高いです。
Marco-Polo pizzaはtomatoが載ってますがhamは載っていません、
そして値段は$8.50です。
Pepperoni pizzaの値段は$7.00です。
Super-Supremeにはpineappleは載っていません。
tunaとcornが載っているピザの値段は$6.50ではありません。
$5.00のピザにはoliveが載っていますがsalamiは載っていません。
pineappleが載っているピザの値段は$10.00ではありません。
そしてNinja pizzaと呼ばれるピザもあります。
・・・これでどのピザにどのトッピングが載っていていくらかを見つけなければなりません。
46デフォルトの名無しさん:05/01/05 12:42:27
例題を見ながら組んでみました。ちなみに'\='は"ではない(=is not)"と読みます。
pizza_solution(S) :-
types(S),meats(M),vegetables(V),prices(P),
entry((pepperoni,_,_,7.00),S),
entry((ninja,_,_,_),S),
associate(S,M,V,P),
entry((hawaiian,mussels,_,PH),S),
PH > 6.50,
entry((marco_polo,MM,tomato,8.50),S),
MM \= ham,
entry((super_supreme,_,VS,_),S),
VS \= pineapple,
entry((_,tuna,corn,PS1),S),
PS1 \= 6.50,
entry((_,MS2,olive,5.00),S),
MS2 \= salami,
entry((_,_,pineapple,PS3),S),
PS3 \= 10.00.

associate([],[],[],[]).
associate([(Name,M,V,P)|Rest],Ms,Vs,Ps) :-
select(M,Ms,RMs),
select(V,Vs,RVs),
select(P,Ps,RPs),
associate(Rest,RMs,RVs,RPs).
47デフォルトの名無しさん:05/01/05 12:43:50
エキスパートシステムはもう古い。海外の状況がわかっていないようだな
48デフォルトの名無しさん:05/01/05 12:44:43
select(X,[X|R],R).
select(X,[Y|R],[Y|S]) :- select(X,R,S).

entry(X,[X|R]).
entry(X,[Y|R]) :- entry(X,R).

types([(hawaiian,MH,VH,PH),
(marco_polo,MM,VM,PM),
(pepperoni,MP,VP,PP),
(super_supreme,MS,VS,PS),
(ninja,MN,VN,PN)]).

meats([ham,mussels,prawns,salami,tuna]).
vegetables([avocado,corn,olive,pineapple,tomato]).
prices([5.00,6.50,7.00,8.50,10.00]).

・・・動くのですが、3パターンの答えが返ってきます。
3 ?- pizza_solution(S).
S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, prawns, tomato, 8.5), (pepperoni, tuna, corn, 7.0), (super_supreme, ham, olive, 5.0), (ninja, salami, pineapple, 6.5)] ;
S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, salami, tomato, 8.5), (pepperoni, tuna, corn, 7.0), (super_supreme, ham, olive, 5.0), (ninja, prawns, pineapple, 6.5)] ;
S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, salami, tomato, 8.5), (pepperoni, tuna, corn, 7.0), (super_supreme, prawns, olive, 5.0), (ninja, ham, pineapple, 6.5)] ;
No

二つ目のsuper_supremeは「$5.00のピザにはoliveが載っていますがsalamiは載っていません。」
のルールに反しています。ちゃんと
entry((_,MS2,olive,5.00),S), MS2 \= salami,
って書いてるんですけどね・・・。
何がどう間違っているんでしょうか?教えてください。m(__)m
49デフォルトの名無しさん:05/01/05 14:19:09
>3 ?- pizza_solution(S).
>S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, prawns, tomato, 8.5), (pepperoni, tuna, corn, 7.0), (super_supreme, ham, olive, 5.0), (ninja, salami, pineapple, 6.5)] ;
>S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, salami, tomato, 8.5), (pepperoni, tuna, corn, 7.0), (super_supreme, ham, olive, 5.0), (ninja, prawns, pineapple, 6.5)] ;
>S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, salami, tomato, 8.5), (pepperoni, tuna, corn, 7.0), (super_supreme, prawns, olive, 5.0), (ninja, ham, pineapple, 6.5)] ;
>No
>
>二つ目のsuper_supremeは「$5.00のピザにはoliveが載っていますがsalamiは載っていません。」
>のルールに反しています。ちゃんと
>entry((_,MS2,olive,5.00),S), MS2 \= salami,
>って書いてるんですけどね・・・。
>何がどう間違っているんでしょうか?教えてください。m(__)m
(_, salami, olive, 5.0) の組み合わせの解はどこにも見当たりませんが・・・。
50デフォルトの名無しさん:05/01/05 15:21:33
英文の通りに書いたらちゃんと1通りだけ出てきたよ。
5144:05/01/05 15:28:01
ありがとうございます。
あっ、本当ですね。(汗
すみません、私の脳内でhamとsalamiを同一視してしまっていたようです。
(少し似てますよね・・・全然似てませんか _| ̄|○)

ということで今は他の原因を探しています・・・。
5244:05/01/05 15:48:39
ええーっ、(やっぱり)そうですか。(汗汗
上記の3パターンの中に正解はありますか?

考察すると
まだ肉類が決まっていないのはmarco_polo、super_supreme、ninjaです。
表にするとこうです:

marco_polop s s
super_supremeh h p
ninjas p h

※それぞれp = prawns, s = salami, h = hamです。

ninjaは何も定義がないので、その三種類どれでもいいです。
marco_poloはhamを受け付けません。
同様にsuper_supremeはsalamiを受け付けません。
prawnsが何か定義されてれば分かるんですが・・・。

ちなみにmusselsは定義でしっかりHawaiian,
tunaはcornとセットで$6.50ではない、という皺寄せで決まったものと思われます。

何故でせう?
何か忘れている定義はありますか?
53デフォルトの名無しさん:05/01/05 15:53:53
>>52
> ええーっ、(やっぱり)そうですか。(汗汗
> 上記の3パターンの中に正解はありますか?

ないねー。

> 何故でせう?
> 何か忘れている定義はありますか?

条件の読み違い。
私のソース貼ってもいいよ。
5444:05/01/05 16:00:26
>>53
>ないねー。
ええーっ!(予想していたにもかかわらず、がっくし・・・)

>私のソース貼ってもいいよ。
是非お願いします。<m(__)m>
55デフォルトの名無しさん:05/01/05 16:13:44
んじゃ、貼りますね。

pizza_types([hawaiian,marco_polo,pepperoni,super_supreme,ninja]).
pizza_meats([ham,mussels,prawns,salami,tuna]).
pizza_vegitables([avocado,corn,olive,pineapple,tomato]).
pizza_prices([5.00,6.50,7.00,8.50,10.00]).

select(X,[X|R],R).
select(X,[Y|R],[Y|S]) :- select(X,R,S).
select_in_order(X,[X|R],R).
associate([],[],[],[],[]).
associate([(T,M,V,P)|R],Types,Meats,Vegitables,Prices) :-
select_in_order(T,Types,RTypes),
select(M,Meats,RMeats),
select(V,Vegitables,RVegitables),
select(P,Prices,RPrices),
associate(R,RTypes,RMeats,RVegitables,RPrices).
56デフォルトの名無しさん:05/01/05 16:15:09
つづき。

pizza_combinations(S) :-
member((hawaiian,mussels,_,Price1),S),Price1 > 6.50,
member((marco_polo,Meat2,tomato,_),S),Meat2 \= ham,
member((_,ham,_,8.50),S),
member((pepperoni,_,_,7.00),S),
member((super_supreme,_,Vegitable3,_),S),Vegitable3 \= pineapple,
member((_,tuna,corn,Price4),S),Price4 \= 6.50,
member((_,Meat5,olive,5.00),S),Meat5 \= salami,
member((_,_,pineapple,Price6),S),Price6 \= 10.00.

pizza_solution(S) :-
pizza_types(Types), pizza_meats(Meats), pizza_vegitables(Vegitables),
pizza_prices(Prices),
associate(S,Types,Meats,Vegitables,Prices),
pizza_combinations(S).

先月末にこのスレ見たときはswi-prologの使い方さえ忘れてて
プロンプトの前でしばらく途方に暮れたくらいなんですが
このところ久しぶりに思い出せて楽しいです。
57デフォルトの名無しさん:05/01/05 16:17:46
しまったー、s/vegitable/vegetable/ して下さい。お恥ずかしい。
5844:05/01/05 16:35:58
ありがとうございます。
文を読んですんなりと組めるんですか・・・すごいです。
私は既存の例題の変数などを変えて組んでます、とほほ。

私も最初に組んだときはvegitableとタイプしました。
一応変えておきました。

それはそうと、結果はこうなりました:

S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, salami, tomato, 6.5), (pepperoni, tuna, corn, 7.0), (super_supreme, prawns, olive, 5.0), (ninja, ham, pineapple, 8.5)] ;
No

ピザの種類、肉類、野菜類の順番は私の解の三番目と一緒ですね。
ただ、marco_poloとninjaの値段が逆になっています。
marco_poloは定義では$8.50になっていると思ったんですがどうでしょうか?
5944:05/01/05 16:43:20
ああーっ!
6044:05/01/05 16:47:11
Marco-Polo has tomato, but no ham, which is on the pizza that costs $8.50.



Marco-Polo pizzaにはtomatoが載ってますがhamは載っていません。
そして、hamが載っているピザの値段は$8.50です。

と訳すんですね。なるほど、納得です。
しまった…また英語の問題で躓いてしまいました。
それを踏まえて自分のプログラムも直してみます。
しばらくお待ち下さい。m(__)m
6144:05/01/05 16:57:15
修正すると1通りだけの結果が出ました!

4 ?- pizza_solution(S).
S = [ (hawaiian, mussels, avocado, 10.0), (marco_polo, salami, tomato, 6.5), (pepperoni, tuna, corn, 7.0), (super_supreme, prawns, olive, 5.0), (ninja, ham, pineapple, 8.5)] ;
No

「また」英文が読めてなかったんですね、私・・・。
何年英語勉強してんだ、って話になります・・・反省。
以下が完成品になります。(長いので次レスです)
ご指摘がなかったら一生迷っていたことでしょう、いや本当に。
助かりました。ありがとうございました!!!
6244:05/01/05 16:57:43
pizza_solution(S) :-
types(S),
meats(M),
vegetables(V),
prices(P),
entry((pepperoni,_,_,7.00),S),
entry((ninja,_,_,_),S),
entry((_,ham,_,8.50),S), %←追加
associate(S,M,V,P),
entry((hawaiian,mussels,_,PH),S),
PH > 6.50,
entry((marco_polo,MM,tomato,_),S), %←修正
MM \= ham,
entry((super_supreme,_,VS,_),S),
VS \= pineapple,
entry((_,tuna,corn,PS1),S),
PS1 \= 6.50,
entry((_,MS2,olive,5.00),S),
MS2 \= salami,
entry((_,_,pineapple,PS3),S),
PS3 \= 10.00.
6344:05/01/05 16:58:05
associate([],[],[],[]).
associate([(Name,M,V,P)|Rest],Ms,Vs,Ps) :-
select(M,Ms,RMs),
select(V,Vs,RVs),
select(P,Ps,RPs),
associate(Rest,RMs,RVs,RPs).

select(X,[X|R],R).
select(X,[Y|R],[Y|S]) :- select(X,R,S).

entry(X,[X|R]).
entry(X,[Y|R]) :- entry(X,R).

types([(hawaiian,MH,VH,PH),
(marco_polo,MM,VM,PM),
(pepperoni,MP,VP,PP),
(super_supreme,MS,VS,PS),
(ninja,MN,VN,PN)]).

meats([ham,mussels,prawns,salami,tuna]).
vegetables([avocado,corn,olive,pineapple,tomato]).
prices([5.00,6.50,7.00,8.50,10.00]).
64デフォルトの名無しさん:05/01/05 18:57:10
おめ。
ところで>>55,56の私のプログラムですが、
あらゆる組合せを無条件に生成してから最後にチェックしているので遅いですね。
そこで、組合せのわかっている部分を取り出して始点にすれば探索空間を絞れます。

--- pizza.pl.old Wed Jan 5 18:33:38 2005
+++ pizza.pl Wed Jan 5 18:34:36 2005
@@ -14,6 +14,8 @@
select(P,Prices,RPrices),
associate(R,RTypes,RMeats,RVegetables,RPrices).

+pizza_menu([(hawaiian,mussels,_,_),(marco_polo,_,tomato,_),(pepperoni,_,_,7.00),(super_supreme,_,_,_),(ninja,_,_,_)]).
+
pizza_combinations(S) :-
member((hawaiian,mussels,_,Price1),S),Price1 > 6.50,
member((marco_polo,Meat2,tomato,_),S),Meat2 \= ham,
@@ -27,5 +29,6 @@
pizza_solution(S) :-
pizza_types(Types), pizza_meats(Meats), pizza_vegetables(Vegetables),
pizza_prices(Prices),
+ pizza_menu(S),
associate(S,Types,Meats,Vegetables,Prices),
pizza_combinations(S).

あとはもはや冗長となったtypesの扱いを削ることができ、
そうすれば44さんのプログラムとほぼ同じ形になりますね。ふむ。
65デフォルトの名無しさん:05/01/05 19:28:46
44さんの使っているprologの本の題名はなんていうの?
66デフォルトの名無しさん:05/01/06 04:58:49
>>47
現在の趨勢はどうなっているのでしょうか?
是非ご教授ください。
67Amalog ◆6l0Hq6/z.w :05/01/06 05:20:01
>>44です。あまりに頻出するのでトリップつけます。w

>>64
短くて分かりやすくていいですね。特に変数が読みやすくていいです。
(私のプログラムが如何にやっつけ仕事だったか、というのを思い知らされます(>_<))

>>65
本のタイトルは
Techniques of Prolog Programming
- with Implementation of Logical Negation and Quantified Goals -です。
著者はT. Van Leで1993年にJohn Wiley & Sons. Incから出版されています。
下のURLに詳しく書かれています。

ttp://books.kelkoo.co.uk/b/a/cpc_5101_ps_6184428_gs_16272291.html

改訂版が出てないところを見るとあんまり売れなかったのかも…Top Listにも載ってないし。
でも今のところは誤字脱字もありませんし、例題も多いので気に入ってます。
68デフォルトの名無しさん:05/01/06 12:18:22
前スレを html 化してもらいました.

Prolog でまったり
http://ruku.qp.tc/dat2ch/0501/06/976462999.html
(http://pc5.2ch.net/test/read.cgi/tech/976462999/)
69デフォルトの名無しさん:05/01/07 04:34:58
SWI-Prologには、なぜ利用価値があると思われる組合せを生成する述語がないのだろう?
順列は最近導入されたようだが。

?- combination([a,b,c,d], 2, X). % 4個のものから2個取り出す組合せを全て求める
X = [a, b];
X = [b, c];
...

こういうのあったら、便利だと思うんだよな。パズルを解くときよく使うし。
70デフォルトの名無しさん:05/01/08 06:03:20
repeatを使ってリストの合計値を求めたり、階乗計算をしたりできますか?
71デフォルトの名無しさん:05/01/08 06:57:54
?- ・・ L = [1,2,3], ・・・,repeat, ・・(2) ・・, _終了条件.
のような質問で、(2)の部分で合計値を求めるということですか?
副作用(仮の述語のassert,retractやグローバル変数への破壊代入)を利用しない限り
無理です。バックトラックしてrepeatに戻って来た時には、副作用データ以外は
元の状態に完全に復帰します。ということは(2)で新たに生成されたもの、
すなわち変数に単一化されたものは何も残らない。
72デフォルトの名無しさん:05/01/08 07:42:06
意図していたことは、そのような感じです。

sum([], 0).
sum([X|L], S) :- sum(L, S1), S is X + S1.

上のようなコードをrepeatを使って一行で済ますことができたらなあと思い、質問しました。
大掛かりなことはしたくないので、やはり上のように再帰呼び出しを使うしか無いようですね。

73デフォルトの名無しさん:05/01/08 07:48:11
SWI-prolog 5.2.12で、計算の途中でたくさんassertを行う(数千回)プログラムを実行したとき
処理系が落ちるんですが、同様の経験をしたかたはいらっしゃいますか?
バグなのかなあ。

74デフォルトの名無しさん:05/01/09 09:38:00
>72 結局、事務処理などにPrologを利用するときには、
この述語を最初に定義することになります。組み込みで持つべきですね。

sum/2は第一引数のリストに
一つでも浮動小数点数があれば、Sは浮動小数点数。
全て整数だとSは整数となります。これだと、
   sum(L,S),write_fromatted('%6d\n',[S]), /* write_formatted/2はCのprintf()と同機能と思ってください */
のような部分で、Sが浮動小数点になるとfailするかexceptionが発生するので
   sum(L,S),(integer(S),write_formatted('%6d\n',[S]);float(S),write_formatted('%6.0f\n',[S])),
と一々せねばならず、やっかいです。
私は sum/2の第一定義節は
sum([],0.0). にして、必ず浮動小数点数になるようにして利用しています。

75デフォルトの名無しさん:05/01/09 19:37:45
>69 ちょっと間が抜けてしまいましたが、

combination(_,0,[[]]) :-
  ! .
combination(L,N,[]) :-
  list_length(L,Len),
  Len < N,
  ! .
combination([A|R],N,X) :-
  M is N - 1,
  combination(R,M,Y),
  mapcar(A,Y,Z),
  combination(R,N,X2),
  append(Z,X2,X) .
mapcar(_,[],[]).
mapcar(A,[L|R],[[A|L]|R2])
 :-
  mapcar(A,R,R2).

?- combination([a,b,c,d,e],3,X).

X = [[a,b,c],[a,b,d],[a,b,e],[a,c,d],[a,c,e],[a,d,e],[b,c,d],[b,c,e],[b,d,e],[c,
d,e]].
yes.
?- 
これでよいのですか。
76デフォルトの名無しさん:05/01/09 19:58:55
すみません。>69の仕様を勘違いしてました。
私のは全解探索版でした。member/2で取り出せば良い、とは云えますが。
77デフォルトの名無しさん:05/01/09 20:38:45
>69
combination(L,N,L) :-
  list_length(L,Len),
  Len = N,
  ! .
combination([A|R],N,[A|Y]) :-
  M is N - 1,
  combination(R,M,Y).
combination([_|R],N,X)
 :-
  combination(R,N,X).
でよいのでしょうか。
78デフォルトの名無しさん:05/01/09 21:18:04
ISOのProlog標準化作業が今年から再開されるとのことですが、
>69、72 で示されたような有用な述語類はどういう形で取り込まれて
いけばよいのでしょうか。
79デフォルトの名無しさん:05/01/10 01:58:00
>>77
正しい解が得られるようだけど、リストが長くなると処理時間が異常に長くなるよ。

たとえば、こんな例
?- combination([a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z], 1, X).
8079:05/01/10 02:11:25
ちなみに俺のは、こうなったよ。
下請け用の述語を用意しているので、あんまりきれいでないかも。
改善の余地があるかも。

comb_sub([A|B], A, B).
comb_sub([_|L], A, B) :- comb_sub(L, A, B).

combination(_, 0, []).
combination(L, 1, [A]) :- member(A, L).
combination(L, N, [A|R]) :-
N>1, comb_sub(L, A, B), N1 is N-1,
combination(B, N1, R).
81デフォルトの名無しさん:05/01/10 07:01:20
>80 77は、list_length/2は無くさないといけないか。
8279:05/01/10 07:21:30
>>81
list_lengthを使うこと自体には問題はないと思うよ。
たぶん>>77の問題点は、最後の節で第2引数をそのままの値で
combinationを再帰呼び出ししていることにあるんじゃないのかな?
それで再帰の停止条件Len=Nがなかなか真にならず、
解につながらない余分な枝が残り続けているのだと思う。
83デフォルトの名無しさん:05/01/11 12:34:44
差分リストって使ってます? いまいち効用がわかりません。
84デフォルトの名無しさん:05/01/12 12:42:42
事務屋の私は、ほとんど使いません。
キューには何箇所かで使っている。それだけ。
85Amalog ◆6l0Hq6/z.w :05/01/12 19:36:17
どうかまたお力をお貸してください。m(__)m

Consider the function f defined as follows:
次のような関数を考えよ。

f(x) = x - 10 if x >100,
f(x) = f(f(x+11)) is x =< 100.

f(x+11)までは出来ました。

moreless(X,Y) :- X >100, Y is X - 10.
moreless(X,Y) :- X=<100,
X1 is X + 11,
moreless(X1,Y).

でもf(f(x+11))はどぉしても出来ません。
moreless(moreless(X1,Y),Y)みたいな感じで出来ると思ったのですが
unknown optionとか言って怒られてしまいます。

moreless(X,Y) :- X=<100,
X1 is X + 11,
moreless(X2,Y),
X2 is moreless(X1,Y).
とかやっても駄目です。
関数が入れ子になった例題なんて載ってないんでさっぱり分かりません。
どうか解決法を教えてください。
86Amalog ◆6l0Hq6/z.w :05/01/12 19:37:12
ちなみに流れはこうですよね?
f(100,Y).
100 <= 100,
100 + 11 = 111,

f(111,Y).
111 > 100,
111 - 10 = 101 ←ここまでは出来ました

f(101,Y). ←ここからは出来ません・・・
101 > 100,
101 - 10 = 91,

Y = 91.
87デフォルトの名無しさん:05/01/12 19:54:41
単純に
moreless(X,Y) :- X > 100,Y is X-10,!.
moreless(X,Y) :- X =< 100,
  X2 is X+11,
  moreless(X2,Y2),
  moreless(Y2,Y).
ではダメですか。
88Amalog ◆6l0Hq6/z.w :05/01/12 20:29:49
>>87
出来ました!
ああ、Y2を二つ目の関数の最初の引数に持ってくるんですね。
これで次回から関数が入れ子になった問題でも(多分)解けると思います。
独学だと自分のペースで勉強できるのはいいんですけど、
一度躓くと先に進めないのが難点ですね・・・これでやっと先に進めます。
ありがとうございました!
89鵺鳥 ◆orz.7IBPr6 :05/01/17 17:51:12
最近日本語入力及び出力できるPrologはないですか?
例えば、述語など日本語で定義したり、日本語で返したりなど。
90鵺鳥 ◆orz.7IBPr6 :05/01/17 18:15:12
ageないと返答なさそうなのでageますね。
91デフォルトの名無しさん:05/01/17 18:50:07
>>89
K-Prologならできます。
インタプリタやライブラリが貧弱ですが。
92デフォルトの名無しさん:05/01/17 18:56:39
K-prologは個人ライセンス料が8000円ですが、即使えます。
SWI-Prologはデータとしては、即、利用可能です。関数名(述語名)に
使うには一々シングルクォーツで囲まなくてはならず面倒です。
SWI-PrologでOSがLINUXの場合は一箇所直して、再コンパイルすれば
上記の制限がなくなる上に
_円周率 = 3.14 のように、変数にも漢字が使用できるようになります。
pl-ctypes.c というファイルの文字テーブルを一部書き換えて、
# make
# make install とするだけだと思います。

私が使っているIF/Prologは最も完全なものですが、高価ですし、
最近販売を停止してしまいました。

そのほか、頭文字がA-Zまでprologは全部揃っているそうですが、
半分以上のPrologが使用可能であると聞いたことがあります。
93デフォルトの名無しさん:05/01/17 20:22:44
>92 pl-ctypes.c ではなく pl-ctype.c の間違いでした。
この中で、char _PL_char_types[] = {
とテーブルの文字番号129以上を全部 LC に変えてしまうだけでよいはずです。
94デフォルトの名無しさん:05/01/18 11:36:47
Prologからデータベースをアクセスしている方、どんな方法を
とっていますか。
とりわけ、SWI-Prologを使用している方に聞きたい。
95お願いします:05/01/19 10:45:36
論理式eが与えられた時、eと等価なCNFを求める述語cnf/2を定義せよ。
という問題がわかりません。
誰か教えてくれませんか?
96デフォルトの名無しさん:05/01/19 13:00:54
CNFってなんだったかな。第一引数をeとして、第二引数をCNFとすると、
cnf((P :- Q),(not(Q1);P1)) :- cnf(Q,Q1),cnf(P,P1).
cnf(not(P;Q),(not(P1),not(Q1))) :- cnf(P,P1),cnf(Q,Q1).
cnf(not(P,Q),(not(P1);not(Q1))) :- cnf(P,P1),cnf(Q,Q1).
cnf(P,P).
こういう風に書き連ねればよいのだろうか。
全然見当違いのこと書いてるかもしれない。
97デフォルトの名無しさん:05/01/19 13:05:27
そうか、
cnf(P,P). の上には
cnf((P,Q),(P1,Q1)) :- cnf(P,P1),cnf(Q,Q1).
cnf((P;Q),(P1;Q1)) :- cnf(P,P1),cnf(Q,Q1).
も必要か。
98デフォルトの名無しさん:05/01/19 13:35:37
cnf(not(not(P)),P1) :- cnf(P,P1).
なんてのもありそう。
99デフォルトの名無しさん:05/01/19 17:18:26
ちょっと蛇足
:- op(1000,xfy,∧).
:- op(1100,xfy,∨).
:- op(900,fy,¬).
cnfの定義の前に上のオペレータ定義をして、

cnf(¬((P ∨ Q)),(¬P1 ∧ ¬Q1)) :- cnf(P,P1),cnf(Q,Q1).

というように定義することは可能。頭部の引数がそれぞれ( )で
囲んであるあたりが微妙。

100デフォルトの名無しさん:05/01/20 13:20:47
100をとれそうなので。
Prologのプログラムでよく使う基本的な述語といえば、
fail/0, !/0, is/2 は別にすると、
repeat/0, member/2 , findall/3 , sub_atom/4か5 , concat_atom/2か3 ,
atom_chars/2, atom_codes/2, list_length/2, list_nth/2,
それからもちろん入出力、
そのほかに案外使うのが、これは方言が多いと思うが, atoi/2, itoa/2 の
類。
課題によっては append/3, sort/2 も使うかもしれない。

組み込みにしてほしいと思うのは
sum/2,
ある要素が現われるまでリストの読み飛ばし、リストの要素置換、
行列演算、
区切り文字のリストを与えられて、文字列から語彙のリストを得るもの。
それから・・・
101デフォルトの名無しさん:05/02/01 18:33:09
質問です。
Prologって可変引数は利用できませんよね?
102デフォルトの名無しさん:05/02/01 19:25:03
>>101
できません。

Pred(_,_)とPred(_,_,_)は共存できて、全く別物と扱われます。
Pred(_,_)とPred(_,_,_)の意味の橋渡しをする節を記述する
(通常の言語で言えば、変換のコードを書く)ことはできます。

その一般化として、いくつ引数がくるかは不明なPred(_,_,_,...)を
何かとマッチ(Unify)することができるかについてですが、
それは全然できません。

リストという可変長のデータ構造を利用することは、ごく普通に
行われます。
103102:05/02/01 19:33:30
で、リストというデータ構造に目を向けると、
[X | Y] と [a, b, c, ... (長さ不明な可変長部分)] をunifyすると
X = a
Y = [b ,c, ... (長さ不明な可変長部分)]
なんて結果が得られる(Yのように変数には複雑な構造をそのまま
保持できる)ので、可変長引数と同等なことができるはずです。

つまり、Predを可変長引数にしたければ、リストを引数にとるように
すればよいことになります。
104デフォルトの名無しさん:05/02/01 20:43:22
>>102
ありがとうございました。
可変長はあきらめて、リストで実現することにしました。
105デフォルトの名無しさん:05/02/01 21:57:03
さらに質問なんですが。
Prologの処理系によって、リストの最大の長さって決まるものなんでしょうか?
標準規格で最大何個まではリストで表現できなければならない、とかって
ありますか?
106デフォルトの名無しさん:05/02/02 13:30:56
ISO標準にはリストの最大値等の記述はないようです。

?- Len=10000000,findall(N,for(1,N,Len),_),fail;true.

上のような、質問のLenの値を順に増やしていくと、
私が使っているIF/Prologで、ヒープ領域やグローバルスタックの
初期値や最大値を全てDefaultで実行した場合、
2000万から3000万の間で急に遅くなります。一回のGCに要する時間と
関係があるようです。スタックの大きさの初期値を適切に指定すれば
億単位の要素も可能ではないかと思います。
?- Len=1000000,findall(X,(for(1,N,Len),concat_atom([a,N],X)),_),fail;true.
すなわち整数ではなく、アトムを生成すると、100万回を超えたあたりで、
セグメンテーションエラーとなることが多い。
これもリストの要素数が原因ということではありませんね。


107デフォルトの名無しさん:05/02/05 09:38:22
大学で、Prologを半年習いました。
それで質問なのですが、
面白い言語だと思いましたが、
なぜ、こんなにマイナーなのですか。
108デフォルトの名無しさん:05/02/05 11:18:49
役に立つプログラムを作りにくいからじゃないかな。
109デフォルトの名無しさん:05/02/05 12:39:30
>108 最終的にはそういうことになるでしょう。
・ 言語仕様が大規模なプロジェクト向きでない。
・ グラフィック環境を前提にしたAPIがほとんどない。
・ 処理系に定番ソフトがない。
110デフォルトの名無しさん:05/02/05 14:26:53
>>109
どれも必要ない機能だ。
111109:05/02/05 14:43:13
>110 その通り。世の中で、
役に立つプログラムが作られていないから、
使われないともいえる。
ただ、定番がないのは普及には不利だった。
112デフォルトの名無しさん:05/02/05 17:50:02
Webインターフェースつけてやったらいいものになるんじゃ?
入出力をCGIにしとけば、グラフィックもつかえるだろうし。
113Aransk:05/02/05 18:36:40
どなたか知っておられたら教えて下さい。
Prologは昔日本の官庁主導プロジェクトに
おいてメインの言語として利用されたと
聞いております。が、うまく行かなかった
とも…。
もし原因が当時のハード事情であれば
復活する可能性はないのでしょうか?
オブジェクト指向言語も当初は使いものに
ならないほど遅かったが今は全盛です。
出始めのJavaもそうだったと…。

114デフォルトの名無しさん:05/02/05 19:53:10
115109:05/02/05 20:00:33
うまくいかなかったと思っているのは知らない人だけです。
正確にいうと、最初からPrologが使われたわけではない、ということです。
新世代コンピュータ技術開発機構では最初はオブジェクト指向Prologの
ESPが使われ、Prologマシンが作られました。ここで機械語、OS記述言語と
してのPrologの特性が検証されました。しかし、この機構は数年でその活動の
主力を並列処理に移し、以後はPrologと似てはいるが、あまり接点のない
並列論理型言語KL1、後にKLICという言語上で開発が進められました。
研究メンバーは献身的にPrologの普及、教育にも
尽力しましたが、研究の対象は最初から1-2年でPrologから離れてしまったのです。

したがって現在のPrologに関する問題は、新世代コンピュータ技術開発機構や
当時のコンピュータが遅かったこととは何の関係もありません。
116109:05/02/05 20:24:56
続きです。私なりにPrologがうまく普及しなかった理由をまとめると、
・ >109に示したような汎用言語の道をとる必要はなかったのですが、
世の中が、高水準言語とインターフェイスをとる方向へ進まなかった。
ネットワークとユーザインタフェイスの整備のみ進んだ。
・ 人工知能の研究成果を産業に剽窃、応用しようという所謂AIブームに
よって持ち上げられすぎた。結果としてAIバブルに飲み込まれた。
・ ビル・ゲイツがマイクロソフトの中核言語としようと研究したが、
欠陥を克服できず放棄し、VBを開発したという噂が流れた。
・ IBMシステム38の開発が早すぎた。Prologマシンのアーキテクチャとして
最適なこのマシンの開発は70年代後半で、Prologを採用するには早すぎた。

相当に怪しげな分析ですが、いかがでしょうか。
117デフォルトの名無しさん:05/02/05 20:57:57
118デフォルトの名無しさん:05/02/05 21:02:57
Aransk Web
http://homepage3.nifty.com/Aransk/contents2.html

でまあ、本論に復帰して関数型言語ですが、主として大学や
研究機関を中心としたアカデミックな色彩の濃い言語ですから
比較的ドロドロの部分が少なく、言わばディレッタント的な好みで
やっている人が多いと思われます。(マイクロソフトもF#は商業化
しない、と言明しております。)

Prologなんか第5世代コンピューター時代には政、官、財の間で
かなりドロドロに揉まれましたが、今はすっかり枯れております。

現役のプログラマーに関数言語やPrologが好きだと言っても
全然脅威にはなりません。言語宗教戦争から無縁の存在です。

関数型言語のClarityの功徳であります。
不可称、不可量、不可思議であります。

ではコンピューター言語宗教談義はこの辺りで。
119デフォルトの名無しさん:05/02/06 01:11:19
パーサージェネレーター見たいな位置づけで使われれば、
それなりに面白いと思うけど。
120Amalog ◆6l0Hq6/z.w :05/02/06 05:12:20
あるプログラマーが
「Cなんかで大きな大きなプログラムを書く場合でも、
そのアルゴリズムが本当に動くかどうかはPrologで確認して
動くと分かったら実際にCで組み始める」
とか言ってました。
それが本当ならカコイイ!!!
121Aransk:05/02/06 18:05:17
>>109,119,120
>・ 人工知能の研究成果を産業に剽窃、応用しようという所謂AIブームに
>よって持ち上げられすぎた。結果としてAIバブルに飲み込まれた。
最近思うんですが、関数型言語Lispなんかもグラフ理論を中心ロジック
にしてエクスパートシステムなどのAI分野で活躍しています。
将棋ソフトをLispで組んでるなんて聞いたことがあります。
ところがPrologって過去の栄光から現在を比較すると
「枯れすぎて」いる。
マシーンスペックの向上により復活の可能性は
ないのか?パーサージェネレーター的でもっと
AI指向の分野で活躍の機会はないのか?
PrologでWeb Agentとかの発想は無いものか?
(小泉さんにPrologを勉強してもらい、「色々」
国会答弁を論理的にするとか…)



122デフォルトの名無しさん:05/02/06 21:30:42
>Prologって過去の栄光から現在を比較すると「枯れすぎて」いる。
正直、そう感じますね。
Prologを使ったAI的な応用は数では増え続けているようですが、
GUIがらみのプログラミングの爆発的な展開に比較すると、
枯れている、と感じられても仕方がない。
SonyのAIBOはPrologで書かれているという噂もありますが。
スケジュール管理など「子供だまし」とでも形容したくなるような
容易さで書けてしまう。しかし、スケジュール管理が本当に必要なのは
企業の総務部で事務計算とは縁があっても、AIとはもともと無縁です。
Prologは言語仕様とかではなく、利用目的(分野)とPrologのイメージの
ミスマッチというか、ちぐはぐがあまりに多い。
Prologは中小「企業」にこそ最適な言語でるということをもう少し
知らしめる努力が必要だった。その点は私に相当責任があります。
>マシーンスペックの向上により復活の可能性はないのか?
私のところでは30万件以上のRDBのtuppleを述語として登録して、
オンメモリーで検索しています。IF/Prologは高価ですが、ほとんど
バグもありませんし、スタックがオーバーフローするなどの経験も
ありません。これらの点では10数年前からまったく問題ありません。
Web Agentなどといえるものではありませんが、Webはもちろん、mailから
Prologを制御して、解をメールやFAXに転送するサービスなどもやっています。

全てのデバイスに当然のようにPrologインタプリタが付いている世界を
目指したいですね。情報家電などは最有力分野でしょう。
123デフォルトの名無しさん:05/02/07 00:32:12
処理系は十分にコンパクトなのですか?
組込みだとその辺が問題でしょうから。
124デフォルトの名無しさん:05/02/07 09:09:24
>123 他の言語のことを知らないので。
インタプリタのメインループとパーサ(readとかassertの時使う)は
十分にコンパクトですね。ただ、スタック言語ですから、
それぞれのデバイスに最適なスタックをどう確保すればよいかに
ついては私にはわかりません。
125デフォルトの名無しさん:05/02/07 09:49:59
いまはメモリが安いから、スタック確保についてはあまり心配ないかもしれませんね。
ちょっと研究してみようかな。
126デフォルトの名無しさん:05/02/07 10:26:48
中間バイトコードに落として、実行したりネットワークを流れる
ことになりますか。
情報家電のデバイスにどうかというのは、将来エンドユーザーが
自身でデバイスの制御を自由に変えたいという要求を持ち始めた場合、
デバイスに書き込む言語としてはJAVAとか.NETでは
エンドユーザーに負担がかかりすぎる。
もっともシンプルで高い記述力のある言語としては現時点では
Prologが有力ということになります。
家電メーカーが全てを仕組んで販売するのはやがて限界にきます。
その時のチャンスをつかみたい。そんな意味での記述でした。

127デフォルトの名無しさん:05/02/07 12:23:40
面白いですね。
それに向かって何をしたらいいのかよくわからないですが
そういう方向性ってのを目指してる人はほかにいないのかな。
128Aransk:05/02/07 17:40:01
「枯れすぎている」と表現しましたのは
当時かなりの人々がPrologを学び、使いこなせた
はずですよね?
言わばかなりの言語学習投資を行った。
つまり付加逆の時間とコスト(頭脳集中)を
払った訳です。どこへ消えてしまったのか?
第五世代「時代」は日本がPrologでは世界最先端で
あったと聞くと…不思議ですよね?
129デフォルトの名無しさん:05/02/07 17:51:14
>>128
日本の情報系の研究者ってものすごく厭きっぽい気がするんですよ。
何か作り上げて形にするというよりも、なんとなく流行りモノをみつけて
ちょこちょこっと触ってなんとなくそれっぽいものをつくって、
予算がっぽりとって、それが終わると続きはせずに次に行く。

そんなだから払ったはずの時間とコストはきえてしまうとそんな印象を持ってます。
ひとつには予算システムにも問題があって、新しいものにはたくさん予算をつけるけど
古いものの継続開発や維持の予算はガンガン削ってしまうという形に
お役所側もなっているのではないでしょうか。
130デフォルトの名無しさん:05/02/07 17:56:55
はぁ?
131デフォルトの名無しさん:05/02/07 19:40:56
>>122
> 私のところでは30万件以上のRDBのtuppleを述語として登録して、
> オンメモリーで検索しています。
これのイメージがよくわからないんですけれど、
RDBをrecordを表す述語を並べた(テキスト)ファイルによって実現しているということですか?

実行開始時にファイルから述語DBを読み込み、
実行中はrecordの追加/削除をassert/retractによって行い、
終了時にはすべての述語をファイルに書き出す

という感じなのでしょうか?
132デフォルトの名無しさん:05/02/07 20:36:59
>131 売上テーブルが
[売上]出荷場所,出荷日,伝票番号,顧客番号,商品番号,数量,単価,金額
から構成されていると(実際にはもう少し複雑)、副目標
売上(_出荷場所,_出荷日,_伝票番号,_顧客番号,_商品番号,_数量,_単価,_金額)
で参照されるような述語として登録しています。
バッチ更新時はトランザクションとして一連の要求を成功した時に
save_system/1が実行され現在の全環境が保存されます。
対話モードすなわち、伝票手入力の場合は、入力後assertされた直後に
同様の保存が強制的に起こります。環境が破壊されることを避けるため
assertzやretractをエンドユーザーは直接には使用できないようになっています。
システムは保守作業以外には途絶えることはありませんから、何年でも
この状態が続きます。
基本的には、このようなデータベース述語と他の述語の区別をつけないことを
目標にしていますが、
実際には、10万節を超える述語だけは特別扱いして、データベース述語を
管理するPrologシステムをバックエンドに置いています。
述語の変更等が頻繁に起こるフロントサイドからソケット通信で
負節を送り込む方法で処理しています。

かって、この部分はORACLEで管理され、OCIというC言語インターフェイスを
介してアクセスしていた部分ですが、現在はPostgresSQLに一日一回、
変更された部分のみ書き出しているに過ぎません。このデータベースは
5年以上前の明細データを調べるといったような特殊処理を除き参照等には
使われていません。
133デフォルトの名無しさん:05/02/07 20:47:46
>>132
なるほど。説明ありがとうございます。
大規模なテーブルはRDBMSにprologインタフェースを被せて管理し、
それ以外は普通に述語として扱っているんですね。
joinとか件数が多いと性能がでないのでは、と思いましたが10^4オーダー
なら問題ないのでしょうね。

昔swi-prologを使ってRDBMSもどきの処理をやったことがあるのですが、
大量に述語をassertするとすぐに処理系が落ちて大変でした。
ちゃんとした製品を使わないと駄目ですね。
134デフォルトの名無しさん:05/02/08 10:23:02
SWI-Prologでまだヘビーな使い方をしたことはないので詳しくわかりません。
私が、RDBシステムベースから、オンメモリーPrologベースに切り替えたのは
CPUを1.7GHzから3.0GHzに変更した昨春です。
Prologの速度はCPUのそれもクロック速度と比例しますから、少し前に
ダメだと評価したことが現在では十分に利用可能というケースも
多いようです。環境が変わり次第、もう一度評価されることを
お勧めします。
135Aransk:05/02/08 16:10:36
>>129
大分以前にどっかのメガネ屋さんのシステムを
Prologで開発したらしい。経験の無い店員でも
お客の要望を入れるだけで最適のメガネを
選定できるエクスパート・システムのような
ものだとか?
こんな使い方もあるんですね。
>>132
RDBより直接XMLデータを操作したほうが
Prologには合っているように思われますが?
136デフォルトの名無しさん:05/02/08 17:55:14
>RDBより直接XMLデータを操作したほうが
>Prologには合っているように思われますが?
XMLについてはすこし考えを整理してから書きます。
>121 のWeb agent とは全然違うのですが、
私のところのWebサイト(業務用で非公開)では空いている窓に
?- 周防内侍.
とタイプしてSubmitすると

山桜をしむ心のいくたびかちる木(こ)のもとに行きかへるらむ
夜をかさね待ちかね山の郭公雲ゐのよそに一声ぞきく
さみだれにあらぬ今日さへはれせねば空も悲しきことやしるらん
春の夜の夢ばかりなる手枕にかひなくたたむ名こそをしけれ
恋ひわびてながむる空の浮雲やわが下もえのけぶりなるらん
契りしにあらぬつらさも逢ふことのなきにはえこそ恨みざりけれ
すみわびて我さへ軒の忍草しのぶかたがたしげき宿かな
かくしつつ夕の雲となりもせばあはれかけても誰かしのばむ

のような解が返ってきます。これは高名な和歌サイトである「千人万首」
から周防内侍の和歌だけを抽出してきて表示しています。
もちろん周防内侍だけでなく、九条良経でも永福門院でも源頼朝でも
同様に抽出してきます。「千人万首」はXMLサイトではなくHTMLですが、
このような実験はPrologの可能性あるいは多言語に対しての優位性を探る
上では欠かせないと思っています。

137デフォルトの名無しさん:05/02/08 19:59:01
若干の補足。 本来 ?- 請求書印刷('20050131').
というような利用が予想されるWebサイトに ?- 周防内侍.
という述語として未定義の質問が来る。これにたいして、
もしかすると、周防内侍とは歌人かもしれないとシステムが勝手に
考えて、その分野に質問にいく。探索範囲は今のところ歌人だけです。
何故、和歌か歌人かというと、なにより一単位の長さが短い。しかも、
形態素解析などの課題としやすい。辞書を作ること自体に意味がある。
など、結構奥行きがあります。こんな分野をもう少し広げて、
次は、周防内侍が歌人であることを推論する。Prologの値打ちが最も
現われる部分ですね。このくらいまでくるとWeb agent の資格がでてくる
かも知れません。
138デフォルトの名無しさん:05/02/08 20:23:08
> ?- 周防内侍.

?- 周防内侍(X), print(X), fail.

に処理系が展開してるってこと?
便利かも知れないが、その利点はprologに由来するものではないような。
139デフォルトの名無しさん:05/02/08 20:57:02
はい、CでもC++でもVBでもまったく同じことができる。
問題はPrologだと何か有利なことがあるかないか。
その比較ができればよい。Prologだから、次から次へと
こういう分野が広げられました。こんな短い期間で。
ということを示せればよいのでしょう。

HTMLファイルを解析して、歌人が記述されている部分のタグを確定して、
その中の<A>タグから、未編集の歌を引き出す部分を完全に自動で
やりたい。ですが、今のところかなりヒントというか、補助的な情報(この場合は
千人万首の「癖」)を神様みたいな視点で私が与えないと、正しくとれてこない。
実際にはまだまだです。
140Aransk:05/02/09 15:04:41
オブジェクト指向言語をやり始めの頃は
デザインパターンとかを覚えて
なんでもその思考パターンにはめ込もうと
したり、クラスー>インスタンス関係で
考えたりしますよね?
Prologを始めると物の見方がこう
変化するよ。なんてないんですかね?
英語で話すと論理的にならざる得ない。
少なくとも主語だけは…みたいな。
141デフォルトの名無しさん:05/02/09 17:51:06
フレームのような構造を嫌うようになりますね。できる限り、フラットで
引数の少ない関数を好むようになる。こういうデータ構造に対する嗜好の
変化は、物の見方に影響を与えるかもしれない。私は20年もPrologで
書き続けているから多分随分影響されていると思いますが、一般には
影響をうける前にプログラムが完成してしまいますらどうでしょうか。
142デフォルトの名無しさん:05/02/09 18:10:03
Prologって囲碁に近い。こう打って、こう来たら、次はこう打って、なんて
考えたらダメ。見た途端にこのパターンはこうなるものと図像的に直感される。
その繰り返しで書いていく。したがって、このパターン認識の邪魔になる
「複雑さ」を排除しようという意識が働きます。
常に、一瞥で済ませようというプログラミング態度が生まれます。
論理プログラミングというと思考力が重要と思われがちですが、
速読術的な直感が働かされている気がします。

143Aransk:05/02/10 17:16:22
>>141,142
>論理プログラミングというと思考力が重要と思われがちですが、
>速読術的な直感が働かされている気がします。

さすがにご慧眼。
直感的に言わせて頂ければ、それを活かすことでは
ないでしょうか。つまり手続き言語が既にやっている
分野ではなく(GUIやDBMなど)Prolog独自の分野を
発見すること。
残念ながらワタクシあまりにC++やJavaに嵌りすぎて
おり、半ば母国語と化しております。
関数型言語でも母国語に変換して意味を理解する
始末です。Prologは正直、学習コストが高すぎて
ギブアップしました。APLやJも…。
しかしその学習コストの高さは差異化にも
なり得る。これまで手続き型言語が
生み出しえなかったアイデアこそ
勝負所ではないでしょうか。
プログラマーの思考に与える影響を含めて。
144デフォルトの名無しさん:05/02/11 04:03:04
Prologみたいな言語って何型言語っていうの日本語で
145デフォルトの名無しさん:05/02/11 04:23:25
ロンリー
146デフォルトの名無しさん:05/02/11 14:55:31
論理型言語てデータマイニングとかセマンティックWEVで使われてないか。
あと形式的仕様記述とか。
147Aransk:05/02/11 16:07:21
>>141
>フレームのような構造を嫌うようになりますね。できる限り、フラットで
>引数の少ない関数を好むようになる。
例えば
ttp://www.cs.nps.navy.mil/people/faculty/rowe/book/chap12.html
People must exploit expectations to understand natural languages,
because speakers and writers try to avoid wordiness. So it's not
surprising that frames are very helpful for natural-language
understanding by computers, for the semantics or
meaning-assignment subarea. That is, with a good frame
representation we can efficiently capture the meaning of
some natural-language sentences, so as to answer questions about it.
こんな考え方もあるようですね?

148デフォルトの名無しさん:05/02/12 11:20:09
>146 リンクの張り方をしらないので、すみません。
http://www.ifcomputer.co.jp/inap/inap2001/home_en.html
などありそうです。
149デフォルトの名無しさん:05/02/12 13:31:38
>141,142,143,147
p(X,Y) :- X=[f1(X1),f2(X2),f3(X3)],p1(X1,Y1),p2(X2,Y2),p3(X3,Y3),p4(Y1,Y2,Y3,Y).

p/2が呼び出される述語とするとき、その中で上のX1,X2,X3のように
ストリームが分岐するコードはできれば書きたくない、ということですね。
Prologのプログラムの焦点は徹頭徹尾ストリーム(引数)上の変数の解決なので、
そのストリームはできるだけ単純に赤、青、緑というような
帯になって最後まで繋がっていてほしい。途中から、紫や茶や橙に化けて、
やがて、いつのまにか消えていく、というようなコードは書きたくない。
150Aransk:05/02/12 15:33:00
>>149
>そのストリームはできるだけ単純に赤、青、緑というような
>帯になって最後まで繋がっていてほしい。途中から、紫や茶や橙に化けて、
>やがて、いつのまにか消えていく、というようなコードは書きたくない。
この考え方は関数型言語の純粋性に近いですね。
破壊的手法を出来るだけ使いたくない。
入れポン出しポンのままでいたい。というか…。
ところで
ttp://www.cs.nps.navy.mil/people/faculty/rowe/book/chap12.html
にあるSlotってCommonLispのオブジェクト指向部分に出てくる
Slotとほぼ同じように素人的には思われますが、どうなんですかねぇ?


151デフォルトの名無しさん:05/02/13 21:34:57
>150 前半部分についてのコメントですが、
Prolog ::: ストリームプログラミング ::: スタックプログラミング
の感覚ですね。なんてことはない。スタックの出し入れをしてるだけだと。
152デフォルトの名無しさん:05/02/13 21:56:00
データに依存関係がないとき、単位節で定義し、非決定性の処理を、
依存関係があるとき(集約関係)はリストに構成して、再帰的に処理
します。しかし、
・ストリームのルーツをはっきりさせたい
・プログラムを書き進んでから集約関係を発見することもある
等の理由から、
findall/3で単位節定義を予めリストに構成してしまう(自前のスタックに
詰め直す)ことも多い。
ここら辺はPrologプログラミングの問題点(弱点)だと思います。
153デフォルトの名無しさん:05/02/15 02:09:27
154デフォルトの名無しさん:05/02/19 17:17:32
>>132
単一ユーザーの場合、データベース更新後のシステムセーブでいける
だろうが、複数ユーザーが場合どうなるか。
サーバーがfork()で別の環境を作っている場合、それぞれ作業中の
Prolog同士でデータベースの更新時にメッセージを交換して、情報を
共有しなくてはならない。
Prologデータベースの課題はそこだった筈だが。
155デフォルトの名無しさん:05/02/19 21:04:17
式の簡略化で
3*(5*x^2)や3*(4*x^2+2*x^3+5)を簡単にする場合

s(Y+Z,S) :- s(Y,SY),s(Z,SZ),s1(SY+SZ,S).
s(Y*Z,S) :- s(Y,SY),s(Z,SZ),s1(SY*SZ,S).
s(Y,Y).
s(Y-Z,S) :- s(Y,SY),s(Z,SZ),s1(SY-SZ,S).
s(Y^Z,S) :- s(Y,SY),s(Z,SZ),s1(SY^SZ,S).
s1(0+Z,Z).
s1(Y+0,Y).
s1(1*Z,Z).
s1(Y*1,Y).
s1(Y,Y).
s1(N+M,S) :- integer(N),integer(M),S is N+M.
s1(N-M,S) :- integer(N),integer(M),S is N-M.
s1(N*M,S) :- integer(N),integer(M),S is N*M.
s1(N^M,S) :- integer(N),integer(M),S is N^M.
s1(_Y*0,0).
s1(Y-0,Y).
s1(Y^1,Y).
s1(_Y^0,1).
s1(N*(M*Z),S*Z) :- integer(N),integer(M),S is N*M.
s1(N*(Y+Z),N*S) :- integer(N),S = Y+Z.

だけではうまくいかないんですが後何を加えればいいんですか?
述語s/2は一般的な式の簡略化を行い,述語s1/2は部分式が既に簡略化されている式の簡略化を行います。
最後の2式に問題があると思うのですが。


156デフォルトの名無しさん:05/02/20 14:58:24
例1: 述語の順序
例2: 分配法則
157デフォルトの名無しさん:05/02/20 15:57:15
順序が大事なんですね
順番変えたらいけました
ありがとうございます。
158デフォルトの名無しさん:05/02/20 23:28:11
>>154
>サーバーがfork()で別の環境を作っている場合、それぞれ作業中の
>Prolog同士でデータベースの更新時にメッセージを交換して、情報を
>共有しなくてはならない。
きびしい指摘ですね。実は私のところでは更新を許可されたユーザは
一人、一端末に限定しています。したがって参照するユーザは入り直せば
最新にほぼ近いデータが参照できるでしょう、という考え方です。
しかし、これではシステムとしては制限がありすぎてしかも不完全です。
それで、現在は全く使ってはいませんが、SMTPとPOP3を利用して、更新時に他の
ユーザにmailで同報し、各ユーザはインタプリタのトップ、質問の実行の
冒頭にmailから取り出し、メールの中の質問を優先することによって、
データベース更新の同期をとるという機能をもっています。
fork()された環境がどのメールアカウントからメールを引けばよいか、などの
記述部分が複雑になりますが、TTY端末からの全く独立した環境でも、
fork()され、子タスクとして立ち上がった環境でも共通して利用でき、
少なくとも実験レベルでは成功しています。
159デフォルトの名無しさん:05/02/21 13:12:51
>>158 所謂バッチ更新はどうなりますか。
160デフォルトの名無しさん:05/02/21 14:04:11
>>159 同報による同期をとる場合、システムセーブをするPrologシステムは
一箇所です。WebでPrologサーバーをサービスする場合も同じだと思うのですが、
更新システムは元の親タスクだけです。
端末ごとのマルチユーザーシステムの場合でも、永続システムを決めておいて、
特権的にシステムセーブを行います。
161デフォルトの名無しさん:05/02/22 13:16:10
webは一般的には読出しばかりで、書き込みはすくないだろうから、work aroundはいろいろ
考えられそうだ
162さっぱり分かりません:05/02/22 18:37:49
論理式eが与えられた時、eと等価なCNFを求める述語cnf/2を定義せよ。
という問題がわかりません。
誰か教えてくれませんか?
163デフォルトの名無しさん:05/02/22 21:05:41
implicationの除去、notの整理までは簡単だけど、分配法則を繰り返し適用するところが
難しいね。どうやるのだろう。

:- op(110,yfy,and).
:- op(120,yfy,or).
:- op(130,yfy,imp).
:- op(100,fy,not).

impE(X, X) :- atom(X), !.
impE(not F, not G) :- !, impE(F, G).
impE(F1 and F2, G1 and G2) :- !, impE(F1,G1), impE(F2,G2).
impE(F1 or F2, G1 or G2) :- !, impE(F1,G1), impE(F2,G2).
impE(F1 imp F2, not G1 or G2) :- !, impE(F1,G1), impE(F2,G2).

notE(X, X) :- atom(X), !.
notE(not X, not X) :- atom(X), !.
notE(not (not F), G) :- !, notE(F, G).
notE(not (F1 and F2), G1 or G2) :- !, notE(not F1, G1), notE(not F2, G2).
notE(not (F1 or F2), G1 and G2) :- !, notE(not F1, G1), notE(not F2, G2).
notE(F1 and F2, G1 and G2) :- !, notE(F1, G1), notE(F2, G2).
notE(F1 or F2, G1 or G2) :- !, notE(F1, G1), notE(F2, G2).
164デフォルトの名無しさん:05/02/22 21:07:03
上の変換後

orDist(F1 or (F2 and F3), (F1 or F2) and (F1 or F3)).
orDist((F2 and F3) or F1, (F1 or F2) and (F1 or F3)).

をくりかえし適用すればよいはずだけど…
165デフォルトの名無しさん:05/02/26 00:11:26
combination(_, 0, []) :- !.

combination([X | Tail], N, [X | R]) :-
N1 is N - 1, combination(Tail, N1, R).

combination([X | Tail], N, R) :-
combination(Tail, N, R).
166デフォルトの名無しさん:皇紀2665/04/01(金) 17:57:12
Mailを使ったPrologの非同期遠隔システムについて。

メールボックスは一つでも良い。専用の質問受付メールボックスと
回答受信メールボックスを用意することが望ましい。
極端な場合、一般のメールに混在させることもできる。
どのようなメールボックス構成であっても、SUBJECT に質問、回答であることを
示すラベルを貼る。ラベルには(質問)識別子を含む。
質問であるか回答であるかが判別できれば、メールボックスをサーチして、
質問時につけた識別子によって、回答を入手する。入手直後にサーバから
メッセージを削除する。回答も必要な時にすなわち非同期にサーチする。
質問はDEC10プロローグ形式で ?- _質問項. を本文の冒頭に置く。
?- のopは :- op(1200,fx,(?-)). とする。
回答は、質問項を実行して変数を解決したものを回答本文の冒頭に置く。
回答項の後のメール文は自由である。一般にはwrite/1 等で表示されるべき
副作用がここに書かれるであろう。
ひとつあるいは複数の添付ファイルによって、Upload、Download が可能になるが、
特別な意味づけはしない。例えば、第一添付ファイルはPrologファイルである、
というような約束事を設けない。
添付ファイルはContent-type: の name=" ファイル名 "; でファイル名を受信者に知らせる。
質問者はしばしば副目標 reconsult(_ファイル名), の実行を要求するが
質問実行者はカレントディレクトリにこのファイル名を以ってコピーし、
その後に質問を実行する。
多くの場合、質問者は質問Pを ?- findall(P,P,L). のパッケージとするであろう。
質問実行者の環境には仕様が不完全であってもfindall/3が存在しなくては
ならない。質問 ?- fail には やはり、 ?- fail を返す。したがって
単純にはtrueになってしまうから何らかの対応が必要である。
文字コードは一応、ISO-2022-JP と EUC-JP とする。
長くなるので一応このあたりで。まだ、モジュール規定、転送規定などがある。
167デフォルトの名無しさん:2005/04/08(金) 12:44:46
来週から高3になります。ほかのスレで読んで興味をもちました。
Windowsでソースから入手できるProlog(できればフリー)ってありますか。
168デフォルトの名無しさん:2005/04/08(金) 18:47:04
「prolog windows free」でぐぐると結果の中にフリーな処理系のページがあります。
「prolog windows フリー」だと日本語の情報になります。
またGoogle DirectoryのPrologのエントリには有名な神戸大学のページへの
リンクがあります。
169デフォルトの名無しさん:2005/04/13(水) 15:14:58
お前ら、prologを言語だと思うなよ
これは定理証明支援が目的なんだからCやらPascalやらと同じに見るなよ
170デフォルトの名無しさん:2005/04/17(日) 00:21:05
cygwinにprologのパッケージは入ってる?
171デフォルトの名無しさん:2005/04/18(月) 12:11:11
>>170
入ってるよ。

cygwinってインストールするときにsetupというプログラムを使うよね。
それが走ったら、Interpretersの分類の中を見ると、SWI-Prologがある。
で、それを選択してsetupを続行するとインストールされる。

今俺のところで実行してみるとこんな感じで、ちゃんと入ってる。
cygwin$ pl
Welcome to SWI-Prolog (Multi-threaded, Version 5.2.6)
(後略)

172デフォルトの名無しさん:2005/04/19(火) 12:02:49
cygwinの話が出てきたので、質問。私のノートで起動していると
時々、入力ができなくなり、数秒後にbeep音がしてから復帰する。
これを繰り返す。これは、仕方のないことか、それとも異常か?
173172:2005/04/20(水) 18:59:09
ウイルスでした。
174デフォルトの名無しさん:2005/05/25(水) 00:56:26
>>169
定理証明支援と云えば ML (Meta-Language) っつーのもあるな
175デフォルトの名無しさん:2005/05/31(火) 01:13:35
>>154の指摘する課題についてぼんやり考えていたら
Prologベースの分散協調システムを実装するのに
TupleSpace(Linda)がなんだか相性よさそうな気がした。
ググってみたら結構ヒットする。
もしかして研究ベースでは結構進んでる話なんだろうか。
176デフォルトの名無しさん:2005/06/01(水) 19:32:00
私はこの分野に暗いのですが、
共有メモリーサーバーといったものはないのですか。
177デフォルトの名無しさん:2005/06/01(水) 22:30:28
TupleSpaceの元祖Lindaは製品として売られてるみたい。
ttp://www.hulinks.co.jp/software/linda/index.html

>>176は事務処理をPrologでやってる>>38さんですか?
178デフォルトの名無しさん:2005/06/01(水) 22:53:42
Lindaの分かりやすい説明
ttp://pitecan.com/UnixMagazine/PDF/if0210.pdf
179176:2005/06/01(水) 22:54:29
そうです。
180デフォルトの名無しさん:2005/06/01(水) 23:42:14
TupleSpace+PrologよりLinda+Prologでググったほうがヒット数が全然多かった!

SICStus Prologには既にlindaというライブラリがあるみたい。
ttp://www.sics.se/sicstus/docs/3.7.1/html/sicstus_29.html#SEC203
181デフォルトの名無しさん:2005/06/05(日) 22:59:58
最近「AIプログラミング」という本でPrologを勉強しはじめました。
しょっぱなからつまずいているのですが、述語と演算子って別のものですか?
(すみません。第一巻は未入手です。)

上著の最初の例題が「リストを表す独自の表現を自作してみる」で、
空リストをアトム donothing、頭部と尾部からリストを作るオペレータを
thenとして
:- op(500, xfy, then).
と定義するとあります。
するとリスト [enter, sit, eat] は、
enter then sit then eat then donothing
と書ける、とあります。確かに swi-prologで
?- op(500, xfy, then).

Yes
?- X = 1 then 2 then 3 then donothing.

X = 1 then 2 then 3 then donothing ;

No

となります。(op()を宣言する前だとsyntax errorになります)

オペレータthenはオペレータとしては定義されていますが、
それがどういう計算を行うものかはどこにも定義していません。
にも関わらず処理系はそれを式として受け入れてくれます。

これはどういうことが起こっているんでしょうか。
他のプログラミング言語ではこういうことは起きないので理解に苦しんでいます。
182デフォルトの名無しさん:2005/06/06(月) 07:54:18
述語と演算子は別のものです。
演算子とは、data constructorだと考えれば分かりやすいと思います。
prologでのdata constructor(functor)は普通functor(term, ..., term)という形で使用しますが、
演算子として定義したものはそこで定義した形(term functor term等)で使用する
という違いがあります。
functorは要するにdata構造を表現するためのtagですから、その計算を定義しなくても
使用できます。
183デフォルトの名無しさん:2005/06/06(月) 08:42:19
opとは 1または2引数の関数(述語の場合もある)が
p(p1)あるいはp(p1,p2) で与えられるとき、
プログラマの理解しやすさの便をはかって
p p1 や p1 p さらに p1 p p2 の表記を可能とするものです。
たとえば 3 + 5 は +(3,5)と内部的には
同じものとみなされます。ほとんどのPrologでは
:- op(500,yfx,+).
がprologの初期値として定義されています。
インタプリタのトップでユーザがopを定義するには、
?- op(650,xfx,#). のような質問で可能です。

述語opの引数は
第一引数が 結合度( +と/では結合度がちがいます)
第二引数が 型
第三引数が オペレータ となります。
型は説明が長くなるので後に説明します。
結合度はSwi-prologの場合、
?- current_op(A,B,+).

A = 500
B = yfx
のように実行して確かめることができるので、
:- ?- is = + - * / などを調べて考えてください。
184デフォルトの名無しさん:2005/06/06(月) 09:32:52
>>182,183
ありがとうございます。なんとなくわかってきました。
? X is 1 + 2.
X = 3 ;

No
となるのは、単に op(500, yfx, +). が定義されている
だけではなくて、+(1, 2) がどういう計算をおこなうものか
別に定義があるんですよね?
185デフォルトの名無しさん:2005/06/06(月) 09:55:52
そうです。
2引数の組込述語 is は第二引数を関数とみなして、
それを計算してその結果を第一引数と単一化します。
関数の計算は定義済みということです。
ユーザーが独自の関数を定義したい場合は
:- op(500,yfx,は).
(X は 四捨五入(_関数)) :- <略>.
(X は _関数) :- X is _関数.
のような定義をしておいて、
以後、"is" の代わりに "は" を使用すればよいでしょう。
186デフォルトの名無しさん:2005/06/06(月) 10:14:08
オペレータは必ずしも関数計算と一体のものではありません。
>>38 >>39 のような特異な例もあります。
ここでは、述語定義の頭部でオペレータ定義が利用されて
います。
187181:2005/06/06(月) 22:48:21
"PROLOG Programming for Artificial Intelligence" 3rd edition
ttp://www.amazon.co.jp/exec/obidos/ASIN/0201403757

が届きました!
まだパラパラ見ただけですが、第二版(邦訳)と比べてかなり面白そうです。
ただ読み通すのに何ヶ月かかることやら…。
188デフォルトの名無しさん:2005/06/14(火) 11:57:58
>>181 PrologとAIの第一巻「Prologへの入門」近代科学社が私の手元に
2冊あります。
ご希望でしたら、mailto:[email protected] に申し込んでください。
最初にメールの届いた希望者に無料で贈呈します(ただし中古本です)。
この本はamazonなどで比較的容易に入手できます。
189181:2005/06/14(火) 14:49:20
>>188
ありがとうございます。
残念ながら、先日amazonで古本を購入したばかりのところです。
千円しませんでしたが。

# とても良い本ですので持っていない他の方にお薦めします。
190デフォルトの名無しさん:2005/06/17(金) 04:07:36
命題論理や述語論理などの論理学を学んでいる者なのですが、
Prologは論理学の知識を生かして
他の言語にあまりない面白いものを作れたりするのでしょうか?
191デフォルトの名無しさん:2005/06/17(金) 04:36:37
古い話題としては、RDBやSQLが一般化する前、
Prologによる演繹データベースとゆーのが流行るかな?という期待があった。

しかしPrologは、通常の言語がデフォで持ってる制御構造を書くのに、
思い切り論理を歪ませて手続き的に書く必要があるので、
もう終わっている言語だとする見方もある。

最近の話題としては、帰納推論と学習理論を使って、
学習結果をPrologプログラムとして出力する
Progolというプログラミングシステムがあって、
テキスト・マイニング、遺伝子解析といった
データ分類の分野への応用に期待する向きもある。
192デフォルトの名無しさん:2005/06/17(金) 09:28:42
人のカンの実装などのソフトコンピューティングで、
ニューラルネットワークで近似できる今
Prologの立場がないというのはありますか?
193デフォルトの名無しさん:2005/06/18(土) 16:47:45
>>190 論理学についてはあまり知識のない者です。それでコメントするのも
滑稽なのですが。
コンピュータの世界では、やはり自然言語で制御できないかということが
あって、それは当分難しいとなると、論理式みたいなものでどうだろうと
いうことになる。いっそ、論理式をプログラム言語にしてみようか、という
順序となる。論理の研究者には不満な見解かもしれないけれど素人から
みるとそうなる。そうだとすると、
論理学の知識を生かしてPrologでおもしろい物が書けないかではなく、
論理式だけで、どのくらいのことが表現できるものですか、と質問したく
なります。Prologならその表現できる事と同等のことが書ける。
194デフォルトの名無しさん:2005/06/18(土) 19:55:44
まあ俺ならカリーハワード同型対応に基づいて
命題=型としてのクラス外部仕様(インターフェース)作って、
次にその命題の証明として、インターフェースを満たすプログラムを実装するわけだが。

ただしプログラム合成に関しては、なんかPrologの方が多少進んでるみたいだなw
195デフォルトの名無しさん:2005/06/18(土) 20:33:00
>>194
覚えたての単語を使ってみたいお年頃…まあ俺も人の事はいえんな。
196デフォルトの名無しさん:2005/06/18(土) 22:23:55
おまえ本当に幼いなぁ。
小学生か?
197デフォルトの名無しさん:2005/06/19(日) 01:20:44
コンピュータやるために数学を学ぶ。
コンピュータやると数学の理解力が付く。
数学の教育者は後者だといいなと思う。Prologについていうと、
Prologやってると論理的な「センス」が付く。
遅々たる歩みですが、囲碁が強くなるくらいの速度で。
198194:2005/06/19(日) 03:01:02
カリーハワード同型対応を使って型プログラミングをすると、
問題領域に応じた適切な命題を作る能力と、
命題を漏れなく証明をする能力が磨かれる。
199デフォルトの名無しさん:2005/06/19(日) 07:50:49
まだいたのか。
dependent typeの話をして、PTSの話をして、logical frameworkの話をして、
自分の付け焼刃の知識を披露するのに満足したら、さっさと帰ってね。
200デフォルトの名無しさん:2005/06/19(日) 11:15:27
お?いつの間にか中の人が変わってるやん。
でおまえは何を妄想してんの?意味不明な絡み方すんなよ
201デフォルトの名無しさん:2005/06/19(日) 11:16:12
>>201
 >>200
  >>195
202デフォルトの名無しさん:2005/06/19(日) 14:32:02
おまいらprologの話をしろよ
203デフォルトの名無しさん:2005/06/19(日) 16:13:47
並列prologとかどこへ行ったんだろう…
204デフォルトの名無しさん:2005/06/20(月) 05:14:20
>>192
雇用促進事業団向けの熟練労働者ノウハウ抽出の件であれば、
いわゆる論理プログラミングで対応するのはお門違いだと思う。
205デフォルトの名無しさん:2005/06/22(水) 15:12:25
やってみるのが一番だいね。
百聞は一見にしかず&
虎穴にいらずんば虎児を得ず。
206デフォルトの名無しさん:2005/06/22(水) 16:25:37
>>199
で、何を言いたいの?

・dependent type?・・・何の話?parametric type?誰もそんな話してないよ。

・PTS?・・・・・・・・・・・・何の話?説明please

・logical framework?何の話?Edinburgh Logical Framework?
207デフォルトの名無しさん:2005/06/22(水) 17:42:54
学生がファビョっただけだろ。気にしない気にしない
208デフォルトの名無しさん:2005/06/22(水) 18:01:55
PTL (Propositional Temporal Logic)をベースとした、
形式仕様記述言語PTS (Practical Temporal Specification language)の事。
ICOTアーカイブに論文あり。

時間論理ベースの形式的仕様記述言語PTS
http://www.icot.or.jp/cgi-bin/trread.sh?TMNAME=tm0479
209デフォルトの名無しさん:2005/06/22(水) 18:05:11
C.A.R.HoareのCSPモデルとは違うの?
210デフォルトの名無しさん:2005/06/22(水) 19:08:14
その文脈ならBarendregt(だっけ)のPTSでしょ
というか、突然あほな事を語りだした>>194に対する皮肉だと思われ
211デフォルトの名無しさん:2005/06/22(水) 19:31:09
いや、俺は当時から繋がりのある話だと思ってるけど。

>>192
ついでに、これも張っておこう。
これはどう思う?

 -------------------------------------------------------------------------------
 知識表現システムUranus と多重世界機構 
 http://www.techno-qanda.net/dsweb/Get/Document-7403/443b.pdf

 (前略)
 述語論理の限界
 Prolog は論理型プログラミング言語の代表的なものであるが,知識表現言語としてはい
 くつかの欠点がある。主なものとしては
  ・状態の変化が素直に表せない。
  ・概念の階層構造が素直に表せない。
  ・不確実な知識や,例外が扱えない。
 などがある。これらはそのベースとなる一階述語論理の欠点をそのまま引き継いだものである。
 Uranus ではこの欠点を取り除き,自然な知識表現を許すように多重世界機構を導入した。
 (後略)
 -------------------------------------------------------------------------------

212デフォルトの名無しさん:2005/06/23(木) 01:07:23
頭いいなお前ら
213デフォルトの名無しさん:2005/06/23(木) 08:23:38
prolog使ってる、とか言うと頭良さそうにきこえるよな。
214デフォルトの名無しさん:2005/06/23(木) 10:49:25
個人的には、Prolog でも何でも、頭の悪い人でも何とか仕事がこなせるよう
にするための進化も視野に入れてほしい。

例えば、鶴亀算、旅人算といった算数のトリックは、ちょっと苦労して方程式
を理解したら全く不要になり、頭の悪い人でも問題が解けるようになる。問題
を一段抽象化することで楽になることは、たくさんあるはずなのだ。

技術の進歩に関しては、例えば F1 を速く走らせることももちろん大事だが、
逆の方向で、例えばかつてのスポーツカー並みのパワーの自動車を、運転のヘ
タな人でも楽に扱えるようにするのも、大事なことだと思う。

と言うか、私自身のために、ぜひそのように進化してほしい。実際、プログラ
ミング言語の歴史を、私は主にそのような視点で見ている。アセンブラと
FORTRAN しかない時代だったら、私はとてもプログラマをやっていられません。
215デフォルトの名無しさん:2005/06/27(月) 04:22:55
>>214
もし鶴亀算、旅人算を「代数学」と捉えるならば、
全解探索を行う Prologの論理プログラミングよりも、
例えば>>198に挙げた構成的型論理プログラミングの方が、
代数求解に近いセンスで問題を解く事ができると思う。

幸いな事にこのスレには、
構成的型論理について一家言持っている >>199が居ることだし、
試しにこの分野についていろいろ聞いてみてはいかがか(笑

>>214が提起する大きな課題「ソフトウェア開発の容易化」
「人間の知的活動をサポートする情報技術進化」に関しては、
いろいろと難しい問題を含んでいるので、簡単に答える事はできない。
「ソフトウェア開発」は、定式化し易い技術領域(ソリューション)よりも、
形式化のしにくい業務領域(アプリケーション)側に、多くの課題があるので、
工学的手法で単純作業に落とし込むのは無理だと思う。
216デフォルトの名無しさん:2005/06/27(月) 17:05:57
いや、プログラミングを単純作業に落とし込むところまで、Prolog に期待し
ているわけではないんです。ただ単に、Prolog の特徴を使って、それ以外の
言語より楽をしたいだけです。

例えば、FORTRAN に比べると、
・C は構造化されているし、ポインタと構造体があるから書きやすい。
・Java はクラスとスレッド管理があるから(そしてポインタがないから)書
 きやすい。
・Lisp はリストと高階関数とマクロがあるから書きやすい。
・関数型言語は参照透過性と遅延評価があるから書きやすい(らしい)。
・SQL は宣言型の記述とトランザクション管理があるから書きやすい。

という風に、それぞれの言語なりのありがたみがあるわけで、そういう視点で
の Prolog のありがたみも考慮に入れてほしいし、アピールもしてほしいと私
は思うのです。

ここで大事なのは、例えば Lisp ならラムダ計算、SQL なら述語論理と言った、
難解な理論的基盤があるわけですが、そういうものは言語開発者には必要でも、
エンドユーザであるプログラマには大して必要ないのです。

こういうスレだと、とかく理論的基盤の話になりがちですが、エンドユーザに
とってのありがたみが広く認知されないと、実務者はなかなか、Prolog に手
を出そうとはしないのではないかと。
217デフォルトの名無しさん:2005/06/28(火) 14:08:51
Prologの特長、楽できるところはパタンマッチとユニフィケーションじゃないか
218デフォルトの名無しさん:2005/06/28(火) 22:45:36
当方Prolog初心者なのですが
Prologをマスターするためのお勧めの本などありましたらご教授ください。
よろしくおねがいします
219デフォルトの名無しさん:2005/06/28(火) 22:52:31
Clocksin & Mellishが良いでしょう。基本です。
220デフォルトの名無しさん:2005/06/28(火) 23:13:16
>>217-219
なんだ、きみは相変わらず話題の流れも読めずに
自作自演で単発質問ごっこやってるのか。
221デフォルトの名無しさん:2005/06/29(水) 05:58:58
>>217
MLやHaskellなどの関数型言語のパタンマッチと、どう違うの?
222デフォルトの名無しさん:2005/07/01(金) 04:19:59
>>211 の >状態の変化が素直に表せない。
ですが、{契機,事象,状態} の連想三つ組でデータベースを
作っておいて、すなわち変化した事象だけを述べておいて、
それを契機をたどって再構成するのではだめなのですか。

Prologのルールとして再構成法を述べるのは素直に表したことに
ならないのでしょうか。
223デフォルトの名無しさん:2005/07/01(金) 12:28:21
とりあえず、ルールベースの状態遷移手法で、
状態変化をルールの追加と削除で表現する、
といった感じでしょうか?
・制御理論の世界では状態遷移行列、
・OOの世界ではStateパターン、
といわれるものと同等の手法かと存じます。

>>211のリンク先で中島氏が提起しているのは、
一階述語論理の枠組みでは、状態や概念階層、様相論理を
素直に表現できないという問題ですので、
回りくどい表現を許せば実用的に問題ない、という見解もあるのでしょうね
224デフォルトの名無しさん:2005/07/01(金) 18:27:27
「状態の変化」の素直な表現がどういうものかイメージしにくいのですが、
何か例はありませんでしょうか?
225デフォルトの名無しさん:2005/07/01(金) 18:31:03
↑一応、時相論理やKripke model等は理解してるつもりです。
226デフォルトの名無しさん:2005/07/05(火) 15:32:23
>>217 Prologはユニフィケーション以外なにもしていない。
227デフォルトの名無しさん:2005/07/06(水) 11:06:59
バックトラッキング...?
228デフォルトの名無しさん:2005/07/06(水) 12:42:23
定理証明系という観点に立てば、バックトラッキングは重要です。
スタック言語という特徴もここからきている。
しかし、それにも関わらず、Prologは徹頭徹尾、ユニフィケーション。

LISPが徹頭徹尾、S式の評価であるというのに対応していると思う。
229デフォルトの名無しさん:2005/07/06(水) 13:07:37
prologの標準的な実装では4本のスタックを使うそうですが,それぞれどういう役割を
持っているのでしょうか?
230デフォルトの名無しさん:2005/07/06(水) 13:12:26
やはり少々言い過ぎですね。
ただ、プログラマの立場からいうなら、意識の99%は
ユニフィケーション。組み込み述語の機能や形式の辞書引きなどが
まったく必要なくなった時点からは、6個程度のユニフィケーションの
ルール以外に頭の中で何も働いていない。
こんなところかな。
231デフォルトの名無しさん:2005/07/07(木) 17:01:25
>>229 PSIのKL0システム制御説明書が手元にあるので掲載します。

  ・グローバル・スタック(Global Stack)
   主として構造体(stracture)内の論理変数の値を保持する。
   また組み込み述語 new_stack_vectorで生成される構造体は
   このスタックの中に置かれる。

  ・ローカルスタック(Local Stack)
   主としてクローズの論理変数(構造体内に現れるものを除く)の値を
   保持する。

  ・コントロール・スタック(Control Stack)
   述語の戻りアドレス。バックトラック先アドレス、呼出しレベル番号
   等の実行制御用情報を保持する。

  ・トレイル・スタック(Trail Stack)
   バック・トラック時に論理変数の値を以前の値に戻すための情報を
   格納する。
232デフォルトの名無しさん:2005/07/08(金) 07:16:46
>>229 データベースと連動したプログラムでは数万要素のリスト(構造体)
くらいは覚悟しなくてはならないので、グローバルスタックの初期sizeが
問題になりますね。
233デフォルトの名無しさん:2005/07/08(金) 20:20:30
>>231>>232
ありがとうございます。
Cで考えると
Local Stack: ローカル変数領域
Control Stack: returnアドレス領域
でしょうか。
structure内部の変数をGlobal Stackとして特別扱いするのは不思議ですね。
またGlobal/Local StackがあればTrail Stackは要らなさそうにも見えますが…。
234デフォルトの名無しさん:2005/07/16(土) 13:43:52
LispでPrologは簡単に作れると言うが、では逆はどうなのだろうか
235デフォルトの名無しさん:2005/07/18(月) 00:25:05
つーかインタラクティブな開発環境でこそ本領を発揮しそうなのに
何故ファイルに書かなきゃいけないようなヘンテコな言語仕様にしたんだろう
236デフォルトの名無しさん:2005/07/18(月) 17:22:10
インタラクティブな開発環境というのが今ひとつ解らないのですが
どんなイメージですか。
assert/1で定義する仕様が使い難いというのは解ります。

私はProlog-KABAがEmacs風エディタを持っていたことから、それを拡張して、
エディタ内で動作するインタプリタを現在でも使っています。
従ってMarkから定義節末までをctrl-x ctrl-sで再定義する的な利用法に
なります。事務処理でPrologを使う場合の課題は対話的にというよりも
例えば「出荷場所、出荷日をキーに日報を作成する」という仕様書から
いかに自動的に、
日報(_出荷場所,_出荷日)
:-
を導くかと言うことにあります。形態素解析などにより、必要な語彙を
抜き取って自動で論理変数の字面を作ったりします。その後、
定義節として組み立て直すのですが、このような手順を踏む以上、エディタを
駆使してという利用法以外、私には考えられません。
237デフォルトの名無しさん:2005/07/18(月) 19:41:37
いや、そんな難しい話じゃなくて
・x(y,z).での定義とx(y,z).での質問が同じ形式なのは解せない
・「変数は大文字から―」は読みにくさ・使いにくさを助長している
とかそういうレベルだよ
インタラクティブってのは、所謂シェルみたいなのが欲しいってことさ
ちょっとイメージがまとまらないさヽ(´ー`)ノスマン
238デフォルトの名無しさん:2005/07/18(月) 22:49:34
Prologのプログラミングというのは、基本的にデータベースの参照に
終始しているといえます。手続き的な要素は
member/2とfindall/3,repeat/0,for/3とfail,true,not/1,でほとんど
構成され、append/3,reverse/2,sort/2のような述語でさえ、めったに
使うことはありません。代表的なパターンは
1・・データベース述語の参照からfailに至るバックトラックパターン
2・・findallで一旦データベース述語をリストに構成して再帰述語に
渡すパターン(データベースではなくstreamであることもあります)
3・・memberでリストの要素を取り出し、failでバックトラックするパターン
この3パターンの組み合わせだけでほとんどの述語(質問)は構成されます。
もちろんC言語などと同様文字列述語なども頻繁に使用されますが、
上記のパターンの中にフィルターとして現れるということになります。
239デフォルトの名無しさん:2005/07/18(月) 23:00:31
>>237 論理変数の仕様については同感です。
私は変数をすべてアンダースコア+漢字変数名で表現しているので
見やすさのレベルはご指摘のケースとは異なります。それでも、
プログラムエラーの90%以上がアンダースコアの付け忘れによって
起こっています。
240デフォルトの名無しさん:2005/07/19(火) 09:58:22
#変数名という仕様が一番よかったと思います。
現在では#クラス名などに使われることが多く、#はもう使えませんね。
というか、使わなかったのが幸いでした。
241デフォルトの名無しさん:2005/07/19(火) 11:09:28
俺なら?変数名だな
242デフォルトの名無しさん:2005/07/19(火) 20:07:32
>>234 LispでPrologを作るよりPrologでLispを作る方が簡単そう。
ただし、PSIで機械語レベルからPrologによってOSを書いた時のことだが
OSのコードはほとんどが「前向きで」バックトラックを必要とする
部分はごく少ない。つまり、テーブルの参照的な部分は少ないと
いうことだろう。とすると、いちいちバックトラック時の「備え」を
するPrologはいかにも効率が悪い。そういう話もあった。
LispをPrologで書く場合も同じことが言えるのではないか。Lispを
書く場合にどれだけバックトラックが必要になるか。そんな視点で
この問題は見ればよいのではないか。
243デフォルトの名無しさん:2005/07/20(水) 18:37:09
>ただし、PSIで機械語レベルからPrologによってOSを書いた時のことだが

キター!!!
244デフォルトの名無しさん:2005/07/23(土) 18:52:19
>>242
沖のPIM-Dって使った事ありますか?
245デフォルトの名無しさん:2005/07/23(土) 21:19:49
> PSIで機械語レベルからPrologによってOSを書いた時のことだが
PSI : Prolog WSの名前
OS : SIMPOS
として、機械語レベルのPrologの名前は何ですか?
246デフォルトの名無しさん:2005/07/23(土) 22:08:55
PSIの機械語の名はKL0です。
247デフォルトの名無しさん:2005/07/23(土) 22:49:22
bitの連載に載ってたっけ?
水平型マイクロコード剥き出しみたいなヤツだったような。
248デフォルトの名無しさん:2005/07/23(土) 22:51:32
あ、elisとごっちゃになってた....orz
249デフォルトの名無しさん:2005/08/12(金) 18:10:10
Prologで書かれたプログラムのユーザーインターフェイスに
皆さんが何を使っているか教えてください。
私はというと、インタプリタのトップから質問を入れています。
250デフォルトの名無しさん:2005/08/17(水) 20:05:58
>>249
Rubyで書いたCGI
251デフォルトの名無しさん:2005/08/17(水) 23:11:27
>>250 htmlファイルの生成はRubyでするのですか。

私はtelnet制御にこだわっているので、
PrologWebServerを立ち上げておいて、telnet上の
Prologインタプリタからw3mやmozillaを起動して、
入力データだけ蒐集させて、それをサーバーに送り
それをさらに同期をとって元のインタプリタが受け取ると
いうインタフェイスも作って使っていました。
ただ、オペレーション速度で、単純な負節呼び出しに
勝てないので現在は使っていません。
PrologWebServerは外部とのインタフェイスとして使われて
おり、そこで使うhtmlファイルが一部書き換え(実行時に行う)だけで
全て流用できるのでその点では便利ですね。
252デフォルトの名無しさん:2005/08/25(木) 17:10:17
SWI-Prologのversion 5.5、 dev版ですがUNICODE support
されているとのこと。
どなたか、試された方はおられますか?
253デフォルトの名無しさん:2005/08/25(木) 17:25:02
>238
>Prologのプログラミングというのは、基本的に
>データベースの参照に終始しているといえます。
鋭いご指摘。これはVBでもJavaでもC++でも
同じです。GUIや通信など余計なものを取り外し、
本質的にまとめるとこうなるのでしょうね。
特に
>>
1・・データベース述語の参照からfailに至るバックトラックパターン
2・・findallで一旦データベース述語をリストに構成して再帰述語に
渡すパターン(データベースではなくstreamであることもあります)
3・・memberでリストの要素を取り出し、failでバックトラックするパターン
<<
論理構造の操作であれば、これで十分なんでしょうか。
254デフォルトの名無しさん:2005/08/26(金) 13:34:28
>>253
そのレスはPrologの動作原理のことを書いてあると思うんだけど、
なにか誤解してない?

Prologのプログラムはルールと事実と問い合わせで構成されているから、
それ自体がデータベースとみなすことができるわけだけど、
VBやJavaやC++が参照するところの「データベース」ってプログラム自体を
指すわけじゃないでしょ。
255デフォルトの名無しさん:2005/08/27(土) 08:39:14
>>254
Prologがデータベースの参照に終始していると言うのは
質問または副目標の実行が全て定義節の頭部との
ユニフィケーションという単一の動作原理に導かれている
から。
プログラムを書くとき、読むとき、そこだけを押さえて
いればよい。
>>253 は、どんな言語でも本質はプログラマが与えた
情報(データベース)を引き出すことにある、という
ことを言っているのだと思う。興味深い指摘だが、
>>238で書いたことと若干ニュアンスが異なる。
256デフォルトの名無しさん:2005/08/27(土) 08:51:53
255の補。
ただ、私の場合OracleやPostgresqlのデータベースを
最近全て、Prologの定義述語に変換した。その心は
Prologとはデータベースである、ということを
完全に実現したかったから。そういう意味では>>253
見解の方に近いのかもしれない。
257デフォルトの名無しさん:2005/08/27(土) 20:58:26
DATA_Baseを内部にもつのか、それとも外部に
もって、例えばRDBからSQLでデータをプログラムに
取り込んで利用するのか、確かに実装上は大きな
差異です。
しかしデータから付加価値を生み出すという
プログラムの本質部分に注目すれば
まあそれは若干直接操作して利便性が高くなるのか
ワンクッションSQLを介するのかの差異であり
あまり大きな問題ではないと考える訳です。
RDBのデータとオブジェクト構造をORマッッピンしなくては
いけないか、それともODBから直接オブジェクト構造化された
ものを利用するのかの差異と同じようなものだと。

ここで問題にしたいのは、ロジックの側です。
具体的な問題領域特有のロジック構造以外は、
ある汎用的な操作でデータ処理が可能なんでしょうか?
>>
1・・データベース述語の参照からfailに至るバックトラックパターン
2・・findallで一旦データベース述語をリストに構成して再帰述語に
渡すパターン(データベースではなくstreamであることもあります)
3・・memberでリストの要素を取り出し、failでバックトラックするパターン
>>
勿論全てをこれでカバー出来るとは思いませんが
問題の70〜80%程度はこのパターンの中に納まる
のでしょうかとお伺いしている次第です。
258デフォルトの名無しさん:2005/08/28(日) 22:20:43
>>257
Prologでプログラムが組めるようになれば、
その質問の答えは自ずから理解できる。

ここで聞くだけ聞いて済まそうというというつもりなら
答えだけ聞いても「ふーん、そんなもんか」で終わり、
結局自分の身にならない。
259デフォルトの名無しさん:2005/08/28(日) 22:24:27
k(1)写経中
260デフォルトの名無しさん:2005/08/29(月) 16:18:10
> 258
> Prologでプログラムが組めるようになれば、
> その質問の答えは自ずから理解できる。
>
> ここで聞くだけ聞いて済まそうというというつもりなら
> 答えだけ聞いても「ふーん、そんなもんか」で終わり、
> 結局自分の身にならない。

随分敷居が高いんですねぇ。
伝統的にム板においては、文句は言うが
聞かれた質問には応えていた。
コードなんか、ブツブツ言いながらも山のように
質問者のために書いてやっていた。

時代が変わったのか?
それとも、
ム板BLの方針が変わったのか?
それとも
質問に応える知識とコードを書く技術自体が
衰退してしまったのか?
ー>関数型言語スレも

261238 255:2005/08/29(月) 16:59:58
プログラムパターンについては書きたいことがまだまだ
あります。どこから書いたらいいか。
Prologはパターン数の少ない言語でその点からもっと
注目を浴びていいと思うのだが、この問題に言及した
啓蒙書がない。Prologブームが下火になった頃に
プログラムパターンが注目されだしたということでしょう。

今回私が示した3つのパターンはデータベースから情報を
引き出し、何らかの働きかけがあって出力する。そこまでの
殻の部分、スクリプト的な部分ですね。2はちょっと性格が
異なりますが、初心者にはこれを教えてあげないと、
集約問題でPrologが嫌になります。findallの第二引数
つまり蒐集項の中にmember/2が現れる、そういうコードは
意外と多いものです。
この外殻パターンは比較的簡単に「空気化」します。
やはり、再帰パターンが「空気」となるかどうかが
Prologプログラマとしての正念場でしょうか。
262デフォルトの名無しさん:2005/08/30(火) 10:26:04
上記3パターンでPrologプログラムの何パーセントを
カバーできるのかという問題は、バックトラックを
含むロジックでは95%以上でしょう。後でよくよく見ると
全部これだったと言う感じです。
Prologの述語にはバックトラックしない述語もありますから
連言が恒に真になるような述語ですね。それから再帰述語。
これらがどのくらいの比率になるかはプログラマの個人差
が大きいと思います。30%くらいで、3パターンの方が
70%というのはいい線いっているかも知れません。

再帰述語は本当にパターン化していて、ほとんど切りません。
読み飛ばし、打ち切り、コピー、変換。他に経路問題(祖先)的なリンク。
その時に、情報を引数として与えるか、リストの中で十分なのか。
それだけですね。
オリジナルなコードというのはほとんど切る余地がありません。

スケジュール問題などはこれら全てのパターンが二重三重に出てきて
ちょっとスリリングですが。
263デフォルトの名無しさん:2005/08/30(火) 10:44:26
パターンの話からは離れますが、以前、
repeat.
repeat :- repeat.
だけをテーマにした講習会を開いたことがあります。

上記の述語から出発して、引数を与えていくと何が
起こるかということを正味5時間講義しました。
定義述語から再帰述語だけで、データを収集することが
なぜ不可能かを完全に理解させるなどといった隠された狙いの
ある画期的な講座のつもりだったのですが、初心者には
むずかし過ぎて不評でした。
264デフォルトの名無しさん:2005/08/30(火) 17:14:01
>261,262,263

丁寧な解説有難う御座いました。

>Prologはパターン数の少ない言語でその点からもっと
>注目を浴びていいと思うのだが、

言語仕様そのものに論理ロジックを組みこんだ言語
(一般言語よりメタ言語)ですから、そのロジックを
取り込んでいる比率に応じてパターン数は
減るはずであり、つまり、少ないパターンで
問題領域がカバーできる、ということですね。

>3パターンの方が70%というのはいい線いっているかも知れません。

素人的な表現で申し訳ありませんが、メタ化された言語で
さらにメタ化を実現して絞りに絞ったパターンとしては
一体何が残るのだろう、と興味を持った次第です。

265デフォルトの名無しさん:2005/08/30(火) 17:14:52
>外殻パターンは比較的簡単に「空気化」します。
>やはり、再帰パターンが「空気」となるかどうかが
>Prologプログラマとしての正念場でしょうか。

この辺りは関数型言語と近いですよね。
自己遡及的な再帰パターンが身体化するかどうか。
コンパイラベースの実装は繰り返しでも、関数スタックを
使用しなくても、それが高速であれば問題ないと思う訳です。
プログラマにとって問題を再帰構造で写像できるかどうか
これが重要だと。

>定義述語から再帰述語だけで、データを収集することが
>なぜ不可能かを完全に理解させるなどといった隠された狙いの
>ある画期的な講座のつもりだった

これはデータ収集においても、ドメイン・スペシフィックな
アルゴリズムが不可欠であると言う意味でしょうか?
266デフォルトの名無しさん:2005/08/31(水) 18:18:04
そんな高水準な話ではありません。どちらかというと
からくり人形水準の話です。
Prologはバックトラックを制御に組み込みました。しかし
バックトラックが働くのは論理的に偽なった時で、一方、
再帰述語は真になった時のみ意味を持ちます。
非決定性の述語として定義されるデータベース、たとえば
身長(彩,160).
身長(未来,165).
身長(あゆ,157).
から[[彩,160],[未来,165],[あゆ,157]]というリストを
得たいとします。
このデータを収集するのに再帰的述語で一旦真になり、
得た[彩,160]をfailしてしかもリストに保持することは
不可能です。しかし、ここが初心者にとっては解りにくいのです。
それで、再帰的述語でありながら、バックトラックして
その機能を発揮する特異な述語repeatを出発点として
それに定義節を挿入したり、引数を与えたりしながら
何とか上記のリストを得ようと努力させます。これは
当然徒労に終わるのですが、この問題に苦闘することで、
なぜ、不可能なのかを一気に理解させようという試みでした。
残念ながら当時のテキストを読み返すとこのような企みが
あったとは思えない踏み込み不足の講義だったようです。
でも着眼としては面白いと思うのでそのうち機会があったら
やり直してみたいですね。
267デフォルトの名無しさん:2005/09/01(木) 18:54:32
>266
>データベース、たとえば
>身長(彩,160).
>身長(未来,165).
>身長(あゆ,157).
>から[[彩,160],[未来,165],[あゆ,157]]というリストを
>得たいとします。

>不可能です。しかし、ここが初心者にとっては解りにくいのです。

申し訳ありません。何故こんなことが不可能なのか?
さっぱりワカリマセン。
普通のハッシュテーブルに見えるが…
Prologを勉強して改めて出直します。
268デフォルトの名無しさん:2005/09/02(金) 07:45:42
>>267 ストリームからのreadとの比較で考えましょう。
ここではストリームとは順序付けされた情報の列でシステムが
これをカウンターを保持しているように管理して、次々と
情報を渡してくれるようなものとします。

get_data([A|R])
:-
read(A),not(A=end_of_file),get_data(R).
get_data([]).
型の再帰述語でリストに収集することが可能なことは
おわかりでしょう。それでは、

get_data([[X,Y]|R])
:-
身長(X,Y),get_data(R).
get_data([]).
ではどうか。これだとX,Yには最初の彩と160がバインドされ続けて
停止することができず、多分スタックオーバーフローが起きます。
ここまではおわかりになりますか?
269デフォルトの名無しさん:2005/09/02(金) 08:44:18
Prologって何ができて何ができないの?
例えば計算機(1+2*3とか)作れる?
270デフォルトの名無しさん:2005/09/02(金) 09:45:51
できない事から。できないというよりやらない事。

AdobePhotoshopをPrologで書き直すこと(たとえば)。

何百万回の演算を相当数繰り返すような操作は苦手。
271デフォルトの名無しさん:2005/09/02(金) 10:01:08
>>269
計算機(_式,_答え) :- _答え is _式.

実行例
?- 計算機(1+2*3,X).
X=7
yes
?-
これでも計算機として十分だと思いますが、おっしゃられていることは
文字列 "1+2*3" を解析して
1 + ( 2 * 3) = 6 を導けるかという意味なのでしょうね。

結論から言うと(プログラムは間に合いませんが)、こういった
文字列の解析はPrologの最も得意とするところと言えるでしょう。
272デフォルトの名無しさん:2005/09/02(金) 17:30:07
>268
申し訳ない。
>データベース、たとえば
>身長(彩,160).
>身長(未来,165).
>身長(あゆ,157).
と書かれてあると条件反射的に、身長という
Columnに(彩,160)(未来,165)(あゆ,157)という
ハッシュテーブルが格納されているイメージしか
浮かびません。
どちらにしてもprologの基礎からやらないと…

>この問題に苦闘することで、
>なぜ、不可能なのか
ただ、この部分は面白い。
目的が方法論的に実現不能であるということを、言わば
ゴール自体が偽であることを、証明する作業になる訳ですよね?
つまりバックトラックして真であることを証明すると
ゴールが偽であることが判明する訳です。
で、もしそれが、バックトラックして偽であることを
「発見」すれば、逆に画期的なことになります。

ここからは、単なる個人的な想像ですが、本来prologは
そのような使い方が合っているのではないでしょうか。
不可能なゴールを設定して、それを証明する過程で、逆に
偽であることを「発見するのに」適しているのでは
ないでしょうか。
例えば第5世代コンピュータ開発時代に「それを作る」
という前向き推論ではなく、「それは不可能だ」という
ゴールを設定したらどうだったんでしょうね。
そのゴールから後向きに推論を重ねることで
逆に「その綻び」を発見する訳です。
273デフォルトの名無しさん:2005/09/02(金) 18:32:39
すべてのfactを集める処理は,公理系の中で,すべての公理を集めるようなものだね。
集める人は系の外側に居ないといけない。
274デフォルトの名無しさん:2005/09/03(土) 02:15:22
>>266

>データベース、たとえば
>身長(彩,160).
>身長(未来,165).
>身長(あゆ,157).
>から[[彩,160],[未来,165],[あゆ,157]]というリストを
>得たいとします。

>不可能です。しかし、ここが初心者にとっては解りにくいのです。

リストを得ることは、

findall([A,B], 身長(A,B), X).

で、可能なんだが。

C = [[彩,160],[未来,165],[あゆ,157]]
275デフォルトの名無しさん:2005/09/03(土) 02:21:44
>>274

訂正

C = [[彩,160],[未来,165],[あゆ,157]]

  ↓

X = [[彩,160],[未来,165],[あゆ,157]]
276デフォルトの名無しさん:2005/09/03(土) 04:55:30
findallの類を使わずにリストを得ることは不可能、という意味でしょ。
277デフォルトの名無しさん:2005/09/03(土) 11:07:42
>276
>findallの類を使わずにリストを得ることは不可能、という意味でしょ。

そうではなくて、

>272
>不可能なゴールを設定して、それを証明する過程で、逆に
>偽であることを「発見するのに」適しているのでは
>ないでしょうか。

でないと、単に初心者に不可能なことをやらせて
「ほうら!出来なかっただろう。」って…
278デフォルトの名無しさん:2005/09/03(土) 13:05:55
>277
この話は>>238あたりに源があって延々と続いています。
findall/3については>>261で指摘いただいたことにもちょっとだけ
触れました。私は事務計算用にPrologを使っているのでfindall/3なしには
暮らせません。

ここでの話のポイントは再帰述語から単位節で定義された述語の
引数データを収集することが「不可能」であるということです。
私がPrologを学び始めた20年ちょっと前、古川康一、黒川利明、高木茂行、
中島秀之、溝口文雄氏といった錚々たる方々からPrologの手ほどきを
受けました。私の記憶ではこの問題に触れてそれが不可能な事なのだ
と言う説明をされた講師の方はいらっしゃらなかったように思います。
私はこの問題に結構悩みましたので、早めにはっきりさせておいた
方がいいと思っていたわけです。
279デフォルトの名無しさん:2005/09/03(土) 15:59:21
>>278
あなたの問題意識がよく分かってないのですが、例えば

height(aya,160).
height(mirai,165).
height(ayu,157).

p([X,Y]) :- height(X,Y).
q([X]) :- p(X).
q([X|Xs]) :- q(Xs), p(X), not(member(X,Xs)).
r(Xs) :- p(X), not(member(X,Xs)).
s(Xs) :- q(Xs), not(r(Xs)).

?- s(X).
X = [[ayu, 157], [mirai, 165], [aya, 160]]

という方法は「再帰述語から単位節で定義された述語の引数データを収集する」
というruleに反するのでしょうか?

> 私がPrologを学び始めた20年ちょっと前、古川康一、黒川利明、高木茂行、
> 中島秀之、溝口文雄氏といった錚々たる方々からPrologの手ほどきを
> 受けました。
確かに凄い。羨ましいです。当時はどういう話題がprologの最先端だったのでしょうか?
280デフォルトの名無しさん:2005/09/03(土) 16:25:13
>>279
その方法は可能ですね。
定義節がRDBであり、集合であるとするならばそれで良いと思います。
述語定義の場合は重複を妨げる約束がないとするのが
一般的な述語の解釈ですので、完全なものは難しいのでは
ないでしょうか。

281デフォルトの名無しさん:2005/09/03(土) 17:45:55
>278
いやぁ、深い意味はありません。
普通プログラム言語を教える時って
こんなことも出来る、あんなことも出来る
って、まずその有用性を吹聴するのが通例ですよね?

それを、初心者に不可能なことをいきなり体験させて
その言語の不能性を叩き込むって、いかにも
prologらしい。
実に「後向き」推論の効いたやり方だなぁ、って
感心しただけですから。

>私がPrologを学び始めた20年ちょっと前

これは当時からの伝統でしょうか?
282デフォルトの名無しさん:2005/09/03(土) 19:16:29
当時はこれも教えたい。あれも教えたい。一日の講習で
できるだけ進みたい。ですから、「前向き」でした。
append/3,sort/2,reverse/2と3,member/2、それに!くらいでもう
夕方になってしまいます。
今と違って再帰的な処理に慣れてなかったですね。私もLISPやPascalは
やっていたのですが、Prologの再帰は目の付け所が違っていて
面食らいました。

溝口先生の時は理科大の柏校舎で「エキスパートシステム」を
テーマにした泊まり込みのワークショップ的な講習会でした。40-50人は
集まりました。楽しかった。
それから、Prologの問題点や欠点に案外と触れられたのが田中穂積先生の
自然言語処理に関する講習会です。これは、田中先生が論理プログラミング
の研究者としてではなくユーザーとしてPrologを見ることのできる
立場だったからではないかと思います。
283デフォルトの名無しさん:2005/09/04(日) 08:33:28
>>279
ああ、そうやればよかったのか。上手いね。
284デフォルトの名無しさん:2005/09/04(日) 10:31:38
>282
>Prologの問題点や欠点に案外と触れられたのが田中穂積先生…

どうもこの点が良く分からないんです。
当時は今と違って相当の数の人々がPrologを学習した
はずですよね。
官民挙げて取り組んだ第5世代コンピュータの旗艦言語
として、鳴り物入りで採用されたPrologが何故?
ここまで衰退してしまったのか。

1)ホストとパソコンという環境の差でしょうか?
2)GUIへの対応の遅れでしょうか?
3)それともPrologの言語仕様を
  他の言語が取り込んじゃったとか?
285デフォルトの名無しさん:2005/09/04(日) 15:42:13
aranskさん、名前を書き忘れてますよ。
286デフォルトの名無しさん:2005/09/04(日) 19:09:43
>>284
もっとも「前向き」な回答を一つ。
プログラマの水準が上がったということがあると思います。
そんな馬鹿なというなかれ。現在では、
たとえば、C++のプログラマで
Prologくらいの機能ならば「必要ならばいつでも書ける」と
思っているプログラマは結構多いのではないでしょうか。
20年前だとNearlyZeroですね。この差は大きい。
そこまでの自信があれば、Prologに特化しておく必要は
ないですね。
287デフォルトの名無しさん:2005/09/05(月) 13:13:32
>>286
ここ十年に限っていえばWindows向きの作りに
なっていないということでしょうね。
WindowsマシンのデスクトップにTeraTermが
標準で載っていれば少しは違ったかも知れません。
288デフォルトの名無しさん:2005/09/05(月) 18:59:41
>286
どうなんでしょう?
ある面、能力的に低下している部分は
ないのでしょうか?
つまり、ロジックにおける細密さです。
GUIやDB操作、WEB系の技術にかまけて
情報そのものの付加価値再構成にうとく
なっていることはないんでしょうか?
表象系(REPRESENTATION)にしか目が
向かない、地味なロジック系がないが
しろになっているようなことは?
> 私がPrologを学び始めた20年ちょっと前、古川康一、黒川利明、高木茂行、
> 中島秀之、溝口文雄氏といった錚々たる方々からPrologの手ほどきを
> 受けました。
我々の世代は、既に先生達の世代を凌駕しちゃったんでしょうかねぇ?
その論理性において、その思想性において。
289デフォルトの名無しさん:2005/09/05(月) 19:58:21
>>288
C++でユニフィケーションがいつでも書けることと
論理プログラミングに精通しているとは関係が
ありませんね。Prologを5年も粘っていれば
誰でも論理式が日常的なものになりますが、
どんなに優秀なC++のプログラマでも論理式は
別物です。
データモデルの構築などという領域では
C++やRuby、Pythonといった言語のプログラマには
想像もつかない奥行きがPrologにはあります。
安定したレベルでの環境に身を置かないとわからない
こともあるのでそういう意味で>>286は不完全で
一方的な見解ということになるでしょう。
290デフォルトの名無しさん:2005/09/05(月) 20:53:14
他分野をつまい食いして回る哲学屋(not 哲学者)の>288と
職人肌だが視野の狭い経験主義者の>289

の間で交わされる会話の空虚さが実に面白い。
291289:2005/09/05(月) 21:23:34
経験主義者ね。歳とったから。

身長(彩,160).
身長(未来,165).
身長(あゆ,157).
の代わりに、
身長([[彩,160],[未来,165],[あゆ,157]]).
と定義すると、じんま疹がでるという感覚は
わからないだろうなー。
292デフォルトの名無しさん:2005/09/06(火) 06:57:18
つまりそれを説明できるほどの語学力や論理的思考ができないというわけね。
293これがprologです:2005/09/06(火) 07:15:13
言葉での説明ですか。それでは経験主義的説明に入ります。
Prologのプログラムの読み方、検証について述べます。
Prologのプログラムはまず副目標が合って、それに対応する
述語の定義節を調べることになりますが、その時、
関数、引数を上から「引っ掻くように」読みます。この引っ掻く
感覚は、短距離走で膝から下を前に振り出しそれを引き戻して
地面を引っ掻く感覚に近いものです。考える隙はありません。
走るときはこの後、脚が体の下で自転車をこぐように回転する
ように動きますが、Prologでは連接する副目標に戻り
次の定義節を「引っ掻きます」。これがぐるぐる回る感覚に
なります。
この感覚で進むには
身長([[彩,160],[未来,156],[あゆ,157]]).
の定義記法では絶対にだめなのです。
これがPrologです。
294デフォルトの名無しさん:2005/09/06(火) 20:17:12
人に伝えることを目的にしてるとは思えん説明だな。デムパは去れ。

295デフォルトの名無しさん:2005/09/07(水) 10:18:17
>>294
「経験主義者」というレッテル貼られたから皮肉で返しているだけだろ。
ただでさえ少ない住人を更に減らすようなレスはどうかと思うぞ。
296デフォルトの名無しさん:2005/09/07(水) 15:39:12
>>293のどこがどう経験主義的説明なん?
297デフォルトの名無しさん:2005/09/07(水) 16:52:58
長くある言語を使っていると誰でもこの言語の要諦はここだ
というものがあるだろう。私の場合は、構造の浅い、平板な
Prologのデータベースを縦方向に走査するとき、それを
感じる。Prologが縦方向に一気に一瞥できるデータ表記法に
なっていることはバックトラックアルゴリズムと無関係では
ないが、そのような理屈よりは、「Prologならでは」の感覚が
どこにあるかを述べたかった。
横方向でなく縦方向だと強調しているのは、Prolog以外に
データベースの構築をこの方向に表記できる言語を少なくとも
私は知らないからだ。現在主流の言語がPrologを乗り越えたのか
という話からいえいえPrologには独自の領域がありますよという
流れになっている。
これは結構「経験主義的」説明だと思うけど。
298デフォルトの名無しさん:2005/09/07(水) 18:32:21
経験主義的でもいいじゃない。

自分の経験を度外れに拡大して「Prologとは〜」と一般論にしたり、
それに基づいて他の言語を批判したりしなければ。
299デフォルトの名無しさん:2005/09/08(木) 00:08:14
「経験主義」言いたいだけちゃうk(r
一度ぐぐってみる程度の知恵はないのかねぇ
300デフォルトの名無しさん:2005/09/08(木) 08:54:38
「経験主義」はジョークみたいなもんだから。
このスレはPart 2の前後からだから新参者ですが
日常、Prologを使い続けてる人の話をできるだけ
多く聞きたいね。
301デフォルトの名無しさん:2005/09/08(木) 11:04:55
>>298 >>289辺りのことをいっているのだと思うけれど
何か読み違いをしていませんか。他の言語批判なんて
全然していませんよ。
302デフォルトの名無しさん:2005/09/08(木) 18:33:17
>>301
> 自分の経験を度外れに拡大して「Prologとは〜」と一般論にしたり、

こっちは否定しないんだw
303デフォルトの名無しさん:2005/09/08(木) 18:43:24
>>302
都合の良いところだけ取り上げて反論するのは議論の基本だろ.
隙を見せた>>298が悪い.

関係ないがpart 1も熱かったよな…
304名無しさん@そうだ選挙に行こう:2005/09/10(土) 16:52:51
>291
>身長(彩,160).
>身長(未来,165).
>身長(あゆ,157).
>の代わりに、
>身長([[彩,160],[未来,165],[あゆ,157]]).
>と定義すると、じんま疹がでるという感覚は
>わからないだろうなー。

身長に対して、個別にデータを代入するんじゃなくて
一気に初期化したと考えたらどう?
305名無しさん@そうだ選挙に行こう:2005/09/10(土) 21:36:56
このスレ読んでprologかっこいいなぁ、と感じました。
自分でprologインタプリタを書くことはできますか?
参考資料があれば教えてください。
306名無しさん@そうだ選挙に行こう:2005/09/10(土) 23:13:03
307デフォルトの名無しさん:2005/09/11(日) 00:49:22
>>304
Prologの定義は超時間的?なものだからその解釈は自然ですね。
ただ、この話では、
・ 外延的な表記
・ 他の言語のデータベース定義がテーブルや配列等、右方向に
伸びる形式で表記されることが多い。
の二点を強調したかった。うまく説明できそうになかったので
じんま疹で誤魔化したらすぐに批判が来た。
リスト形式で格納する案は
?- ・・・,身長(L),( member([A,B],L),foo(A,B),・・・
でfooに論理的な解釈が来る。もちろん、
?- ・・・,身長(L),foo(L,Y), ・・・の場合もある。
Lを読む気はなく、fooでデータベースの解釈を述べる定義となる。
それに対し、ここで外延的な表記と言ったのはこれ以上ルールとして
述べられない原初的な情報。それを強調したコードを書きたい。

(ちょっと長くなるから一旦切る)


308デフォルトの名無しさん:2005/09/11(日) 01:38:25
突飛かも知れないが、例の先祖定義で考えよう。
親子(為義,義朝).
親子(義朝,頼朝).
先祖(A,B) :- 親子(A,B),!.
先祖(A,B) :- 親子(A,C),先祖(C,B).

原初的情報とは、親子、為義、義朝、頼朝、であり、
これを、
親子([[為義,義朝],[義朝,頼朝]]).
と定義しても、先祖の定義の変更すれば良いのだが、
プログラマとしては絶対に受け入れられないくらいの意味です。
309デフォルトの名無しさん:2005/09/11(日) 02:09:32
>>305
SWI-Prologのソース読んでみるというのもある。ただし、ヒントに
なりすぎるかも。
ハイスペックのマシンでは、PrologでPrologインタプリタを書く
つまり、デバッガーで動かすのは当たり前だから、最初にこれの
しっかりしたものを作ってからにするとよい。
310名無しさん@そうだ選挙に行こう:2005/09/11(日) 07:57:33
昔PC-9801用のPrologがあった。これかな?
http://hp.vector.co.jp/authors/VA000672/#sprolog

最初に書くときはGCを面倒みてくれる言語を使った方がいいと思う。
311名無しさん@そうだ選挙に行こう:2005/09/11(日) 12:07:01
>>307
> ?- ・・・,身長(L),( member([A,B],L),foo(A,B),・・・

これが嫌なら、

身長(Who, Value) :- 身長(Data), member([Who, Value], Data).

みたいなのも定義するとか。
312デフォルトの名無しさん:2005/09/11(日) 16:30:55
単位節からリストへの変換はfindall/3を使うか、
効率の悪い>>279になる。一方、リストに保持すれば、
>>311でいけるからこちらの方が一般的といえるかも
しれない。じっさい、データベースがORACLE等の外部の
場合、
?- select * into L from 身長,( member([WHO,VALUE],L),・・・
のようなコードとなるだろう。この時、RDBSでの定義は>>307的に
いうなら、外延的な表記以外の何者でもない。
このように考えると確かに>>307->>308の外延重視の根拠が
疑わしくなってくる。
データモデルを構築する際にわざわざ
身長([[彩,160],[未来,156],[あゆ,157]]).
と定義して、>>311で取り出す手法を使う
Prologプログラマがどれだけいるかは疑問ではあるが。

313デフォルトの名無しさん:2005/09/12(月) 08:09:36
Ciao Prolog には、findall に加えて、解のリストを、N 以下に
抑える findnsols があるんだが、他の Prolog にもあるのかな?
普通の findall だと、解のリストが多過ぎる場合に、困るんだが。

findall(Template, Generator, List)

findnsols(N, Template, Generator, List)
314デフォルトの名無しさん:2005/09/13(火) 16:51:20
>身長([[彩,160],[未来,156],[あゆ,157]]).

全然関係ない話ですが、無償のPrologの処理系って
基本的に日本語は通りませんよね?
315デフォルトの名無しさん:2005/09/13(火) 18:20:20
SWI-Prologの場合。

?- '身長'([['彩',160],['未来',156],['あゆ',157]]). は○

?- 身長([[彩,160],[未来,156],[あゆ,157]]). は×

?- '身長'(_氏名,_値). これも× (_氏名,_値は変数)

だったと思います。書き換えて使っているので正確には思い出せない。

SWI-Prologで日本語を完全にに使うためにはpl-ctype.cファイル内の
文字型テーブル書き換え後再コンパイルが必要です。


316デフォルトの名無しさん:2005/09/15(木) 17:40:22
>315
SWIの5.5はUNICODE対応らしいが、どなたか使った方は
ありませんか?
317315:2005/09/16(金) 06:44:38
すみません。私のはVersion5.4.5でした。
できるだけ早く、5.5試してみます。
私はEUCなのですが。
318デフォルトの名無しさん:2005/09/18(日) 04:58:31
V5.5.3 のEUCだと
> ?- '身長'(_氏名,_値). これも× (_氏名,_値は変数)

は○ですね。
319デフォルトの名無しさん:2005/09/23(金) 15:04:55
>>318
UTF-8 でも同じですね。5.5.31ではEUCとUTF-8の
差はないようです。5.5.4でさらに変わるのかも知れない。

pl-utf8.c というファイルがあります。
pl-file.cも内容が変わっていますが、この中で
'を外すことはできそうです。
320デフォルトの名無しさん:2005/10/03(月) 21:49:01
swi-prologを使ってます。
prologのsource fileを読み込む処理を書こうとしているのですが、
consultを使うと、ファイルの中身が変な場合でも成功してしまい、
チェックすることができません。

なにか良い方法はないでしょうか?
321デフォルトの名無しさん:2005/10/06(木) 12:45:34
>>320
ERROR:表示とソースの位置(行数)が表示されますが、
エラー箇所で止まることを望まれますか。
322デフォルトの名無しさん:2005/10/06(木) 13:24:38
相応しい述語名のアドバイスをお願いします。

述語は
以前出てきたPrologサーバーでの共用Prologデータベース側で
実行されることを宣言するものです。

サーバーの参照は基本的に、
?- ..,node1 :: 身長(彩,X), ...
のようにサーバー名をつけて、すなわち
述語 :: の第一引数にサーバー名、第二引数に質問を
置く形式になっています。これは参照の場合で、
子スレッドで実行される場合です。共用Prologデータベースの
追加、更新、削除は親スレッドで実行される必要があり、
?- ...,node1 :: xxx(assertz(身長(豊,169))), ...
のような形式にしたい。ここでは仮にxxxになっていますが、
xxx に 相応しい述語名を付けてください。


323デフォルトの名無しさん:2005/10/06(木) 18:49:18
>>320
たしかにconsultは常に成功するみたいだね.変な仕様だ.

対策としては,file末尾に特定の述語を置くようにしておき,それが定義されてるかどうかで
読み込みの成否を判定するというのはどうだろう.
324デフォルトの名無しさん:2005/10/07(金) 16:38:47
>>322
意味的には、node1 のコンテキストでの call/1 ということになりますか?
だとすると call で始まる名前がいいのではないでしょうか。

call_with_remote_context とか?(Schemeっぽいけど)

325デフォルトの名無しさん:2005/10/07(金) 18:33:09
>>320
swi-prologには例外みたいなものがなかったっけ?
consultで例外が投げられていたりしない?
326デフォルトの名無しさん:2005/11/07(月) 10:56:25
あげ
327デフォルトの名無しさん:2005/11/08(火) 10:57:11
友人が大学でPrologを勉強させられているけど、役に立つか
どうかわからん、っていってました。
Prologはどんな特徴がある言語ですか。
それから、どうすれば入手できますか。
Swi-Prologというサイトは直ぐ見つかりましたが
これは代表的なものなのですか。
328デフォルトの名無しさん:2005/11/08(火) 19:43:43
友人=脳内友人じゃなければ友人に聞け
329デフォルトの名無しさん:2005/11/08(火) 20:42:48
>>327
言語の特徴、入手方法、SWI-Prologのどれも
このスレ(とくに前スレ)でくどいくらい出てきます。
330デフォルトの名無しさん:2005/11/09(水) 22:29:13
SWI-Prologは最メジャー処理系
331329:2005/11/10(木) 11:25:56
スレを読んで欲しいな、ということです。

特徴だけ。

Prologは質問にシステムが答えてくれることの
連鎖でプログラムが進行していくように
見える(感じられる)言語です。
最小単位の質問で得られた答えを次の質問の
入力にして、質問して、その答えをまた・・・

という具合ですね。
実は他の言語でも似たようなものなのですが、
そのことがはっきり(くっきり)感じられることが
Prologの特徴であり、長所なのだと思います。

332デフォルトの名無しさん:2005/11/27(日) 00:42:51
ここでprolog製ソフトウェア一覧を頼む
333ハーピィ:2005/12/05(月) 03:15:22
E・∇・ヨノシ <333ゲット♫
334デフォルトの名無しさん:2005/12/05(月) 23:01:19
ひどい
335デフォルトの名無しさん:2005/12/09(金) 22:06:54
age
336デフォルトの名無しさん:2005/12/09(金) 22:08:30
ageれてなかった
337デフォルトの名無しさん:2005/12/18(日) 04:22:41
最近興味でてきたから遊んでるんだけど、
たまにチュートリアルとかで見る
append( X, List, [X|List] ).
この述語の名前のつけかたって
なんていうか汚くない?
list( CAR, CDR, [CAR|CDR] ).
こうやる方が美しく感じるんだが
338デフォルトの名無しさん:2005/12/18(日) 07:01:50
CAR,CDRってなんですか?
339デフォルトの名無しさん:2005/12/18(日) 08:27:02
340デフォルトの名無しさん:2005/12/18(日) 12:29:30
FirstとRestでもいいよ
341デフォルトの名無しさん:2005/12/18(日) 21:06:30
head and tail
342デフォルトの名無しさん:2005/12/18(日) 23:17:21
HeadとTailでリストを表すと
顔とその何倍の長さもあるしっぽだけっていう
不格好なバケモノを想像するので嫌ッ!
343デフォルトの名無しさん:2005/12/18(日) 23:32:14
どう見ても精子です。
ありがとうございました。
344デフォルトの名無しさん:2005/12/19(月) 00:13:28
warata
345デフォルトの名無しさん:2005/12/25(日) 14:29:54
ESPの復活はないのだろうか。
346デフォルトの名無しさん:2006/01/05(木) 01:33:07
a
347デフォルトの名無しさん:2006/01/07(土) 00:15:22
i
348デフォルトの名無しさん:2006/01/07(土) 22:06:20
% LInux環境のSWI-Prologで作動 Rowは行、Colは桁の位置
% cursor(20,30),write('あいうえお')
% write_cursor(Col,Row,X) :- cursor(Row,Col),write(X).
cursor(Row,Col) :-
Y is Row,X is Col,
put(27), put(91),
write(Y),
put(59),
write(X),
put(72),!.
349デフォルトの名無しさん:2006/01/07(土) 22:17:45
% Start=開始の数字,Finish=修了の数字,Result=経過数,F=実行述語
% Fの述語は括弧で括れば複数の述語も繰り返し実行可
% 例:for_do(1,50,X,(write('A'),write(X),tab(1)))
% A1からA50迄を表示
for_do(Start,Finsh,Result,F) :-
ctr_set1(Start),repeat,ctr_inc1(Result),F,Result==Finsh.

ctr_set1(T) :- abolish(cnt/1),asserta(cnt(T)).
ctr_is1(T) :- cnt(T).
ctr_inc1(T) :- retract(cnt(T)),T1 is T+1,asserta(cnt(T1)).
350デフォルトの名無しさん:2006/01/07(土) 22:24:16
%----------------------------------------------------------------
% 条件式 Cが成功(真)ならばX1を実行する
ifthen(C,X1) :- C,X1;true.
%----------------------------------------------------------------
% 条件式 Cが成功(真)すればX1を実行し、失敗(偽)であればX2を実行する
ifthenelse(C,X1,X2) :- C,X1;X2.
%----------------------------------------------------------------
351デフォルトの名無しさん:2006/01/08(日) 00:49:51
>>338
亀レスご免。
CAR は Contents of the Address part of Register number
CDR は Contents of the Decrement part of Register number
IBM704の機械語の呼称だとのことです。

「LISP入門」 黒川利明著 培風館 1982年 P71 にそんなことが
書いてありました。
352デフォルトの名無しさん:2006/01/08(日) 01:15:36
350 ifthen、ifthenelse使い方
ifthen(X2 >= 0,M2 is N),
ifthenelse(X > 0,write('A'),write('B'))
353デフォルトの名無しさん:2006/01/08(日) 01:27:50

%Linux環境SWI-Prologで作動

% test.plプログラムの開始の頭部がmain/0の場合、compile(test,main).
% で実行ファイルが生成される。実行は./test
% test.plのプログラムが main :- write(12345).の内容だったら
% ?- compile(test,main).で実行ファイルtestが生成され ./testで
% 12345と表示される
compile(Program,Goal) :-
load(Program),
qsave_program(Program,[stand_alone(true),goal(Goal)]).


% test.plの場合、load(test).でプログラムがロードされる

load(Program) :-
concat(Program,'.pl',Pro),[Pro].
354デフォルトの名無しさん:2006/01/08(日) 01:40:14
% Windows環境のSWI-Prologで作動(XPで動作確認)
% SWI-Prologのプログラムをコンパイルする。load/1でプログラムを
% ロードし、qsave_program/3でコンパイル
% test.pl、ゴールがmain/0の場合cpl(test,main)とすればコンパイルをする
% 実行ファイルtest.exeが生成される
% 実行ファイルがあるフォルダにpthreadVC.dll plterm.dll libpl.dllが必要
% pthreadVC.dll plterm.dll libpl.dllはSWI-Prologのbinフォルダにあります
compile_pl(Program,Goal) :-
load(Program),
qsave_program(Program, [goal(Goal), stand_alone(true)]).

load(Program,Pro) :-
concat(Program,'.pl',Pro).
355デフォルトの名無しさん:2006/01/08(日) 02:58:48
% 354訂正
% Windows環境分
% SWI-Prologのプログラムをコンパイルする。load/1でプログラムを
% ロードし、qsave_program/3でコンパイル
% test.pl、ゴールがmain/0の場合cpl(test,main)とすればコンパイルをする
% 実行ファイルtest.exeが生成される
% 実行ファイルがあるフォルダにpthreadVC.dll plterm.dll libpl.dllが必要

cpl(Program,Goal) :-
load(Program),
qsave_program(Program, [goal(Goal), stand_alone(true)]).

load(Program) :- atom_concat(Program,'.pl',Pro),[Pro].
356デフォルトの名無しさん:2006/01/08(日) 03:15:57
Windows環境下SWI-Prologの場合、カレントフォルダに、pl.iniの名前のファイルに自作の述語を書いておけばSWI-Prologを起動したときに
それらの述語が自動的にインタープリタに追加されますが、少し作動がおかしいみたいです。私の環境だけかもしれませんが。Linux環境では
./plrcがpl.ini相当しますが、Linux環境の方が安定して動作するようです。
357デフォルトの名無しさん:2006/01/08(日) 15:00:38
356訂正
./plrc は .plrc に訂正
358デフォルトの名無しさん:2006/01/12(木) 11:07:44
>>329
LISP系などはすこし近いと思うのですが、
言語観が他のプログラム言語と少し違う気がする。
身長(尾崎,168).
は、Prologプログラマにとって大事なプログラムであり、
このようなプログラムを自らの環境にできるだけたくさん、
永続的に維持したい願う。ひとかけら、ひとかけらが
独立した貴重なプログラムという感覚。
この部分が一番の違いであり、特徴といってもいいのではないか。
359デフォルトの名無しさん:2006/01/12(木) 11:10:09
>>327 にリンクすべきでしたね。
360デフォルトの名無しさん:2006/01/12(木) 21:23:16
Hello World から始めるProlog初心者はいない、ということだな。
361デフォルトの名無しさん:2006/01/12(木) 22:28:50
Prolog初心者の第一歩は ?- mortal(socrates). から。
362デフォルトの名無しさん:2006/01/13(金) 00:23:41
no

?-
363デフォルトの名無しさん:2006/01/13(金) 07:56:36
*** E X C E P T I O N: existence_error(procedure,mortal / 1)
>>> goal = user : mortal(socrates)

no

[user] ?-
364デフォルトの名無しさん:2006/01/13(金) 08:01:55
>>361 私の環境だと、Backspace3回の後
mortal(socrates).
365デフォルトの名無しさん:2006/01/13(金) 08:17:20
悪ふざけを続けてしまった。

語彙一つがプログラムという感覚は、引数一つ追加、削除するのにも
「惜しみ、惜しみ」という態度になり、
プログラムとは形式的にこういうもの、という感覚の言語とは
違うように思う。
Prologというと、定理証明、反駁、導出原理、単一化、などばかり、
そういう側面ばかり強調されてきたが、私にはこのような感覚の方
が大事に思える。
プログラムエラーを減らす最大の要因だから。
366デフォルトの名無しさん:2006/01/13(金) 15:01:00
Prolog使いにしては論理性に欠ける展開だな
367デフォルトの名無しさん:2006/01/13(金) 16:14:06
うーん。
>>358 >>365 確かに説得力に欠ける。ただ、
オブジェクト指向には差分プログラミングを
貫くぞという意志というか、態度表明のような
ものを感じる。だからつよい。

私が書いてみたのはそれに対する相聞。
368デフォルトの名無しさん:2006/01/13(金) 16:40:46
雪は白い。 太郎は人間である。
をほとんどのPrologプログラマは共通して、

白い(雪).
人間(太郎).

と書く。このプログラムをPrologを知らない人も
捨象された部分を補完して、
雪は白い。 太郎は人間である。 と読む。

この関係が成立する言語はそうそうあるものでは
ないのだから、そこを大事に考えようということ。
369デフォルトの名無しさん:2006/01/14(土) 23:18:04
prologって人工知能言語が強調されるけど、汎用言語として使える。
370デフォルトの名無しさん:2006/01/15(日) 11:56:54
今更Prologってなぁ。。
371デフォルトの名無しさん:2006/01/15(日) 13:10:04
どんな個人史を以て今更なのか、興味。
372デフォルトの名無しさん:2006/01/16(月) 23:17:27
|д゚) 知識ベースに情報が蓄えられればきっと居場所が分かる・・・分けないか・・・

【携帯】2ちゃんねら娘が行方不明のようだがスレ【専用】2

ttp://ex14.2ch.net/test/read.cgi/news4vip/1137416634/l50
373デフォルトの名無しさん:2006/01/20(金) 10:28:01
私は、データモデルとか全く考えずに、反射的に述語にしてしまう。

性別('女').
名前('かよ').
年齢('14歳').
髪型('おかっぱに近い髪形(少し茶色がかっている)').
身長('157センチ').
目('少し垂れ目で二重').
眉毛('困った感じになっている').
輪郭('丸顔').
口元('最近出来た茶色のシミのようなものがある').
頬('赤いニキビがある').
服装('黒いフードつきジャンバー(白いラインが一本腕から背中に入っている)').
服装('黒いジーンズ、青いスニーカー').
特徴('左腕に大きな蒙古班(もうこはん)に似たようなアザ').
特徴('話すときに自分の名前を言う').
趣味('2ちゃんねる閲覧').
自宅('神奈川県川崎市中原区').

これじゃ、まずいな。とそれから考える。
374デフォルトの名無しさん:2006/03/04(土) 20:03:27
>自宅('神奈川県川崎市中原区').
中原か。
不夜城の脇の連中か。
375デフォルトの名無しさん:2006/03/04(土) 21:25:44
上がってきてしまった。役に立つプログラムにするには、

:- op(850,xf,だ).
:- op(700,xfx,は).

性別 は '女' だ.
名前 は 'かよ' だ.
年齢 は '14歳' だ.
髪型 は 'おかっぱに近い髪形(少し茶色がかっている)' だ.
身長 は '157センチ' だ.
目 は '少し垂れ目で二重' だ.
眉毛 は '困った感じになっている' だ.
輪郭 は '丸顔' だ.
口元 は '最近出来た茶色のシミのようなものがある' だ.
頬 は '赤いニキビがある' だ.
服装 は '黒いフードつきジャンバー(白いラインが一本腕から背中に入っている)' だ.
服装 は '黒いジーンズ、青いスニーカー' だ.
特徴 は '左腕に大きな蒙古班(もうこはん)に似たようなアザ' だ.
特徴 は '話すときに自分の名前を言う' だ.
趣味 は '2ちゃんねる閲覧' だ.
自宅 は '神奈川県川崎市中原区' だ.
376デフォルトの名無しさん:2006/03/04(土) 23:23:27
これが何の問題解決の役に立つの?
377デフォルトの名無しさん:2006/03/05(日) 04:44:26
内容はともかく、テキストを参照可能な情報へ変換するのに
必要な極小の知識とは、という話だから。
この場合、" は "の挿入と" だ."の付加でよいということ。
それから"'"を使ってアトムとしての形式を確保していることかな。
378デフォルトの名無しさん:2006/03/05(日) 04:57:25
>>375 の情報のほかに
・・・
山田かよ の 現在の所在地 は 東京都杉並区 だ.
山田かよ の 趣味 は '2ちゃんねる閲覧' だ.
山田かよ の 自宅 は '神奈川県川崎市中原区' だ.
・・・
・・・

が定義されていたような場合に、

尋ね人は山田かよで、現在東京都杉並区にいる。
その確信率は45%というような解を導く述語の
定義が可能だろう。
379デフォルトの名無しさん:2006/03/06(月) 07:59:44
>>375 >>378 のように述語として定義してあれば、
単純にPrologで参照することはもちろんだが、
この述語を参照して、SQLのinsert文を生成して
実行するProlog述語を作ったり、C++のソースに
変換する述語を定義することが、次の展開となる。

このような非形式的な仕様からのプログラム生成は
大規模なシステム開発には向かないが、
スモールビジネスでのプログラム開発には有力と
思われる。
380デフォルトの名無しさん:2006/03/12(日) 23:02:07
http://meisou.com/books_data/00050/00050.htm#honbun
>私自身、PROLOGという論理型の人工知能言語による建物診断システムの開発に従事した事がある。
>大学ではFORTRANという科学技術計算用プログラム言語を習ったが、PROLOGは、
>FORTRANとは、まるで概念が違うコンピューター言語だ。私がこの人工知能言語に始めて接した時
>に大きな戸惑いがあった。FORTRANは原則として上から下という分かり易い流れでプログラムが
>処理される。プログラムは殆ど計算式そのものといった感じだ。数式をほぼそのまま当てはめていけば
>完成する。
> ところが、PROLOGは科学技術の要素はあまり無く、どちらかというと哲学に近い感じがする
>コンピューター言語だ。しかも、どこが始まりで、どこが終わりなのかよく分からない奇妙な
>プログラム言語でもある。微分積分といった高度な計算より、人間の勘や経験を必要とする分野に
>向いている。この点が理工系に偏った日本の技術者にとって容易に使いこなせない要因になりそうだ。
>特に工学部出身者だと、持て余すだろう。

さすがに頭も古いってことか。7年前とはいえ、この程度の古い上辺だけのしかも間違った知識で
人工知能の研究家??

【自称】知られざるある作家の真実【地上最強最優秀】
http://science4.2ch.net/test/read.cgi/doboku/1137900994/435,436

 投稿日 2000年8月2日(水)23時21分 投稿者 古舘真    delete

 今や向かうところ敵なしの地上最強最優秀の評論家になりつつある私ですが、
ここで現在執筆中の「DV通説への疑問」(仮題)を特別に皆様に披露いたします。
何回かに分けて掲載する事に致します。
381デフォルトの名無しさん:2006/03/13(月) 17:55:19
 企業の経営者にとっては、外国からの「日本人は働きすぎだ」という批判が気に食わない人がたくさんいる。
欧米から非難されると、「文化の違いによるものだ」、「根底に人種差別がある」、「内政干渉だ」などと反発して、過酷な労働条件をなかなか改めようとしない。
経営者は社員をできるだけ長時間低賃金労働させたいと考えるのが普通だから、それは当然かもしれない。
しかし、労働基準法は企業に対して弱い立場にある労働者を守るためにある法律なのだから絶対に守らなければならない。
「内政干渉だ」などと欧米の主張に反発する前に、経営者は自分の国の法律を守るべきだ。
もし、現行の労働基準法に間違いがあるのなら直ちに改めるべきだ。
やるべき事をやらないで、欧米が主張する正論に対して反発するのは筋違いだ。


↑この部分だけは禿げ上がるほど同意.
382デフォルトの名無しさん:2006/03/13(月) 23:25:27
暇だ〜〜。よしprologの勉強をしよう。まずは381のカキコをホーン節に落とすぞ。
まずは述語論理で表す。

企業の経営者にとっては、外国からの「日本人は働きすぎだ」という批判が気に食
わない人がたくさんいる。

集合
企業の経営者∋x
批判∋y

論理式
CEO(a) 経営者である。
CriticismFromForeignCountry(a)外交からの批判
JapaneseOverWork(a)日本人は働き過ぎという批判。
DontLike(a,b)aはbを嫌い。

∃y∃x((CriticismFromForeignCountry(y)∧JapaneseOverWork(x)) -> (DontLike(x,y) ∧ CEO(x)))
TextSS のWindowsXP(Professional)64bit化おながいします

もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?

そういや64bitにネイティブ対応している2chブラウザてありましたっけ?

384デフォルトの名無しさん:2006/03/19(日) 09:04:57
http://ja.wikibooks.org/wiki/C%E8%A8%80%E8%AA%9E
>C言語(に限らずプログラム言語全般だが)とは、命令の羅列だといったが、命令とは一体どんなものなのでしょうか?

さらっとPrologは無視されましたなww
385デフォルトの名無しさん:2006/03/28(火) 01:34:14
SWI-Prolog 5.6.8 の Windows 版で Prolog をはじめてみました。
日本語を入力すると、日本語が重なって表示されてしまい困っています。
フォント設定を変えても変わりませんでした。
どうすればよいでしょうか。
386デフォルトの名無しさん:2006/03/29(水) 18:31:29
>>385
Windowsを使うことはほとんどないので、
この環境では安定した環境を作るプログラムが揃わず、
使いこなせないのですが、ともかく、最新版5.6.9を
インストールしてみました。
XPでShift-JISだと、plwinのウィンドウ内だと
正常に表示されています。UTF-8で動かしたかったのですが
どうすればよいかわかりません。
387デフォルトの名無しさん:2006/03/29(水) 18:48:32
現在、TeraTermでTelnet接続し、plconを起動して、
動かしていますが、正常に表示されますね。
388デフォルトの名無しさん:2006/04/03(月) 08:24:56
Aからzまで頭文字が全部揃っていると言われるPrologだが、
処理系の移行が難しい点でも横綱級。

ISO規格を基礎に、それ以外の組み込み述語には
かならずソースコードの付加を義務付けるように
したいものだ。
ほとんどのものが放置処理系だから、実際には
これから開発する処理系が対象となるのかも知れないが。
389デフォルトの名無しさん:2006/04/03(月) 20:50:20
組み込み述語の差程度ならまだなんとかなるが、
型の有無、副作用の可否の壁は厚い。
390デフォルトの名無しさん:2006/04/03(月) 22:24:04
>型の有無、副作用の可否の壁
これは、どういう処理系と処理系の間で
起こっていることですか。
391デフォルトの名無しさん:2006/04/18(火) 05:43:39
最近流行のHaskellは
ややこしいPrologって感じがする
392デフォルトの名無しさん:2006/04/18(火) 14:45:40
>>391
ぜんぜん違う
どちらも理解してないだろw
393デフォルトの名無しさん:2006/04/18(火) 15:21:43
私はHaskellはほとんど知らないのだが、遅延評価があると聞いた。

事務処理屋でProlog=データベースという使い方がほとんどで、
データベースの参照順序を、できうるならば
datebase(A,B,C,X), ・・・ ,hoge(_1,A),hoge1(_2,B),hoge2(_3,C), ・・・
と書きたい。これでA,B,Cの具体化を待ってdatabase(A,B,C,X)を実行したい。
Prologでこれが可能になる見込みはないかな。
394デフォルトの名無しさん:2006/04/19(水) 01:52:48
>>391
Haskellは一方向

Prologは双方向
395デフォルトの名無しさん:2006/04/19(水) 01:54:02
>>393
Prologって左から試していくんじゃなかったけ?
396デフォルトの名無しさん:2006/04/19(水) 05:45:27
dababaseの定義が

database(%U,%Y,%Z,X) :- ...だと

U,Y,Zが具体化(変数でない)されるのを待つというような
仕様にならないものか。
397デフォルトの名無しさん:2006/04/19(水) 05:49:28
これだとデータベース述語に方向性が発生するから
あくまでview述語としての定義かな。
view(%A,%B,%C,X) :- database(A,B,C,X).
のような定義をして、
database(A,B,C,X)の代わりに
view(A,B,C,X)で照会にいく。
398デフォルトの名無しさん:2006/04/19(水) 05:57:58
>>393の参照は
5000節ならへーチャラだけど500000節になると
考えてしまう。
399デフォルトの名無しさん:2006/04/19(水) 05:59:03
もちろんdatabase()の定義節の数ね。
400デフォルトの名無しさん:2006/04/20(木) 09:13:16
>>393 以降まとめ。
Prologも遅延実行のオプションがあるといいな。

データベース述語を引数に遅延実行項をかいて、
待たせると、この述語の参照方法が限られて
しまうから、view述語を別に定義してここに
遅延実行項を書くことで、処理系に特殊な
評価を必要とする副目標であることを伝えればよいだろう。
view述語を別に切るのは煩わしいけれど、
実務ではデータベース述語が20引数、などということも
珍しいものではない。このような場合view述語は
どうしても書くことになるから、それほど問題にはならない。

>>393 >>397 でdatabase() view()としたがこれは勿論、
実際には
?- 売上(A,B,C,X), ...
売上_vew(%A,%B,%C,X) :- 売上(A,B,C,X).
のように書かれることを意味している。
401デフォルトの名無しさん:2006/04/21(金) 09:17:14
>>393 >>397 >>400
いくつか理解できない事があるので質問。
・副目標databaseが左に出てくるのは何故。
一番最後でもよいのでは。
・副目標databaseを最終的にはviewに書き換える
必要があるなら、databaseの位置を左から右に移したら?
・遅延実行するなら、負節に
database(%A,%B,%C,X),hoge1(_1,A),hoge2(_2,B),
のように遅延実行指示項を書く仕様でよいのでは?
402デフォルトの名無しさん:2006/04/21(金) 11:59:32
>>401
大原則として、既にあるプログラムをできるだけ
変更したくない。
遅延実行指示も条件部(負節)で行うとコードの
書き換え箇所が広範囲に及び可能性が高い。

それから、この話は、SQLの仕様が面白くないから、
Prologでデータベースの照会を済ませたらという
話に端を発しており、できるだけ自由かつ柔軟な
仕様を指向しています。
SQL<->Prolog双方向の変換を考えます。
既にSQLで書かれたコードのProlog変換に於いて、
逆にPrologのコードからSQL文を生成するにしても、
遅延実行可能でどこからでも懸念なくPrologの
データベース参照ができる仕様が好ましいと
考えたわけです。
403デフォルトの名無しさん:2006/04/24(月) 14:51:22
select 繰越残高 into X from 売掛 where 顧客番号='11111' and 締日='20060331';
のようなSQL文を
売掛(_顧客番号,_繰越残高,_,_,_,_締日),顧客番号取得(_顧客番号),締日取得(_締日),
でも
顧客番号取得(_顧客番号),締日取得(_締日),売掛(_顧客番号,_繰越残高,_,_,_,_締日),
と同じようなパフォーマンスを得たいということですね。
404デフォルトの名無しさん:2006/04/25(火) 00:02:45
>>402
Prologプログラマは、SQLの何が不満なのですか。
405デフォルトの名無しさん:2006/04/25(火) 06:26:00
ひとつ。group by句
406デフォルトの名無しさん:2006/04/25(火) 13:13:37
位置ですか? from句の前か後にあるべきだという主張は
よく耳にしますが。
407デフォルトの名無しさん:2006/04/25(火) 13:44:36
そういことではありません。
テーブルから部分集合を切り取ることと、
その部分集合に対し集約演算を施すことは
表現上完全に分離するべきだと考えます。
RDBSのなかでこれが最適化されて、Tupplesの
ハンドリングと集約が同時に処理されて
高速化されることは結構なことですが、
SQLがせっかく集合の直積上の部分集合を
切り取るという単純な命令なのですから、
その解りやすさをSQLはできる限り維持すべきです。
group by句が射影部分照応して集約解が得られる
という現在の仕様はほとんどのSQLユーザに
とって理解しにくく、後に述べてみたいと思いますが
集約演算の発展をも閉ざす結果になっています。
408デフォルトの名無しさん:2006/04/25(火) 13:46:16
射影部分照応して -> 射影部分に照応して
409デフォルトの名無しさん:2006/04/25(火) 14:10:49
>>402 で言いたかったことのひとつは

データベースの参照,集約演算, が連接してしかも、
どんな順序でも同じ結果が得られる、そんな
制約論理型言語がいいな、と言うことです。
先程述べたように、SQLの仕様がいいとは思って
いませんが、結果として、このような自由な
表現が、SQL文
select ... from .. where .... group by ...
に変換されてデータが探査され集約されたとしても
少なくともこのような窮屈なSQL文を書かなくて済みます。
410デフォルトの名無しさん:2006/04/25(火) 22:18:36
学校の宿題がわからないんですけど、どなたか教えてもらえます?
「自然数から自然数への関数 t を t(x)=x+1 とする。
 自然数を 0,1,2,…と表現する方法を A とし、
 0→0
 1→s(0)
 2→s(s(0))
 3→s(s(s(0)))
 と表現する方法を B とする。A から B へ変換する述語henkan(A,B) を定義しなさい。
 例:henakn(2,X)は X=s(s(0))を返すようにする。」
411410:2006/04/25(火) 22:25:03
>>410
ごめんなさい。最後の行
×henakn(2,X) → ○henkan(2,X)
です。
412デフォルトの名無しさん:2006/04/25(火) 22:28:32
>>407 で書いた集約演算の発展と言うことですが、
例として、部、課だけからなる木構造の組織を考えます。
部,課,人数
小売,営業,6
小売,購買,2
卸売,営業,2
卸売,購買,1
ちょっと単純すぎますが。ここで集約キー候補は
[部,課]-[部]-[]が考えられます。
キーが[]の時は実は全社というようなキーが実はあります。
そのほか[課]だけが集約キーになることもあります。
413417:2006/04/25(火) 22:31:03
>>412
すみません。原稿を書き出した途端なぜか、
送信されてしまいました。無視してください。
マウスにもさわってないのですが。
414デフォルトの名無しさん:2006/04/25(火) 22:46:32
>>410
可能な限り仕様どおりに書くのがPrologプログラミングです。
第一引数に数字が来たとき(表現A)、第二引数に表現Bが来るのですから、

henkan(0,0).
henkan(1,s(0)).
henkan(N,s(X)) :- integer(N),N>1, ? , ?.

? は君が考えてください。

普通はinteger(N),N>1,は省略します。私はできるだけ書くように
しています。
415410:2006/04/25(火) 23:30:06
>>414
ありがとうございます。3行目を
henkan(N,s(X)) :- N1 is N-1, henkan(N1,s(s(X))).
としたのですが、うまくいきません。
どこがまずいですか?
416デフォルトの名無しさん:2006/04/25(火) 23:36:26
頭部(左側)にくるXはs(X)よりsがひとつ少ないのですよ。
N1の第二引数はNよりsが一つ少ない表現Bですよね。
ならば・・・。
417デフォルトの名無しさん:2006/04/26(水) 00:01:39
henkan(N1,?)
N1と等価なものがひとつあります。
418410:2006/04/26(水) 00:36:47
>>416>>417
できました!ありがとうございました!
419デフォルトの名無しさん:2006/04/26(水) 01:26:15
関数型はやりだしたみたいだけど,いつになったら論理型言語流行るんだろうな。
Prologでコンパイラ作るの楽しいんだが。
420デフォルトの名無しさん:2006/04/26(水) 06:33:41
>>407
>SQLがせっかく集合の直積上の部分集合を
>切り取るという単純な命令なのですから、
>その解りやすさをSQLはできる限り維持すべきです。

言わんとするところはSQLじゃなくてSelect文、かな?
集計までSelect構文に含めるべきではなかった、というのは分からんでもない。

でも>>407〜409の書き方だと
「group byの書き方はめんどくさくてワシには分からん!どうせ皆もそうだろうが!」
というような一部のO/Rマッパーの尖がった主張みたいに読めてしまうのが
ちょっと遺憾に思えます。
421デフォルトの名無しさん:2006/04/26(水) 10:10:26
私の発言には関数型は窮屈だから、ゆとりのある論理型の方がよい的な
好みとしか言い様のない部分を含むことは否めません。それはそうとして、
group by句については位置を改善できれば初心者にも取っつきやすくなるでしょう。
問題は、
select 数量,count(*) from 売上 group by 数量; このような場合は希で、
ほとんどの集約キーは構造を持っているということです。
select 部,課,係,sum(金額) from 給与 group by 部,課,係; のように。このような参照は
select 部,課,sum(金額) from 給与 group by 部,課;
select 部,sum(金額) from 給与 group by 部;
select sum(金額) from 給与; 何故かgroup by句がなくなってしまう!
勘定系などではこれらは常に一体として参照されるものでこれを逐次別々に
計算する現在のselect tableの仕様には疑問を感じます。viewと同様な位置づけで
部,課,係 部,課 係 をそれぞれ一意名を再定義し、部,課,係に構造名を与えれば、
この集約演算は一命令で済むはずです。
422デフォルトの名無しさん:2006/04/26(水) 11:13:56
集約計算については、予算の総額を与えて、それを
現在値を基礎に部,課,係に配分する割り算や、
条件を与えて、集約値を分解すること、集約キーの
接ぎ木など豊かな可能性を秘めており、これらを現在の
select talbae + group by句で表現するのは無理が
あると思います。
423デフォルトの名無しさん:2006/04/26(水) 11:19:05
集約計算 -> 集約演算
select talbae -> select table
に訂正します。
424デフォルトの名無しさん:2006/04/26(水) 12:27:13
誰か、SICSTus Prologのスタックサイズ変更の仕方しらないですか?
メモリ不足で結果が出ないんだが、サイズ変更のやり方がわからない。

マニュアルにこんな文はあるんだが、どこ探しても見つからない・・・。

3.1.1 Environment Variables
The following environment variables can be set before starting SICStus Prolog. Some of
these override the default sizes of certain areas. The sizes are given in bytes, but may be
followed by ‘K’ or ‘M’ meaning kilobytes or megabytes respectively.
icates the pathname where temporary files should be created. Defaults
to ‘/usr/tmp’.

GLOBALSTKSIZE
Governs the initial size of the global stack.
425424:2006/04/26(水) 12:27:44
すいません、下げ忘れました。
426デフォルトの名無しさん:2006/04/26(水) 15:46:43
>>424
global stackのサイズを変更したければSICStus Prologを起動する前に
環境変数 GLOBALSTKSIZE にglobal stackのサイズを設定しておくってことだろ。
GLOBALSTKSIZE がなければ作ればいい。

> LOCALSTKSIZE
> Governs the initial size of the local stack.
>
> CHOICESTKSIZE
> Governs the initial size of the choicepoint stack.
>
> TRAILSTKSIZE
> Governs the initial size of the trail stack.

この三つも同様。

Windows/環境変数の設定
http://kawacho.don.am/wiki/pukiwiki.php?Windows%2F%B4%C4%B6%AD%CA%D1%BF%F4%A4%CE%C0%DF%C4%EA#content_1_0

Linux Tips 環境変数を設定するには
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/118setenv.html
427424:2006/04/26(水) 15:51:19
>>426
ありがとう!
できた!
428デフォルトの名無しさん:2006/05/01(月) 00:58:18
system述語について、
処理系ごとに使い勝手を教えてください。
429デフォルトの名無しさん:2006/05/01(月) 14:47:26
IF/Prologの場合
system(+Command)
system(+Command,?ExitStatus)
system(+Command,?Input,?Output)
system(+Commane,?Input,?Output,?Error,?Pid)
の4種類ある
我々が期待することは出力の各行を要素とするリストが出力モードの引数に単一化されることだ。
system/1-4は組込述語として使用済みだから、別に述語shs/2を定義します。

shs(Command,X) :- tmpnam(TmpFile),
concat_atom([Command,' >',TmpFile],S),
system(S,user_input,TmpFile),
open(TmpFile,read,Input),
findall(U,(repeat,get_until(Input,'\n',U,EndStatus),(U='',EndStatus=end_of_file,!,fail;true)),X),
close(Input),
unlink(TmpFile),!.

ここではC言語インターフェイスで定義したCで書かれた述語tmpnam/1,unlink/1
使用されています。これがない場合、システム上でユニークであること
保証されるファイル名をassert、retractしながら管理する必要があります。
430デフォルトの名無しさん:2006/05/01(月) 15:13:15
ユニーク名は
?- ..., Time is time,getpid(Pid),getppid(PPid), ...
で得られるTimeとPidとPPidの組み合わせで作ります。
431デフォルトの名無しさん:2006/05/09(火) 17:38:45
SWI-Prologの最新版をインストールしてみました。
Version 5.6.12 です。

驚くべき事に、日本語処理が完全になされていました。
?- assertz((古今和歌集(_歌人,_歌) :- 千人万首(古今和歌集,_歌人,_歌ならび),member(_歌,_歌ならび))).

_歌人 = _G180
_歌 = _G181
_歌ならび = _G185

Yes
?-
ただし、Windows版(plwin)では >>385 に指摘された文字とカーソルの
ズレがひどく快適とはほど遠いようです。カーソルが漢字2文字に
対して、ascii3文字分しか移動しないようです。
432デフォルトの名無しさん:2006/05/09(火) 18:36:59
カーソルが6バイト分先に進んでいるとの
認識なのでしょうか。それを4バイトに調節して、
つまり
?- _カーソル変位 is _実際のバイト数 * 2 // 3 + 1.

になっているような気もします。
433デフォルトの名無しさん:2006/05/09(火) 20:18:45
すいません、学校の宿題で、一応プログラムは出来たのですが、
正しいかどうかどなたか判定していただけますか?
よろしくお願いいたします。
「Term ::= Alphabet | Integer | f(Term) | g(Term,Term)
 Alphabet ::= a | b
 Integer ::= 0 | 1
 という文法の定義に対し、与えられた表現が項(Term)か否かを
 判定する述語isTermを定義せよ。」
この課題に対し、私が作ったプログラムがこれです。

isTerm(a).
isTerm(b).
isTerm(0).
isTerm(1).
isTerm(f(X)) :- X is 0.
isTerm(f(X)) :- X is 1.
isTerm(f(X)) :- X = a.
isTerm(f(X)) :- X = b.
isTerm(f(f(X))) :- isTerm(f(X)).
isTerm(g(X,Y)) :- isTerm(X), isTerm(Y).
isTerm(g(g(X,Y),g(Z,W))) :- isTerm(g(X,Y)), isTerm(g(Z,W)).

適切なアドバイス等よろしくお願いいたします。
434デフォルトの名無しさん:2006/05/09(火) 21:11:31
何で alphabet とか integer とかを定義しないのか理解できない。
435デフォルトの名無しさん:2006/05/09(火) 21:33:31
問題に書いてある定義通りに書けばいいだけなのに、
何でそんなに色々いじろうとするのかが分からない。
436デフォルトの名無しさん:2006/05/09(火) 21:45:24
とりあえず、 f(g(X,Y)) みたいなパターンが抜けてると思う。
437デフォルトの名無しさん:2006/05/09(火) 21:49:59
つーか、そんなパターン要らない。
そんなん無くても書ける。
438デフォルトの名無しさん:2006/05/09(火) 22:13:31
めんどくさいから、私のプログラムを見せます。
可能な限り、仕様を写すようにプログラミングするのが
Prologです。

isTerm(Alphabet) :- isAlphabet(Alphabet).
isTerm(Integer) :- isInteger(Integer).
isTerm(f(Term)) :- isTerm(Term).
isTerm(g(Term1,Term2)) :- isTerm(Term1),isTerm(Term2). /* 注1 */
isAlphabet(a).
isAlphabet(b).
isInteger(0).
isInteger(1).

/* 注1 BNF記法などの通例から isTerm(g(Term,Term)) :- isTerm(Term).
の意味ではないと思う */
439433:2006/05/09(火) 22:16:31
>>434-437
たくさんのご指摘ありがとうございます。
具体的にどこをどう直せばよいのかお教えいただけますか?
440デフォルトの名無しさん:2006/05/09(火) 22:17:21
あーあ・・・。
つーか、is って接頭辞は必要なのか?
441デフォルトの名無しさん:2006/05/09(火) 22:22:20
いや、integer/1が組込にあるからw
442433:2006/05/09(火) 22:25:03
>>438
ご丁寧にありがとうございました。
重ねて
>>434-437
の方々もありがとうございました。
解決しました。
443デフォルトの名無しさん:2006/05/09(火) 22:27:56
>>442
何でそれでいいかくらい考えとけよ。
444438:2006/05/09(火) 22:33:47
順を追って進めるべきでせっかくの学習(機会)を
壊してしまったかも知れない。

私は、Prologのプログラムは仕様を正確に
写すだけと思っているし、人にもそう教えて
きた。知恵を働らかせるのも大事なのですが、
プログラミングスタイルを感じることも大事
だと思い、敢えてプログラムを載せました。
445デフォルトの名無しさん:2006/05/09(火) 22:35:36
うーん。まあ分からんくもないけど、
写して終わりでいいやーという人だったら
意味ないなー、と。
446デフォルトの名無しさん:2006/05/09(火) 22:42:12
>>445
まあ、仕様がしっかりしている場合だけどね。

言語的な理解に沿ってプログラミングすると
いうのが私の考え方かな。言語的に咀嚼できない
クイズみたいなのは苦手。
447デフォルトの名無しさん:2006/05/09(火) 22:47:53
質問者に関しては、
こういうところで質問してくるだけで結構だと。
なにか、興味とか新鮮さみたいなものを与えて
あげられれば、(いいな)くらいかな。
448デフォルトの名無しさん:2006/05/11(木) 08:27:39
【言語】おすすめの言語ってなんでしょう【初心者】
http://pc8.2ch.net/test/read.cgi/tech/1124600090/

ここ↑のスレ見ました。
何をしたらいいですか?
教えてください。
449デフォルトの名無しさん:2006/05/11(木) 08:57:03
ぐぐれ
450デフォルトの名無しさん:2006/05/11(木) 09:01:44
検索してもみつかんないからここで聞いてるの
はやく誰かおしえろ
451デフォルトの名無しさん:2006/05/11(木) 09:05:37
馬鹿には無理
452デフォルトの名無しさん:2006/05/11(木) 09:07:50
馬鹿じゃないよ大学生だよ
453デフォルトの名無しさん:2006/05/11(木) 09:10:13
       _,.._,.=-_-、
      ,r;r '´     `ヽ
    ,r:i'          ヽ
   /::::;!           ヽ
   ;!:::::::'! .,     _   _,.......i:、
  ;i:::::::::::::l.  ,;r''_:::::'' ::r_;ニ;.:l:::i
  r'::::::::::::r   "'"`=';' '  i:::`;::::l:;!
 /::::::::::r:ミ ;::::.   ´'´ r  )´ '::l!
 !::::::::::::、_,.::::::    /.:::::::::ヾ、.::l
  ヾ:::;、::::!::::::. ..::' ';':::::::::::::::::ヽl!
   `  ヾi ::::::ミ:、-':::::;:r―::、:::ij;!
     ,.r!i  ミ::_;::::''::::::::::::::;r/::`::::-.、
  ,...-:::::::::/ `r、__,-―--‐'´ /::::::::::::::::::::::..、
:::::::::::::::i'' ー-'r--r.、´ヽ   /::::::::::::::::::::::::::::::::`::、

 ググ・レ・カス [Gugu Re kasu]
  ( 1541〜 1625 ギリシャ )
454デフォルトの名無しさん:2006/05/11(木) 09:14:05
現在最も広く使用されかつ、日々発展しているProlog処理系は
アムステルダム大学のグループによるSWI-Prologです。もちろん
オープンソースでWindows版、Mac版、Linux版が揃っています。
http://www.google.co.jp/search?hl=ja&q=SWI-Prolog&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=
ともかくDownloadしてみてください。
455デフォルトの名無しさん:2006/05/11(木) 09:21:06
ごめん、Linkをまちがえた。
http://www.swi-prolog.org/
456デフォルトの名無しさん:2006/05/11(木) 10:18:28
Prologの啓蒙書としては

1.. 「楽しいプログラミング2 記号の世界」 中島秀之・上田和紀 共著 岩波書店
2.. 「Prologを学ぶ」 杉崎昭生 著 海文堂
3.. 「PrologとAI」 I.Bratko 著 阿部憲広 訳 近代科学
4.. 「Prologの技芸」 L.Sterling E.Shapiro 共著 松田利夫 訳
共立出版

などが良いと思います。どれもAmazonから入手可能だと思います。
1..の"2"はアラビア数字です。
457デフォルトの名無しさん:2006/05/11(木) 11:02:58
>>456
この中だと私は
2.. をお勧め。
458デフォルトの名無しさん:2006/05/11(木) 11:22:30
Prologの技芸の日本語訳って絶版じゃなかったっけ?

459デフォルトの名無しさん:2006/05/11(木) 11:54:33
>>458
確かに。
極めて遺憾であります。
460デフォルトの名無しさん:2006/05/11(木) 13:16:44
>>448
これから、週一回くらいのペースで寺子屋「Prolog」を開店します。
第一回は今週の土曜日。テーマは「repeatとmemberについて」

こういうのなかなか手が着けられなくてプレッシャーになるんだよね。
461デフォルトの名無しさん:2006/05/11(木) 14:29:11
友人がPrologという名前が悪いというから寺子屋「ふろく」に改名します。
私は土曜の夜までに書き上げますが、私以外にこのテーマで
書きこんでくださる方がいらっしゃることを期待します。
462デフォルトの名無しさん:2006/05/11(木) 19:27:36
>>448 >>456
Prologだけの本ではありませんが、最もよい本だと思います。
これも絶版なので図書館で探してください。

岩波講座 ソフトウェア科学 14巻 「知識と推論」 長尾真 著 岩波書店
463462:2006/05/11(木) 19:30:52
訂正。
絶版ではありませんでした。Amazonで即、買えます。
464デフォルトの名無しさん:2006/05/12(金) 11:57:44
>>448
2000年以前にPrologを主なテーマとして出版された邦書の一覧は
http://nojiriko-prolog.com/prolog_book.html
465デフォルトの名無しさん:2006/05/13(土) 06:55:46
>>464
一番重要な書籍が抜けているとの指摘がありました。

'prolog書籍'('Prologプログラミング','',['W.F.Clocksin','C.S.Mellish'],'中村克彦'
,1983 / 6 / 25,マイクロソフトウェア,'').
466デフォルトの名無しさん:2006/05/13(土) 09:47:21
再び「雪は白い」問題について、
"おすすめの言語"スレでやってた問題ですが、雪は白いに対し
白い(雪).
というプログラムを書いたということは、
1.. 雪は白いを [雪,は,白い]と形態素解析した
2.. はを省略した
3.. 雪を主部、白いを述部と見なした。
これだけのことはしている。
我々は雪、と、白い、から、色の情報だな、感じてしまう。
それが支えにあるからスムーズに形態素解析ができる。
それなら
class 雪 { 色 = 白い;} // Java or C++
class 雪: 色 = 白い # Python
でもたいした差はない、という意見はわかる。

ただ、真っ暗闇の虚無の世界に「雪は白い」を定義してください、
といわれて、色という情報を付加するのはいかがなものか。
雪と白いという記号を()で括りながら併記することによって「は」を
解釈したという所止まりにしたいと思うのだが。
467デフォルトの名無しさん:2006/05/13(土) 12:03:27
寺子屋「ふろく」第一話 repeatとmember (その一)

repeat/0とmember/2を同時が同時に論じられることは意外と少ない。
私は10年くらい前このテーマで講習会を一日がかりでやった。
もしかするとこれが最初で最後かも知れない。
結果は失敗だったので再挑戦ということになる。

最初に形式から比較しよう。構造は似ている。だから比較してみたくなる。
repeat.
repeat :- repeat.
member(A,[A|_]).
member(A,[_|R]) :- member(A,R).
memberにはrepeatにない引数が二つあり、どうも、第二引数にはリストがくるらしい。
この二つの引数のトリックによって、repeatとちがった挙動をとる。
468デフォルトの名無しさん:2006/05/13(土) 12:16:39
寺子屋「ふろく」第一話 repeatとmember (その二)

定義節をいくら眺めていても、さっぱり意味がわからないのがrepeatだ。
使われ方から考えるとだいぶんわかりやすくなる。それでは、
それぞれの定義がどのように負節(Goal)のなかで使われるかの例をみよう。

?- see('foo.pro'),repeat,read(X),(X=end_of_file;write_formatted('%t.\n',[X]),fail),seen.
ファイルを最後まで読んでそのまま表示する簡単なもの。
end_of_fileの判定が変なところにあるのは最終行としてend_of_file.を印刷しないための工夫だ。
一言だけ言っておくと、repeatの後どこかに、折り返す為の副目標(SubGoal)がくる。ここではfailだ。
そして、その間には何か副作用のある副目標がくる! assertz/1やwrite_formantte/2のような。

member/2は

?- member(_季節,[春,夏,秋,冬,恋]),新古今和歌集(_季節,_巻,_歌).

_季節=春,
_巻=1,
_歌=み吉野は山もかすみて白雪のふりにし里に春はきにけり;
_季節=春,
_巻=1,
...
member/2の方は案外とインタプリタトップから使われることが多い。
469デフォルトの名無しさん:2006/05/13(土) 13:55:06
寺子屋「ふろく」第一話 repeatとmember (その三)

member/2がPrologのプログラムの中で最も多く使われる述語といわれるのは

例えば、httpdサーバーからの情報を[_鍵,_値]のペアを要素とするリストで
受け取るケースが多いからだ。その中から必要な情報を取り出すときに

httpd情報取得(URL,_鍵,_値) :- cgi呼び出し(URL,_値ならび),member(_鍵,_値).

のような定義をする。_鍵の部分にはhtmlの<input name="xxx">のxxxがくる。HTMLファイルが
出荷場所:<input name="出荷場所"> 出荷日:<input name="出荷日"> だとすると
副目標 cgi呼び出し('http://yyyyyy.com/cgi-bin/zzz.pro?***',_値ならび), の _値ならび には
_値ならび = [[出荷場所,大阪支店],[出荷日,20060513]] のような情報がはいってくる。
これを一つずつ先頭から取り出すのがmember述語の役割となる。これはインターネットの例だが

データベース呼び出し(SQL文,_組) :- sql_call(SQL文,_組ならび),member(_組,_組ならび).

これはデータベースの呼び出しでやはり、リストの要素として、複数フィールドをもつレコードが
リストとして現れる。これを一つずつ呼びだすためにmember/2が使われる。
470デフォルトの名無しさん:2006/05/13(土) 14:55:31
寺子屋「ふろく」第一話 repeatとmember (その四)

memberとrepeatの比較というテーマから離れていますがもうちょっと続けます。

組み合わせ表示(L1,L2) :- member(A,L1),member(B,L2),write_formatted('%t,%t\n',[A,B]),fail;true.

共通要素のみの表示(L1,L2) :- member(A,L1),member(A,L2),write_formatted('%t\n',[A]),fail;true.

fail;true. の部分に悩まないでください。おまじないだと・・・。このような定義があると、実行例。

?- 組み合わせ表示([1,2,3],[a,b]).
1,a
1,b
2,a
2,b
3,a
3,b

?- 共通要素のみの表示([1,2,3,4,5],[1,4,6,8]).
1
4

?-
実行例のなかではデバッグしているときのようにリストの中身が
見えるようになっていますが、実際には何が入ってくるかわからないよ、
というのが定義の変数部分です。このように見えているなら、
手作業で同じ事が簡単にできますが。
471デフォルトの名無しさん:2006/05/13(土) 15:33:01
寺子屋「ふろく」第一話 repeatとmember (その五)

member/2の使い方を若干見てきました。これで四分の一くらい説明したことになりますか・・。

さて、今回のお話は、repeatとmemberの振る舞い(実は制御)の違いを意識することに
よって、Prologの制御と再帰述語との微妙な関係を感じ取ってほしい、という狙いを
もっています。この微妙な関係はPrologの恐るべき底力であると同時に欠点でも
あるのです。これから、本来のテーマであるrepeatとmemberのバックトラック時の
振る舞いの違いについて、考えることにします。
まず、
repeatは決して失敗しない述語です。 ?- repeat. が失敗するのは repeatが定義されていないときです。

だから、
?- see('foo.pro'), ← repeat,read(X), (X=end_of_file; ,,, (略)

で←方向に制御が戻ることはありません。一度定義を振り返りましょう。
repeat. /* repeatは真となる */
repeat :- repeat. /* 真であった筈のrepeatの別解を求められたならばrepeatの真偽値は新たにrepeatを呼びだすことによってわかる */

:- 左側部分repeatを2行分頭の中で ?- see('foo.pro'), repeat,... のrepeat位置に動かしてきて読んでみてください。

←方向には戻らず、直角三角形を描くように制御が元のrepeatの所にもどって新たにread(X)に進む感覚が
得られると思います。
472デフォルトの名無しさん:2006/05/13(土) 16:50:05
寺子屋「ふろく」第一話 repeatとmember (その六)

この直角三角形が頭の中で最初は大きく描かれるのですが、これがだんだん小さくなっていつか、
そういう制御を全く意識しなくなります。次に、memberに行きましょう。

?- _四季 = [春,夏,秋,冬], ← member(_季節,_四季),write_formatted('%t\n',[_季節]),fail.

で←方向に制御が戻ることはあるのでしょうか。定義にもどりましょう。

member(A,[A|_]).
member(A,[_|R]) :- member(A,R).

repeatとの違いは引数があり、定義第一節に於いては、第二引数がリストであること、そしてその第一番目の
要素が第一引数と一致するときに真になる、と主張しています。repeatの場合は無条件に真となりました。
それでは一致しなかったらなにが起きるか。
473デフォルトの名無しさん:2006/05/13(土) 16:58:28
寺子屋「ふろく」第一話 repeatとmember (その七)

?- L=[2,5,6,7],A=6, member(A,L). を実行したとしましょう。最終的に、
?- member(6,[2,5,6,7]). が実行されることになります。

この質問は定義第一節の主張と食い違います。すなわち、第一番目の要素が第一引数と一致するときに真になる
という主張と。失敗です。
repeatの時は成功し元の質問の節での制御は→方向にrepeatの次の副目標に移ったのですが、ここでは
そうはなりません。memberの第一節が失敗したということは、第二節以降がなければmemberを呼びだした
副目標が失敗します。しかし、ここではmemberに第二節の定義があります。

member(A,[_|R]) :- member(A,R).

ここで主張されていることは、第二引数のリストの第一要素は無視して残りのリストで同様に
memberを実行しよう。その真偽値をその結果に求めよう。ということです。

さて、上の実例の質問では[2,5,6,7]のうち2と5と7は第一節で真になりません。そして、
?- member(6,[6,7]). が実行された時ついに、
新たに呼びだされたmemberの第一節の定義が真となり、すなわち、呼び出しもとの
?- member(6,[6,7])が真となり、大本のL=[2,5,6,7],A=6,member(A,L), が真になります。
474デフォルトの名無しさん:2006/05/13(土) 17:12:13
寺子屋「ふろく」第一話 repeatとmember (その八)

講習会を主催したことがある人は誰でもここら当たりで「まずいなー」と思います。
ごちゃごちゃしてきて、短時間で理解してもらえるはずがない。そこで私はこの再帰の制御には
深入りしないことにしました。こちらを見てください。

?- member(6,[2,5,6,7]) -> member(6,[5,6,7]) -> member(6,[6,7]) -> member(6,[7]) -> member(6,[])

第二節から発生する質問は上記のように遷移します。このうち成功するのはmember(6,[6,7])の時です。
これも強制的に失敗すると最後の
member(6,[]) は第一節、第二節ともに失敗します。形式的に。

第一節は受け取った第二引数がすでにリストではありませんから、失敗します。
第二節は受け取った第二引数がリストでないとやはり、失敗します。
一度、member(6,[6,7])で成功して→方向への制御を得たmemberでしたが、
もう一度後戻りしてきてからはついに成功することはありませんでした。
したがって、memberは失敗に終わります。

?- L=[2,5,6,7],A=6,member(A,L), のmemberが失敗に終わるということは、制御は、

?- L=[2,5,6,7],A=6, ← member(A,L),

←方向に戻るということになります。repeatでは決して現れなかった方向への後戻りが起きました。
475デフォルトの名無しさん:2006/05/13(土) 18:00:02
寺子屋「ふろく」第一話 repeatとmember (その九)

ここで、(その六)での問いかけ、
?- _四季 = [春,夏,秋,冬], ← member(_季節,_四季),write_formatted('%t\n',[_季節]),fail.

で←方向に制御が戻ることはあるのでしょうか。に戻ります。ここまで付き合っていただいた方なら、
このmemberが4回真となり、→方向に制御が進み、そしてついに偽となり、←方向に戻って
この質問が最終的に偽となる。ということがおわかりでしょう。

では、repeat/2とmember/2のこの違いは何だったのでしょうか。
repeat.
repeat :- repeat.
member(A,[A|_]).
member(A,[_|R]) :- member(A,R).

1.. member/2の第二引数はリスト形式を取る。
2.. 普通のリスト表現ではリストは有限である。従って、いつか、先頭から要素を取り出していくと[]となる。
第二引数がリストであるということは、
a.. この定義の呼び出し側(副目標)の第二定義が[]を含むatomicデータ(整数やアトム)の時は偽となる。
b.. リスト以外の複合項の時も偽となる。
第一引数が変数でなく具体化している時は

第二引数のリストの中に第一引数と同じ要素がある時、そしてその数だけ制御は→方向に進む。

それ以外の時は偽となる。
というような制約を掛けられたと考えることができる。
引数表現によって、これだけの制御の可能性を広げたともいえる。

次項では第二引数が変数によって呼びだされるケースについて考察するが、
ここで一服入れることにする。
476デフォルトの名無しさん:2006/05/15(月) 09:22:02
寺子屋「ふろく」第一話 repeatとmember (その十)

予告では第二引数が変数で呼ばれるケースに続くはずでしたが、その前にrepeatの変形について
もう少し考察します。

member/2を2引数のrepeatとして、見てきたのですが、1引数のrepeatはあるのでしょうか。
形式的には、
repeat(_).
repeat(_) :- repeat(_).
ですね。形式的にしめしたこの定義は、よく見るとrepeat/0と全く同じ機能になっていることがわかります。
引数に何をいれてもよい。ということです。
repeat(A).
repeat(B) :- repeat(B). 変数がのように記述されても変わりません。

次はどうでしょうか。第一引数だけ引数がアトム"a"であることを主張してみます。
repeat(a).
repeat(_) :- repeat(_).
これは、呼び出し側が、 ..., repeat(a), → ...
だと、repeatとして機能します。バックトラックして戻ってくると以後は?- repeat(_).
として副目標が実行されることになりますから、以後はrepeat/0と同機能となります。
477デフォルトの名無しさん:2006/05/15(月) 09:22:57
寺子屋「ふろく」第一話 repeatとmember (その十一)

そうです。引数が変数の状態で副目標repeat/1が実行されると、
repeat(_).
repeat(_) :- repeat(_). はもちろん、

repeat(a).
repeat(b) :- repeat(_).

repeat(a).
repeat(a) :- repeat(a).

repeat(a).
repeat(b) :- repeat(a).

のどれもが、単一化の過程は異なりますが、同じ制御をすることになります。
この四つの定義を見ればわかるように,第二節の本体(仮定)部の引数が、
第一節の頭部の引数と無条件に単一化であるように定義されているとき、
?- ..., repeat(_), → は repeat/0と同じ制御となる、と言えます。
478477:2006/05/15(月) 09:41:23
第二節の本体(仮定)部の引数

とありますが、

第二節の本体(条件部)の引数

に訂正します。
479デフォルトの名無しさん:2006/05/15(月) 09:53:36
>>468
恋は季節?
480477:2006/05/15(月) 11:42:19
寺子屋「ふろく」第一話 repeatとmember (その十二)

第二引数を変数のまま、member/2を呼ぶ話の予告を(その九)の最後にしたのですが、
memberについては、その利用パターン考える夜話を別に設けることとします。

ここで、いささか眩暈を覚えるような今回の寺子屋のお話のまとめに入ります。
まず、このお話の対象ですが、後から言うのも変なのですが、全くの初心者では
ありません。一応の、講習とか、大学の授業とかで、Prologの骨格は理解しているが
どうも、制御がよくわからない。再帰述語自体はわかった気にはなるが、
実際にどのように使うのかもうひとつクリアにならない。そんな人が対象です。

私は螺旋階段を昇るようにこの問題を説明していきたいな、思っていました。今来た道を
何度もいつでも振り返れるように。そして、あいかわらず、元の位置にいるように
思えるように。このような螺旋階段状に少しずつ昇ることが、述語のパターンと
引数の意味、単一化の実際、そして、なによりその呼び出し元の副目標との関係の
理解、いや、ひらめきを得る、近道であるような気がしているからです。
現在の私はPrologのプログラミングでデバッガのように頭の中にその制御構造を
描くと言うことはありません。多分、こうに違いないと、引数を書き入れるだけです。
最初から答えはわかっています。なぜ答えがでるかというと、ひらめくとしか
いいようがありません。
このひらめく力を短期間に増強する方法をいろいろ試みてきて、この切り口ならどうだ
という問いかけが今回のお話ということになります。
481デフォルトの名無しさん:2006/05/15(月) 14:11:04
>>464
書籍目録ありがとうございました。
私は、初心者向きではないかも知れませんが、

わかる:-Prolog 塚本龍男著 がお勧め、です。

私が興味を持っていたことの半分くらいは載っていました。
482デフォルトの名無しさん :2006/05/16(火) 20:37:24
prologを大学で習い始めて1ヶ月のほぼ初心者の者です。
prologにて'!'は何を表すのかどなたか教えていただけますか?
483デフォルトの名無しさん:2006/05/16(火) 21:44:52
参考書に載ってないのか?
載ってない筈無いと思うのだが。
484デフォルトの名無しさん:2006/05/17(水) 04:39:03
>>482
!(カット)の正確な意味を言葉表現するのはなかなか難しい。
プログラムで示します。(その一)
季節(春).
季節(夏).
の定義があるとき。
?- 季節(X).
X = 春;
X = 夏;
no
?- とインタプリタトップから実行できます。
ここで定義を変更して、
季節(春) :- !.
季節(夏).

?- 季節(X).
X = 春;
no
?- となります。この節が真になったならば、次節以降が解となることは
ない、がこの!(カット)の意味です。
485デフォルトの名無しさん:2006/05/17(水) 05:08:22
プログラム(その2)
売上(山本商店,'20060501',3000).
売上(森下電気,'20060503',2000).
売上(山本商店,'20060514',2000).
売上(森下電気,'20060517',4000).
さて、ここで、2006年5月中に森下電気に売上あったか調べようと
思います。
?- 売上(森下電気,A,B),atom_part(A,1,6,'200605').
A = '20060503',
B = 3000;
A = '20060517',
B = 4000;
no
?- ですね。しかし、本当に求めているのは「あるかないか」であって
全てのデータを得ることではないとすると、
プログラム(その一)のように
売上(山本商店,'20060501',3000) :- !.
売上(森下電気,'20060503',2000) :- !.
売上(山本商店,'20060514',2000) :- !.
売上(森下電気,'20060517',4000) :- !.
と定義を変えればよい。
これで
?- 売上(森下電気,A,B),atom_part(A,1,6,'200605').
A = '20060503',
B = 2000;
no
?- となり、うまく1解が取れたところで検査は終了しました。しかし、
本当にこれでよいか?

486デフォルトの名無しさん:2006/05/17(水) 05:25:03
(その三)
領収書明細行印字(_顧客,_日付下限,_日付上限) :-売上(_顧客,_日付,_金額),_日付 @>= _日付下限,_日付 @=< _日付上限,
write_formatted('%t,%t\n',[_日付,_金額]),fail;true.

のような実務的なプログラムが存在したとします。
前回の!(カット)のついた売上定義ですと、明細を
常に1行しかださない領収書ができてしまいます。
そこで、裏技。
487デフォルトの名無しさん:2006/05/17(水) 06:00:08
(その四)
裏技などと期待を持たせる言い方をしましたが、じつは、
Prologプログラマにとって当たり前の話でしかありません。まず、定義を
売上(山本商店,'20060501',3000).
売上(森下電気,'20060503',2000).
売上(山本商店,'20060514',2000).
売上(森下電気,'20060517',4000). に戻します。
そのうえで、
売上存在検査(_顧客,_年月) :- 売上(_顧客,_日付,_),atom_part(_日付,1,6,_年月),!.
を定義します。そして、以後>>485で示した検査は
?- 売上存在検査(森下電気,'200605').
yes
?- で行います。(金額の確認は止めました) これでOK。

実はここまでが導入部。この売上存在検査の節の最後の!(カット)を
説明することで、!を理解していただけると思います。次稿で。
488デフォルトの名無しさん:2006/05/17(水) 06:22:49
ごめんなさい。大失敗をしていました。>>485の説明に致命的な
誤りがあります。その説明の方が先になってしまいます。
何がちがっているかというと、このプログラムだと、
年月の検査が全く働きません。ここでは全データ2006年5月分だったから
よいのですが、もし、
売上(森下電気,'20060430',1000) :- !.
売上(山本商店,'20060501',3000) :- !.
売上(森下電気,'20060503',2000) :- !.
売上(山本商店,'20060514',2000) :- !.
売上(森下電気,'20060517',4000) :- !.
第一節を追加しました。
だとすると、
?- 売上(森下電気,A,B),atom_part(A,1,6,'200605'). は
この第一節の4月分データで日付検査が進んでしまって、atom_partが偽と
なります。しかし、売上の定義には!が打ってありますから、
そのまま、この質問は偽となってしまいます。森下電気の5月分売上はなし!
まずいですね。

ちょっと仕事の時間になってしまいました。昼休みにつづきを書きます。
489デフォルトの名無しさん:2006/05/17(水) 06:52:24
>>488
この問題が起こる可能性があるから、
単位節述語の条件に :- !. を振って、非決定性の述語に
するということはしないね。
ミステイクかも知れないが、かえって好例になったかも。
490488:2006/05/17(水) 06:55:56
>>489
非決定性 -> 決定性 ですね
491デフォルトの名無しさん:2006/05/17(水) 07:05:22
補足。
一度解が得られるともう別解はない定義のされ方をした述語を
決定性述語、
別解の可能性を残した定義のされ方をした述語を非決定性述語と
呼びます。
売上(森下電気,'20060430',1000) :- !.
売上(山本商店,'20060501',3000) :- !.
...略
と定義されたとき述語売上は決定性述語。
売上(森下電気,'20060430',1000).
売上(山本商店,'20060501',3000).
と定義された場合は非決定性述語ということになります。
write_formatted や atom_part も決定性述語です。
492デフォルトの名無しさん:2006/05/17(水) 10:03:06
大失敗はあったが、幸いに(その四)で解決するから、こちらを
勧めるということにします。
(その五)
売上存在検査(_顧客,_年月) :- 売上(_顧客,_日付,_),atom_part(_日付,1,6,_年月),!.

この定義の最後の!によって、
売上の定義が事実上決定性を持つ理由を説明します。最初に質問

?- 売上存在検査(森下電気,'200605'). から

売上存在検査の定義の引数部分が_顧客 = 森下電気,_年月 = '200605'に
単一化され、その状態で、

?- 売上(森下電気,_日付,_),atom_part(_日付,1,6,'200605'),!.

の質問が導出されます。
493デフォルトの名無しさん:2006/05/17(水) 10:09:54
(その六)
売上の定義が
売上(森下電気,'20060430',1000).
売上(山本商店,'20060501',3000).
売上(森下電気,'20060503',2000).
売上(山本商店,'20060514',2000).
売上(森下電気,'20060517',4000). だとすると、
第一節が適合して、_日付='20060430' になります。
つぎに、制御は進んで、 ?- atom_part('20060430',1,6,'200605').
が実行され、'20060430'の1桁目から6文字は'200604'ですから、
第四引数に単一化できず偽。
これでバックトラックして、次の単一化可能な売上の定義節が
求められます。第三節が適合して_日付 = '20060503' となり
?- 売上(森下電気,'20060503',2000),atom_part('20060503',1,6,'200505'),!.
という質問が導出されて今度はatom_partも真になります。
494デフォルトの名無しさん:2006/05/17(水) 10:39:15
(その七)
ここでいよいよ!の登場です。
先に!(カット)の意味を言ってしまいます。カットはバックトラックを停止させる指示子(述語)です。

バックトラックしてきたら? その場合この質問全体がその時点で偽となります。具体的に見てみましょう。
?- 売上(森下電気,'20060503',2000),atom_part('20060503',1,6,'200505'),!. のatom_partまで真となりました。
次の副目標は!です。これは真になります。それでここを通過し・・・。この場合もうありません。
売上,atom_part,!の三つの副目標の全てが真ですから、この質問は真になります。

ここまで説明してきてまたまた「しまった」ということになりました
495デフォルトの名無しさん:2006/05/17(水) 10:40:21
(その八)
?- 売上存在検査(森下電気,'200605'). は森下電気に2006年5月中に売上があるか、いう質問でから、
あるか、ないかであって一度あるとわかったらバックトラックする必要はありません。それにバックトラック
させる良い方法がありません。
?- 売上(森下電気,_日付,_金額). は
_日付 = '20060430',
_金額 = 1000 は一旦停止したインタプレタトップから";"をキー入力することによって次の解
_日付 = '20060503',
_金額 = 2000 が得られます。ここではバックトラックが起こっていると言うことになります。
このように質問に変数がある時は一旦真になったあと別の解があるか探すことができるのですが、
?- 売上存在検査(森下電気,'200605'). のように引数に変数がないと、別の「解」を求めようがありません。
したがってバックトラックを起こす機会もありません。無理にバックトラックするとすれば、
?- 売上存在検査(森下電気,'200605'),fail. ですが、これだと売上存在検査は2回ほとんど成功しているのに
failによって最終的に偽になり、存在するの答えが出なくなってしまいます。
これが「しまった」の理由です。
496デフォルトの名無しさん:2006/05/17(水) 10:53:54
(その九)
それで
売上存在検査(_顧客,_年月,_金額) :- 売上(_顧客,_日付,_金額),atom_part(_日付,1,6,_年月),!.

に定義を変更して話を進めます。断っておきますが、売上存在検査で金額を取得するというのは全くの
ナンセンスです。偶然存在した第一解の金額を知ってみたところでほとんど利用の仕方がおもいつきません。
あくまで!の説明の便宜上ということです。

?- 売上存在検査(森下電気,'200605',_金額). で検査することにしましょう。金額が単一化される以外は
(その七)とほとんど変わりません。

?- 売上(森下電気,'20060430',1000),atom_part('20060430',1,6,'200605'),!. は偽になります。
atom_partが偽でバックトラックして
?- 売上(森下電気,'20060503',2000),atom_part('20060503',1,6,'200605'),!.
これでこの質問は真となり、導出した大本の質問
?- 売上存在検査(森下電気,'200605',_金額).
_金額 = 2000 となって成功します、解は_金額 = 2000 ですね。今度は";"で強制的にバックトラックすることが
できます。
しかし、今度は別解はでずに、no (偽)となります。ここに!(カット)の働きがあります。
497デフォルトの名無しさん:2006/05/17(水) 11:40:24
(その十)
!の働きは ← ,!, → は!を越えて、一度→方向に制御が進んだら、
バックトラックして←方向に戻る事はない。
もし、バックトラックしてきたらこの節は偽となる。ということです。これだけなら単純なのですが、
売上存在検査の定義が、

売上存在検査(_顧客,_日付,_金額) :- 売上(_顧客,_日付,_金額),atom_part(_日付,1,6,_年月),!.
売上存在検査(_顧客,_年月,_金額) :- 売上過去帳(_顧客,_日付,_金額),atom_part(_日付,1,6,_年月),!.
売上過去帳(森下電気,'20060500',0).

だとします。意味はお解りですね。売上述語になかったら、過去帳をみろということです。
?- 売上存在検査(森下電気,'200605',_金額).
_金額 = 2000 となって成功した後、";"で強制的にバックトラックを生じてもやはりnoになります。
売上過去帳に何故か混入した森下電気のエラーデータは参照されませんでした。
このように!は単に←方向へのバックトラックを停止するだけでなく、
現在質問している、条件(:-の右側)が定義されている述語に、質問している定義節以下に
定義節がさらに存在する場合でも(上の場合 売上存在検査( ... ) :- 売上過去帳( ..),atom_part,!. )
その定義節の参照の可能性を断つという働きがあります。
498デフォルトの名無しさん:2006/05/17(水) 11:45:58
(その十一)
言葉にすると複雑ですが、
売上(山本商店,'20060501',3000) :- !.
売上(森下電気,'20060503',2000) :- !.
売上(山本商店,'20060514',2000) :- !.
売上(森下電気,'20060517',4000) :- !.

の定義の定義の元で

?- 売上(森下電気,X,Y).
X = '20060503',
Y = 2000 ここで";"をいれてバックトラック起こしても、
'20060517'のデータは取れずに
no
?- となってしまう、例をよく考えると、節の最後の!の意味がわかります。
499デフォルトの名無しさん:2006/05/17(水) 12:28:01
(その十二)

!は何故使われるのでしょうか。

1.. !(カット)は解の探索空間を狭める働きがあります。Prologの解の探索は(深さ優先の)しらみつぶしの
探索といえます。多くの場合探索空間は極めて広く、計算量は膨大となります。ひとたび解が得られて
その解で満足ならば別解を求めないようにすることによって計算量が少なくなり実行速度が向上します。
2.. Prologはバックトラック時にもとの状態に戻れるように多くの情報をスタックに積みながら、
実行されます。!(カット)はこの積んであるスタックからバックトラックの可能性をなくすことにより
必要なくなった情報をpopさせる可能性を作ります。
3.. 最適化の可能性 この部分は説明が複雑になるので別稿を設けます。
500デフォルトの名無しさん:2006/05/17(水) 17:22:08
最適化と!の関係
研究者でもPrologの制作者でもなかった私がこの問題の存在を知ったのは
Prolog-KABAのマニュアルの中でした。ほんの十数行が私にPrologでやって
いけるという確信をあたえました。すぐに資源を食いつぶして、立ち往生
するのではないかという不安を払拭したからです。私はこの点からも
KABAの三人の制作メンバーに深く感謝しています。この謝意を表した上で
著作権に抵触することを覚悟した上で私を啓発したこのマニュアルの
文章をできるだけ正確に掲載したいと思います。
501デフォルトの名無しさん:2006/05/17(水) 17:31:41
流石にウザい。
502デフォルトの名無しさん:2006/05/17(水) 17:36:17
PrologKABAマニュアル -A.3- 萩野達也 桜川貴司 柴山悦哉 著
「このシステムのインタープリタは実行時のローカルスタックの使用量を減らす
ため、次のような最適化をおこなっています。

1) Successful pop
あるゴールの実行にdeteministicに成功したとき(そのゴールの実行の
しかたには別の選択肢がないという意味です)、そのゴールの実行に要した
部分をローカルスタックから取り除きます。
2) Last call optimization
節(Aとします)の本体のゴールを実行していって最後にとりかかるとき、
その節のゴールの実行がすべてdeterministicに終わっていたとします。
そのような場合にその最後のゴールと単一化をできるかどうか調べるべき
節が一つしかないときには、節Aに対応する部分をローカルスタックから
取り除きます。また、カット・オペレータ"!"が使用されたとき、そのカットを
含む節(Bとする)を呼びだしたゴールがそのゴールを含む節(Cとする)の最後の
ゴールであり、Cの他のゴールがすべてdeterministicに終わっている場合には、
Cに対応する部分がローカルスタックから取り除かれます。」
商品として売り出された製品のマニュアルであり、今の若い世代の
目に触れることのない貴重な資料だと思い、ここに掲載しました。
503デフォルトの名無しさん:2006/05/17(水) 20:10:42
>>501
ここのところ私の書き続けだからね。気持ちはわかるけれど。

掲示板はNifty以来7-8年空いてしまって、去年くらいから2ch
を覗いてみたら、Prologがあまりに低調なので驚き、かつ、
周章てた。これじゃ、社員がとれない。
一人で立て直すなんてできない。せめて、少しでもPrologを
知ってもらうことと、1980年代の知識をもう一度共有すること。
そのために、紹介したいものはたくさんある。>>502なんかも
その一つ。
504デフォルトの名無しさん:2006/05/17(水) 21:19:03
興味深く読ませてもらっております。他にネタもないしいいんじゃね。
505デフォルトの名無しさん:2006/05/17(水) 23:07:52
別に煽るつもりはないんだけど。

Prolog自体は面白いアプローチの言語だと思うんだけど、
どう実用すればいいのかが思いつかない。

とりあえず「こんな面白い事が出来る!」というような、インパクトが欲しい。
Haskellだと「Haskellで作ったシューティングゲーム」のページがあって結構衝撃だった。
(あまりHaskellらしくはないというのはさておき(笑))
Prologでそういうようなインパクトのある事を紹介しているようなサイトとか無いだろうか。

「こういう事を表現するにはこう書く」みたいな文法の説明だけでは
先が見えなくて息が続かない感じがする。
506デフォルトの名無しさん:2006/05/18(木) 07:25:10
「ご破算に願いましては」

四季(春).
四季(夏).
四季(秋).
四季(冬). が定義されていて、

?- repeat, → 四季(X).
X = 春;
X = 夏;
X = 秋;
X = 冬
までの実行で→を何回通過するでしょうか。
論理を名にし負ふPrologの「制御」について語ることを
お笑いの方もあろうが。
Prologを全く知らない人は4回だと思うでしょう。実際は最初の1度だけ。
?- repeat, → 四季(X).
X = 春;
X = 夏;
X = 秋;
X = 冬;
X = 春 ここまで来て2回目の通過をしたことになります。

さて、ここで。

ご破算に願いましては.
ご破算に願いましては :- ご破算に願いましては.

このrepeatと言う述語自体が、じゃらじゃらとゼロにするわけではないが、
それでも、こう名付けた方が雰囲気があるように思えてきた。
507デフォルトの名無しさん:2006/05/18(木) 07:57:53
>>507
驚くほどないなあ。ヨーロッパにはあるのではないかと今探しています。

神戸大学などは公開の仕方を変えれば利用できるものがもっとあるのかも
知れない。
Prolog協会のメンバーだった私達がサボッタというか、
インターネット時代を軽視して、ライブラリの確保に動かなかったことに
大きな責任がありますね。
私自身も急遽、公開するつもりで、自分のシステムの整理に入ったと
いう段階ですね。
508507:2006/05/18(木) 07:59:13
すみません。 >>505 の間違えでした。
509デフォルトの名無しさん:2006/05/18(木) 23:21:09
「適当な数値を含むリストとある数値の二つを
引数として取り、そのリスト内の要素を
いくつか含むリストでその総和が与えられら整数に
等しいものを計算する述語を定義」
したいのですが、とても苦戦しております。

要は
?- sumCombi(10,[2,3,4,5,6],X).
X=[2,3,5];
X=[4,6];
といったように第一変数(10)を第二変数(2,3,4,5,6)の
組み合わせで第三変数(X)で出力したいんですが。

ご助言お願いします。
510デフォルトの名無しさん:2006/05/19(金) 03:42:27
>>509
単純には、
・「そのリスト内の要素をいくつか含むリスト」を作る
・総和を計算する
・等しかったら第三引数に単一化する
でできるよね。

どこまで考えたか、どこで悩んでるのか…とかを晒さないと、助言なんてできないよ。
511デフォルトの名無しさん:2006/05/19(金) 04:05:13
>>509
JAIST レポート課題の丸投げ 禁止

--- 以下、>>509 を放置の方向でお願いします ---
512デフォルトの名無しさん:2006/05/19(金) 06:30:36
JAISTでどのようなProlog教育がなされているか、
コメントをいただきたい。
513デフォルトの名無しさん:2006/05/19(金) 11:40:27
>>512
不十分な説明のわりには、難しいレポート課題を出題されます。
詰め込み教育せざるを得ない教育システムなので
学生がレポート丸投げ、丸写ししまくりで大変です。
Google世代ですからね、彼らは…。

学生のためにも、>>509は放置の方向でお願いします。
514デフォルトの名無しさん:2006/05/19(金) 16:45:22
本当はスキルがなくて答えられないだけなんでしょ。
515デフォルトの名無しさん:2006/05/19(金) 17:15:37
>509
すいません解決しました。
516デフォルトの名無しさん:2006/05/19(金) 18:18:23
>>513
> 不十分な説明のわりには、難しいレポート課題を出題されます。

別段普通だろ。ましてや院なんだし。
517デフォルトの名無しさん:2006/05/19(金) 20:40:43
>>516
「普通であるか否か」は個人の主観に依存した問題です。
頭が良ければ、何てことはありません。
ところで、JAISTは負け組み(バカ)しかいない。
よって、普通ではない。
518デフォルトの名無しさん:2006/05/20(土) 08:12:40
?- sumCombi(2,[1,1,1,1],X).

X = [1,1];
X = [1,1];
X = [1,1];
X = [1,1];
X = [1,1];
X = [1,1];
no.
?- となるね。重複解を抑制したいね。
519バグ:2006/05/20(土) 13:41:13
重複解抑制でついやってしまうのが

sumCombi(N,L,X) :- sort(L,L1),select(L1,X),add(X,N).

というやつ。
520デフォルトの名無しさん:2006/05/20(土) 16:27:43
どの数字がいくつあるかを数えて、重複させない select を作ればいけるね。
521デフォルトの名無しさん:2006/05/20(土) 16:38:06
もっと単純か、選択しなかった数字は全部 remove しちゃえばいいだけかな。
522デフォルトの名無しさん:2006/05/21(日) 05:01:17
一般論として、>>509 >>519のように
非決定的に解が取れている負節の重複解を検査することは
簡単ではない。一旦、解リストを生成して、重複を除去して、
あるいは、重複を除去しながら、解リストを生成して、
member/2で取り出しているなら別だが。
季節(春).
季節(夏).
季節(春).

?- 季節(X).
X = 春;
X = 夏;
X = 春;
no
?- 3解目を抑制するには結構難しい。Prologデータベースから
集約解を得るのが難しいというのと同様の意味で。
523522:2006/05/21(日) 05:13:30
>>519>>518 3解目を抑制するには は 3解目を抑制することは

に訂正します。
524411:2006/05/21(日) 06:41:48
member2(A,[A|R]) :- not(member(A,R)).
member2(A,[_|R]) :- member2(A,R).
を定義しておいて
?- findall(U,季節(U),L),member2(X,L). /* で良さそうなものだが */
X = 夏;
X = 春;
no
?- と取り出し順序が逆転してしまう。
525デフォルトの名無しさん:2006/05/21(日) 07:45:16
>>524 の名前が411になっているのは間違いです。なぜか、
書き込み時に変な数字が生成されてしまいます。
526デフォルトの名無しさん:2006/05/21(日) 10:50:28
sumCombi の場合だと、最初からリストを使ってるから、難しくないんだよね。
やっぱり、データはリストに保持して、 member とかで取るほうが便利だと思う。


>>524
順序が重要なら、

member3(Element, List) :- member3(Element, [], List).
member3(Element, History, [Element|_]) :- \+ member(Element, History).
member3(Element, History, [Head|Rest]) :- member3(Element, [Head|History], Rest).

みたいな定義でどうかな。
527526:2006/05/21(日) 12:04:09
訂正…リストだからって簡単なわけじゃないね。
一部の問題で findall 使う手間が省けるくらいで。
たまたま sumCombi が重複解抑制しやすい問題だっただけだね。
528デフォルトの名無しさん:2006/05/21(日) 12:52:06
>>527
sumCombiの作り方も
あらかじめ数字の組みあわせを作る段階で合計値によって
選択しながら、解を蒐集してリストとする方法と、
組み合わせが一つできるたびに合計値の適合を調べて、
解とする方法があり、素直なのは後者。こちらだと、>>518
ような仕様変更で苦労することになる。
Prologプログラマは前者の方のリスト生成述語のようなものを
反古として持っているから、どちらかというとそちらを書く。
それで救われる。
529デフォルトの名無しさん:2006/05/22(月) 02:48:25
>>528
sumCombi だと、後者でもあんまり苦しまない気がするけど…
与えられたリストからサブセット作る述語は、例えば

subset(List, Result) :- subset(List, [], Result).
subset([], Result, Result).
subset([Head|Tail], Temp, Result) :- subset(Tail, [Head|Temp], Result).
subset([_|Tail], Temp, Result) :- subset(Tail, Temp, Result).

みたいな感じだよね。
この場合、重複解の原因はここだけだから、例えば

subset_uniq(List, Result) :- subset_uniq(List, [], [], Result).
subset_uniq([], Result, _, Result).
subset_uniq([Head|Tail], Temp, BlackList, Result) :- \+ member(Head, BlackList), subset_uniq(Tail, [Head|Temp], BlackList, Result).
subset_uniq([Head|Tail], Temp, BlackList, Result) :- subset_uniq(Tail, Temp, [Head|BlackList], Result).

みたいにすると解決する。


前者のやりかただと、もっと簡単なの?
530522:2006/05/22(月) 07:18:46
そうか、私が間違っていたんだ。
member型の述語は原資がリストだから、findallを使わずに、
解の蓄積が可能。>>522 のケースとははっきりちがって。

それから、リストを作ってからmemberで引き出すケースとの比較ですか。
私は前者を完全には書いていなかったので、これから。
531デフォルトの名無しさん:2006/05/23(火) 20:54:32
すいません、学校の宿題です。
『有向グラフGのエッジ数がEであるようなenumber(G,E)のプログラムを作成せよ。
 Gは要素が項edge(N,Ms)であるリストであり、edge(N,Ms)は、
 「Msの任意の要素Mに対してNからMまでのエッジが存在する」ことを表す。
 例えば、下のグラフは、[edge(a,[b,c]),edge(b,[a,c,d],edge(c,[d]),edge(d,[])]
 のように表され、
  a →
 ↓↑ ↓
  b →c
↓ ↓
   →d
 enumber([edge(a,[b,c]),edge(b,[a,c,d]),edge(c,[d]),edge(d,[])],E).
 は E=6となる。』
図がわかりにくくてすいません。aからc、bからdへの経路がそれぞれあります。
(斜め矢印が表示できないので)
この問題で、私は
edge(a,[b,c]).
edge(b,[a,c,d]).
edge(c,[d]).
edge(d,[]).

enumber([],0).
enumber([H|T],E) :- H = edge(N,[]), enumber(T,E).
enumber([H|T],E) :- H = edge(N,[M|Ms]), enumber([H1|T],E1), E1 is E+1, H1 = edge(N,Ms).
と書いたのですが、うまくいかないようです。どなたかアドバイス等お願いいたします。
532531:2006/05/23(火) 20:56:31
a →
↓↑ ↓
b → c
↓  ↓
 →d
533531:2006/05/23(火) 20:57:23
>>531の図について532へ訂正しました。すみません。
534デフォルトの名無しさん:2006/05/23(火) 21:45:53
>>531
> enumber([H|T],E) :- H = edge(N,[M|Ms]), enumber([H1|T],E1), E1 is E+1, H1 = edge(N,Ms).

この部分、どうやって呼ばれるか考えてみた?
E が何にも単一化されてない変数の状態で呼ばれるんだよね。
その状態じゃ E+1 なんて計算はできない。

っていうか、 enumber([H1|T],E1) が成功してきたなら、 E1 は数値に単一化されてるよね。
単に逆なんじゃ?

あと、 H1 を edge(N,Ms) に単一化するのが遅すぎ。
enumber([H1|T],E1) より先に単一化しとかなきゃ、変数を含んだリストに対して enumber を計算することになる。
535531:2006/05/23(火) 21:46:18
>>531-533
自力で解決しました。
もし、考えてくださった方がおられたなら、ありがとうございました。
536531:2006/05/23(火) 21:47:49
>>534
解決しました。
ありがとうございました。
537デフォルトの名無しさん:2006/05/23(火) 22:13:54
prologが宿題ってなんかニガイなー
538デフォルトの名無しさん:2006/05/23(火) 22:55:54
すいません、丸投げです。
「red,white,blue の3種類の複数の要素からなるリストL1を並べかえて
最初にred、次にwhite、最後にblueという順のリストL2にするプログラム
dutch(L1,L2)を以下の関数appendを用いて作成せよ。
append([],Y,Y).
append([X|Xs],Y,[X|Zs]) :- append(Xs,Y,Zs).
ただし、各要素は"色(順序)"という形で表現し、同一色同士の場合には、
出現の順序は保持されるものとする。例えば、
dutch([red(1),white(2),blue(3),red(4),white(5)],L)は
L=[red(1),red(4),white(2),white(5),blue(3)],となる」
ヒントだけでもいいので、どなたかお願いいたします。
539デフォルトの名無しさん:2006/05/24(水) 02:53:02
とっかかりすら自分でやらないのか。問題を論理的に整理する能力がないってことだな。
言われたことしか出来ないんだね。
バカモノ。自分で問題を整理して、一部でも手のつけられることからやってみろ。

540デフォルトの名無しさん:2006/05/24(水) 11:58:38
Prologはツンデレ
541デフォルトの名無しさん:2006/05/25(木) 19:52:57
>>538
基本型
copy([],[]).
copy([A|R1],[A|R2]) :- copy(R1,R2).
単純に第一引数のリストを第二引数に生成するための述語ですね。
?- copy([1,2,3],X).
X = [1,2,3]

ヒント 引数を増やすことを怖れないこと。
542538:2006/05/25(木) 23:26:13
append([],Y,Y).
append([X|Xs],Y,[X|Zs]) :- append(Xs,Y,Zs).

member(X,[X|T]).
member(X,[Y|T]) :- member(X,T).

dutch([],[]).
dutch([L1|Ls1],[L1|Ls2]) :- Ls1=[], dutch(Ls1,Ls2).
dutch([L1|Ls1],[L1|Ls2]) :- L1=red(_), dutch(Ls1,Ls2).
dutch([L1,L2|Ls1],Ls2) :- L1=white(_), member(red(_),[L2|Ls1]), append([L2|Ls1],[L1],L3), dutch(L3,Ls2).
dutch([H|T],[H|Ls]) :- H=white(_), dutch(T,Ls).
dutch([L1,L2|Ls1],Ls2) :- L1=blue(_), member(red(_),[L2|Ls1]), append([L2|Ls1],[L1],L3), dutch(L3,Ls2).
dutch([L1,L2|Ls1],Ls2) :- L1=blue(_), member(white(_),[L2|Ls1]), append([L2|Ls1],[L1],L3), dutch(L3,Ls2).
dutch([H|T],[H|Ls]) :- H=blue(_), dutch(T,Ls).
543538:2006/05/25(木) 23:26:53
>>541ありがとうございます。
>>542のようなプログラムが出来ました。が、少し間違っています。
?- dutch([red(1),white(2),blue(3),red(4),white(5)],L).
L=[red(1),red(4),white(5),white(2),blue(3)]
とwhiteの順が正しくなりません。
このプログラムでは、先頭要素が、whiteの場合は、残りのリストに
redが含まれれば、その先頭要素を最後尾にまわし、blueが先頭要素のとき、
redかwhiteが残りのリストに含まれれば、そのblueを最後尾にまわす、
という法則にしているためだろうと思います。
どうすればよいでしょうか?
544538:2006/05/25(木) 23:37:03
>>541ありがとうございました。
>>543の件ですが、解決しました。
他にも考えてくださった方々、ありがとうございました。
545デフォルトの名無しさん:2006/05/26(金) 01:44:01
ほぼ独学です。。。
A+B=Cであるような非負整数A,B,Cの組をすべて数え上げるようなプログラムを作りたいのですが、
A+B=CのCが与えられた場合についてA,Bをすべて数え上げるプログラムしかできません。。。

add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

これを使って、

adda(X,Y,0) :- add(X,Y,0).

という風にすると、A+B=0のときのA,Bの組が求められるので、この3つ目の'0'の部分を徐々にs(0),s(s(0)),,,,と増やしていく、
というプログラムにしたいのですが、どうもうまくいきません。

どうすればよいのか教えていただけないでしょうか・・・。
よろしくお願いします。
546あぼ〜ん:2006/05/26(金) 01:58:14
>>531
>>538

せっかくの少人数制講義(演習)が無意味じゃないか
教授やTAをもっと使えよなw
547デフォルトの名無しさん:2006/05/26(金) 03:13:55
>>546 >>414のパターンで
g(0).
g(s(X)) :- g(X).

add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).
adda(X,Y,Z) :- g(Z),add(X,Y,Z).

ではだめなのかなぁ。
548547:2006/05/26(金) 03:15:11
549デフォルトの名無しさん:2006/05/26(金) 09:30:48
>>541
append 使うってそういうことだったのね。
red とかを優先順位の数値に変換して整列…とかいうのを思いついたから、 append の用途がわからなかった。
550545:2006/05/26(金) 14:29:46
>>547
確かに出来ました。

有難うございましたm(_ _)m
551デフォルトの名無しさん:2006/05/26(金) 14:43:19
>>550
Prologでは
生成器は一引数のrepeat型再帰述語から
考え始めるのが普通です。
552デフォルトの名無しさん:2006/05/26(金) 18:07:38
>>549
まだ、このスレを覗いているなら、問題を解いてください。

red,white,blueの3色だとわかっていると易しいのですが、
何色でてくるかわからないとしたら、どんなプログラムになりますか。
553552:2006/05/26(金) 18:28:56
実は、この問題は初心者には少し難しすぎるある問題を
含んでいます。そこら辺のところに気づいたり、悩んだり
するだけで十分かも知れません。
554デフォルトの名無しさん:2006/05/26(金) 18:51:05
>>552
何色出てくるかわからないって、それ並べる順序はどうすればいいの?
何色あっても、色ごとに別のリストに分けて順番に append する…とかでいけるけど。
555デフォルトの名無しさん:2006/05/26(金) 19:05:20
引数をいくつ増やせばわからないわけだから、そこをリストにする、
ということになります。
そのリストの中に既にその色があればそこに付加されるようにし、
もし、まだ見出ならば新たにリストの中にその色のリストを作るようにする。
でよいのですが、
私が問題といったのはそういうレベルの話ではありません。
556555:2006/05/26(金) 19:06:28
見出 は 未出 の間違いです。
557555:2006/05/26(金) 19:10:38
引数をいくつ増やせばよいかわからないわけだから、

ですね。 たびだびすみません。
558デフォルトの名無しさん:2006/05/26(金) 20:23:56
>>554
色の順序については、偶然の出現順、つまり、
yellow(1),red(1),yellow(2),blue(1), ...
だとすると
[yellowのならび + redのならび + blueのならび + ... ]
で構わないことにしましょう。
559デフォルトの名無しさん:2006/05/27(土) 00:50:19
>>558
とりあえず書いてみた。

uniq_color(List, Result) :- uniq_color(List, [], Reversed), reverse(Reversed, Result).
uniq_color([Head|Tail], Temp, Result) :- functor(Head, Color, 1), \+ member(Color, Temp), !, uniq_color(Tail, [Color|Temp], Result).
uniq_color([_|Tail], Temp, Result) :- uniq_color(Tail, Temp, Result).
uniq_color([], Result, Result).

extract_color([Head|Tail], Color, [Head|RTail]) :- functor(Head, Color, 1), !, extract_color(Tail, Color, RTail).
extract_color([_|Tail], Color, Result) :- extract_color(Tail, Color, Result).
extract_color([], _, []).

fold(Function, [First|[Second|Rest]], Result) :- call(Function, First, Second, Temp), fold(Function, [Temp|Rest], Result).
fold(_, [Result], Result).

sort_colors(List, Result) :-
uniq_color(List, Colors), maplist(extract_color(List), Colors, Temp), fold(append, Temp, Result).
560デフォルトの名無しさん:2006/05/27(土) 03:24:28
>>559
「ある問題」とは関数部分に変数を置いて参照することは
できないということですね。メタ述語 functor/3(または=..)を
使わざるを得ない。この述語を知らないとどうにもなりません。
それにしても、複雑だなぁ。(出題者、無責任に呆れる)
561デフォルトの名無しさん:2006/05/27(土) 04:16:09
u([],[]).
u([P|R],L) :- u(R,L2),a_u(P,L2,L).

a_u(P,[],[[P]]) :- !.
a_u(P,[[Q|R1]|R2],[[P,Q|R1]|R2]) :- functor(P,F,1),functor(Q,F,1),!.
a_u(P,[L|R1],[L|R2]) :- a_u(P,R1,R2).

だと、思ったのだが。
562デフォルトの名無しさん:2006/05/27(土) 04:36:27
>>561
! はいらない !
563デフォルトの名無しさん:2006/05/28(日) 15:13:23
変数が単一化されてない場合に真となる述語はどうすれば定義できますか?

undefined(X)ならyes
undefined(x)ならno

みたいにな感じです。
564デフォルトの名無しさん:2006/05/29(月) 03:46:21
ISO標準のvar/1で組み込むことになっている述語ですね。

自分自身の引数として受け取った値(構造体)を直接参照できないと、
真の判定はできませんね。
ゴールundefinedが実行されるときControlStackにundefined構造体が積まれ
そのオフセット8バイト目(例えば)からが第一引数へのポインターであって
この値が-1(これも例えば)の時は変数である。だから、この値を参照すれば
よい。というように。Prologマシンでない限りこのような参照は
不可能でしょう。

undefined(X) :- not(functor(X,_,_)).

も考えられますが、これは、functor/3が偽でなく、
例外処理が発生しますので、この記法では実行が停止してしまいます。

仮に Exception Handlerが
例外処理(_ゴール,_例外実行) の書式だとすると、

undefined(X) :- not(例外処理(functor(X,_,_),fail)).

なら判定はできるでしょう。しかし、
考えてみればvar/1とfunctor/3のどちらが原初的な述語かという
ことになり、このような定義は解になっていない気がします。
565563:2006/05/29(月) 09:56:26
>>564さん
ありがとうございます。もう少し、var/1について勉強しなおしてみます。
566デフォルトの名無しさん:2006/06/01(木) 02:10:13
Win用のSWI-Prologの最新版が公式でダウンロードできないのですが、
どこかにダウンロードできるところがあるでしょうか?
いくら探しても見つかりませんorz
567デフォルトの名無しさん:2006/06/01(木) 14:43:35
>>566
整理中にしてはちょっと長いですね。もう少し待ってみるか。
568デフォルトの名無しさん:2006/06/01(木) 20:34:55
>>566
復旧しました。
569デフォルトの名無しさん:2006/06/01(木) 23:28:48
>>568
明日テストなので今ごろ復旧しても遅いんですが^^;
570デフォルトの名無しさん:2006/06/03(土) 07:32:09
最初から答えを知ってる人は無視してください。
member/2の定義が
member(A,[A|_]).
member(A,[_|R]) :- member(A,R).
の時、
次のLはそれぞれ何になるか直感的に即答しましょう。

?- member(A,L),member(A,[1,2,3]).

?- member(A,[1,2,3]),member(A,L).

どうでしたか?
571デフォルトの名無しさん:2006/06/03(土) 08:51:19
member(A,L)はLが自由なとき無限個の解を持ち、その一般解は、
listの連結を++で表すとL = L1 ++ [A] ++ L2と書ける。よってprolog
の評価順序を考慮すると、上はL = L1++[N]++L2 where N ∈ {1,2,3}、
下はL = L1++[1]++L2となる。
572デフォルトの名無しさん:2006/06/03(土) 12:26:38
>>571
極めて適切な解答ですね。
以前からこの2つが異なった振る舞いになってしまうことを
残念に思っていたので話題にしてみました。
573デフォルトの名無しさん:2006/06/03(土) 15:05:15
手続型言語から見りゃ、評価順序で結果が変わるなんて当たり前だけど
論理型的には気持悪いんかなぁ
574デフォルトの名無しさん:2006/06/03(土) 18:40:13
順序数で
3×ω ≠ ω+ω+ω
になるみたいな、そうでないような。
575デフォルトの名無しさん:2006/06/04(日) 05:49:49
バックトラックの優先順位とか設定できればいいのかな…
576デフォルトの名無しさん:2006/06/04(日) 07:14:51
>>575 せっかくシンプルなPrologの文法が複雑になってしまう。
しかし、
>>570 の例は特殊なものであって、それに該当しないが、
指定された引数が束縛されていない時に待ち合わせる
遅延評価はどうしても欲しい。
どんな指定の仕方をすれば(記法上)シンプルさを失わずこれが
可能になるか、もう一度議論して欲しいと思う。
1980年代前半に中島秀之氏が提案していた{項記述}という拡張が
参考になるように思う。
577デフォルトの名無しさん:2006/06/04(日) 08:09:50
>>576
> 指定された引数が束縛されていない時に待ち合わせる
> 遅延評価はどうしても欲しい。

ちょっとイメージがわかないのですが、何か具体例はありませんか?
578デフォルトの名無しさん:2006/06/04(日) 08:59:30
>>577 ちょっと午後まで用事があるので、夕方までに書きます。
579デフォルトの名無しさん:2006/06/04(日) 10:46:33
これが問題だって思う人は何が問題だと思うの?
解の順番が違うこと?
解の個数が無限の場合にそれが数え上げっぽくなってないこと?
580デフォルトの名無しさん:2006/06/04(日) 13:26:55
差集合を求める述語を定義したいと思うのですが、なかなかできないのでヒントをお願いします。

@
difference([a,b,c,d],[b,a],Z).
|?- Z=[c,d]
A
difference([b,a],[a,b,c,d],Z).
|?- Z=[c,d]
B
difference(X,[b,a],[c,d]).
|?- X=[a,b,c,d]

が全て成り立つようにしたいのです。
@、Aはできたのですが、Bを入力したときに終わらなくなります。
よろしくお願いします。
581デフォルトの名無しさん:2006/06/04(日) 13:32:33
>>579
細部を考えたくない。実行経過のトレースのようなものを放棄したい。
第一感だけでプログラミングしたい。
member/2は双方向性の述語だと思ってみると、これは第一感では
Lは同じになる。ところが実際は、そうとはならず、
?- member(A,[1,2,3]),member(A,L). の場合、バックトラックしても、
A=1, のまま(いわば)ωとなってしまって、A=2,.. A=3,...さえ現れない。
ちょっと違和感のある解となる。そのことを「残念」と表現した。

582デフォルトの名無しさん:2006/06/04(日) 15:53:16
>>581
解の順番が違うことはどうでもいいのね。

>member/2は双方向性の述語だと思ってみると、これは第一感では
>Lは同じになる。ところが実際は、そうとはならず、

そうとなってないわけじゃないと思うけど。
Lの長さが有限なら同じ答になるんだし、むしろこの二つの使い分けが
できることが効率的なプログラムを書く助けにもなると思う。
583デフォルトの名無しさん:2006/06/04(日) 19:09:15
>>580
@とAは今どんな風に定義してあるの?
584デフォルトの名無しさん:2006/06/04(日) 20:27:27
>>580
例から
difference(X,Y,Z) <=> Z = {x | x はXとYのいずれか一方にのみ含まれる}
と解釈(通常の差集合ではない)。

difference(X,Y,Z) :- d(X,Y,Z), is_set(X), is_set(Y), is_set(Z).

d([],Y,Y).
d([H|T],Y,Z) :- member(H,Y), delete(Y,H,Y1), d(T,Y1,Z).
d([H|T],Y,[H|Z]) :- not(member(H,Y)), d(T,Y,Z).
585デフォルトの名無しさん:2006/06/04(日) 20:53:31
>>577 遅くなりました。ようやく帰ってきました。
さて、私の書き込み>>576も不備があったようです。

1).. p(A,B,X) :- X is C+D, ... ,p1(A,C), ... ,p2(B,D).
2).. p(U,X) :- call(U), ... , database(A,X), ...
3).. p(U,X) :- database(A,X), ... , check(U,A), ...

の3つのケースを考えます。
1)はis/2の実行がエラーになるから後ろに回そうというものです。
2)はUの内容がA @>= '1000'だとやはりエラーになるから、
database/2の後ろに来るまで遅延させようと言うことになります。
3)は全く逆で、database/2がBtreeのようなindexを持っている時、
database/2を後ろに回して、解の取得を高速化したいなどの場合
起こりうると思います。Aが決まってから実行したいのです。
3)はコンパイルするならば、database(A,X),のAは初出の変数ですから、
最適化て、副目標の位置を変えることも可能でしょう。

2)のUですが、 A='2000' が 入ってきたり A @>= '1000' が入って
きたりもするわけで、A='2000' の場合は遅延させる必要はないわけです。
しかし、このAは述語=/2の第二引数であり、call/1の引数として存在する
訳ではないので、2)の条件部で遅延させられるかという問題があります。
不備といったのはこの点です。
3)はコンパイルするならば、database(A,X),のAは初出の変数ですから、
最適化として、暗に副目標の位置を変えることも可能でしょう。
586580:2006/06/05(月) 01:46:50
>>583,584
おかげさまで成功しました。
ありがとうございました。
587587:2006/06/05(月) 09:28:56
すみません。また、誤りを発見しました。
2)の A @>= '1000' ですがこれだと呼び出し側の A とこの定義節の
A はリンクされませんね。どうすればよいのでしょう。
2) は
p(A,U,X) :- q(A,U), ... , database(A,X), ...
q(A,A @>= B) :- A @>= B,!.
q(A,A = B) :- A = B,!.
q(A,U) :- call(U).
でq(A,U) のAが束縛されているかどうかで遅延するかどうか決定する。
これで、
?- p(A,A @>= '1000',X).
と呼びだす。
588587:2006/06/05(月) 09:34:33
>>587 はもちろん585についてのコメントです。間違えました。

q(A,A @>= B) :- A @>= B,!.
q(A,A = B) :- A = B,!.
の部分はイメージを明確にするため定義してみたのであって、省略して、

q(A,U) :- call(U).

だけで構いません。
589デフォルトの名無しさん:2006/06/05(月) 09:52:11
>>587 だと

?- p(A,A = 尾崎,X). と
?- p(尾崎,true,X).
の実行結果は同じになりますね。もし遅延実行が可能になれば、
上はp/3の条件でq/3は遅延し、
下は遅延しません。当然のこととして、
q/3の第一引数と第三引数を遅延評価のトリガーとして利用するか
しないか、の記法上の差をつけられるようにしなくてはなりません。
そうしないとこの例のXは、どれもまだ束縛されていませんから、
全部遅延評価になってしまいます。
590デフォルトの名無しさん:2006/06/05(月) 10:11:03
>>589 以下の部分はなかったことにしてください。
当然のこととして、
q/3の第一引数と第三引数を遅延評価のトリガーとして利用するか
しないか、の記法上の差をつけられるようにしなくてはなりません。
そうしないとこの例のXは、どれもまだ束縛されていませんから、
全部遅延評価になってしまいます。

トップレベルにあるXをみて、書いてしまったのですが、これまで
p/3の述語定義の条件の中のq/2の遅延評価について考えてきているので
適切でありませんでした。
591デフォルトの名無しさん:2006/06/05(月) 12:02:46
なんかこのスレでみてると
偉そうな先生が書くたびに、いろいろ間違いが多いので、
Prolog は所詮その程度のものなんだと思いました。

ちょっと経験がある人でも、こんなに間違えやすいものは、
理屈がどうあれ、全く実用にはなりませんな'。
592デフォルトの名無しさん:2006/06/05(月) 12:36:31
間違えてるのは私ばかりだよ。
ほとんど読み返さず送信を押しちゃうからね。
メモ帳にでも一旦書き込んでからコピーすればいいんだろうけど。
個人的な資質の問題で言語とは無関係な気がするけど。
593デフォルトの名無しさん:2006/06/05(月) 13:50:47
visual prolog等のように型付きにすると少しはミスも減るかな…
594デフォルトの名無しさん:2006/06/05(月) 15:52:42
>>587 で指摘したようなミスはプログラム作成時にも起きる。
読み返したとしても、起こりがちなエラーといえる。
大域変数が使えるなら、こんな不思議なテクニックは必要ないから、
確かに、Prologの難しいところかも知れない。醍醐味でもあるのだが。
595デフォルトの名無しさん:2006/06/05(月) 19:43:28
>>591 >>592 >>594
尾崎さんは仕様書をそのまま一気にプログラムとして
書き下ろすスタイルだから、読み返す習慣がないのかなw
我々、並みのプログラマは、Prologでも考え考えですから、
そんな、すぐに送信という訳にはいきません。
596デフォルトの名無しさん:2006/06/05(月) 19:46:07
>>595
私は仕様書なんて書きませんw
597デフォルトの名無しさん:2006/06/06(火) 10:11:43
つまり
理屈がどうあれ、全く実用にはならず
趣味や自己満のためのものです。
598デフォルトの名無しさん:2006/06/06(火) 10:54:04
18年も企業実務(販売管理、給与計算、財務会計)で使ってますが。
599デフォルトの名無しさん:2006/06/06(火) 11:18:05
>>597
三十年以上も存在している言語で実用にならない言語なんて
あるわけないだろ。
プログラミング言語なんて最終的には兄弟姉妹みたいなもの。
600デフォルトの名無しさん:2006/06/06(火) 11:25:56
>>599
天才肌の兄貴が、努力家の弟(C++ Java)に圧倒されてるということか・・
601デフォルトの名無しさん:2006/06/06(火) 14:39:08
>>598 のいってる実用がしょぼくて悲しい
602デフォルトの名無しさん:2006/06/06(火) 14:58:07
もっとProlog向きの領域を期待するなら、
INAPのProceedingを全部読んで、そこでの発表がいつ頃まで
実用でいつ頃破棄されたかを全部確かめた上で、出直していらっしゃい。
603デフォルトの名無しさん:2006/06/06(火) 15:39:20
はいはい
偉い偉い
604デフォルトの名無しさん:2006/06/06(火) 18:50:06
INAPのProceedingsはひとつも読んだことがないので発言権はないかも知れないが…

個人的にprologを使っていて今ひとつなところは、

1. 遅い。
2. 仕様記述言語やプロトタイプ開発言語として使いたいが、prologと他の非論理型言語
 の距離が遠いため、仕様と実現が乖離しやすい。
3. 実行可能な仕様にするためにcut等を入れたり、バックトラックの大域的な挙動を考慮
 する必要がある。
4. assert/retractは破壊的で美しくない。
5. 集合を扱うのが面倒(これはこのスレッドで常々言われている通り)。
6. 処理系依存な述語を使う羽目になることが多い。

あたり。将来この辺が改善される見込みはあるのだろうか…
605デフォルトの名無しさん:2006/06/06(火) 19:15:28
>>604 INAP云々はできっこないことを意地悪で言った。

ほぼ全面的に同意。
1. についてはそれで十分なアプリケーションも実は多い。
2. は同意。私の場合はPrologに終始しているので、違った感想となる。
3. Cutはほとんど使わないので措いておくとして、バックトラックの挙動が
難しいことは正直たしか。
4. 同意。
5. 同意。
6. 同意。

PrologとしてはISO規格も決まってしまったし、3-5が改善することは
ないのではなかろうか。やはり、別の言語として我々が拡張するほかない。
私は典型的に6.で移植に苦しんできた。しかし、Prologプログラマの大勢は
Prologはロジック記述用に限定的に使うべきだと考えている。
ISO規格がシンプルなのも設計段階でそういう前提があったのだと思う。
問題はその割には、他の言語からの呼び出しに配慮がないこと。
共有サーバーとして、動作できることも必要だと思う。言語は適材適所で
低水準の部分はPrologは担わないなら、それなりのインターフェイスを
保証する必要はあると思う。
606デフォルトの名無しさん:2006/06/06(火) 19:40:16
私はPrologで全て処理してしまおう派なので、以下のPrologの長所の
方を強調することとなる。
1) 全くの素人がみても何が書いてあるか解る記述法。
2) 前にくどくど書いた 白い(雪). 的な、これこそ真にSmalltalkとでも
呼ぶべきプログラミング。全ての小思考が、即、プログラムとなるのは
大変なことだ。
4) 可読性から来る仕様変更要求からプログラムの改変までの迅速さ。
5) SDLC(SystemDevelopmentLifeCycle)を通じての超低コスト。
6) 極めてシンプルなデータベース。確かにassert retractは武骨だが。

4)は相対的な評価だが、私は電話で変更要求を受けて、数分後に改変を
完了してしまうというサービスをし続けてきたのでやはり強調せずには
いられない。

Z記法のようなものを全ての開発者に要求するのは現実的ではない。
Prologなら可能なのだから、ソフトウェアの高信頼性のために
トータルなPrologシステムの再興が必要と考える。
607デフォルトの名無しさん:2006/06/06(火) 21:16:19
606はlisper同様宗教臭い
608デフォルトの名無しさん:2006/06/07(水) 01:11:52
18年前からあるようなアプリケーションじゃなくて、
最近の業務システムやWebアプリケーションなんてのは
やはり無理なのでしょうか?
609デフォルトの名無しさん:2006/06/07(水) 05:19:03
GUIなど作り込みだしたら、やはり、超低コストと言うわけには
いかなくなる。それでそういう拡張をする気は私はない。
Telnet前提のアプリからWebアプリへの変換は当然あった。
これも、幸いソースが論理変数まで全て日本語だったおかげで、
トップの業務述語をlistingしてソースをparseすれば、
項目見出しとinput(select)タグのname属性の値は定義述語の引数の字面から
取得できる。
formタグのaction属性だけ引数渡しすれば、htmlは全て自動生成できる。
見てくれを気にしなければ、生成コストはゼロ。
メニュー画面だけ作ればよい。
見栄えがしないから、商品にはならないかも知れないが、中小企業の
業務ソフト開発とはこうあるべきものだと思う。
610デフォルトの名無しさん:2006/06/07(水) 09:42:11
>>606 コメントさせてください

最近では 1) が最も重要と私も思っている。実は 2)故なのかも知れない。
何故か 3)がないw

4) が問題で、ソースプログラム以外、仕様書もなく、しかも、そのソースを
手動で書き換えているのだと思う。述語間の連携情報があるわけもなく、
自動化の可能性がないとするとそれはそれで問題だ。
5) 4)のような作りだとすると確かに超低コストになるだろう。
6) Prologのデータベースは標準ではindexが振れないから、10万オーダーの
参照を繰り返すとさすがに苦しいのではないか。DBMSに備わっている
復元機能も必要だと思う。共用化の指針は?

>>609 どこに話のポイントがあるのかわからない。要するに
Prologは中小企業向きだということですか?
611デフォルトの名無しさん:2006/06/07(水) 10:26:12
>>610
仕様変更が来た時に、述語の変更を自動化することは将来的にも
不可能と思いますが。
indexのオプションは欲しい。共用化や復元に関しては、
自宅サーバー板のPrologサーバースレで扱っています。

最終的には、中小企業は管理業務を最小限に縮退させるべきで、それで
こそ中小企業の値打ちがある。採用するプログラム言語としては
Prologが最適だという主張になります。
612デフォルトの名無しさん:2006/06/07(水) 10:57:27
611によると、Prologは中小企業のインハウスな使い勝手しょぼしょぼの小規模ソフトという、ニッチな用途専門ってこと???

そういうのだとたしかに言語はなんでもいいでしょうね。
でも、安くしたいのなら市販の汎用パッケージ買ってきた方が賢い。
ひとにつくってもらうのでもPHPごときで充分なんじゃない。

言語の向き不向きより、単に請け負った611の趣味としか見えないなー。
あ、一度納めたら他の会社に変えられないような囲い込みの意味はあるかも。

だいたい609は他の言語やパッケージで、同等のアプリ作ったり保守したり、
チームで作業したことあるのかな?
613デフォルトの名無しさん:2006/06/07(水) 12:22:23
>>612 順序をひっくり返して答えると、
18年前に、それから、10年前にCOBOLで書いた業務システムを
Prologに置き換えたということだな。チームの経験は皆無。

Prologが大規模開発向きだとは思わない。オブジェクト指向とも相性が
いいとは思えない。だから、こういう組織ではロジック記述用に
使えば良いと思う。
中小企業では業務担当者自身がプログラミングすることが多く、
ちょっと上で話題とした可読性は極めて重要になる。この環境で
全てのマニュアルを含む仕様書を排除するとなると、やはり、言語は
選ばなくてはならない。
どんなに小さいシステムといっても、業務システムだと、Prologの
副目標数で数えても、数千、あるいは万のオーダーとなる。
しょぼしょぼと思っていたり、「PHPごとき」というような
取り組みでは、数週間で書ききるのは困難だ。
それからパッケージについては、以前はなかった。いまはそれも
有力な選択肢だろう。私のところで法令印刷などの部分では利用
させてもらっている。
614デフォルトの名無しさん:2006/06/08(木) 08:59:07
% _月 / _日 + _顧客番号 + _商品番号 + _数量 + _単価
% :-
% 出荷日正規化(_月,_日,_正規化された出荷日),
% 顧客番号正規化(_顧客番号,_正規化された顧客番号),
% 商品番号正規化(_商品番号,_正規化された商品番号),
% _金額 は 四捨五入(_数量 * _単価),
% insert into 売上(_正規化された出荷日,_正規化された顧客番号,
% _正規化された商品番号,_数量,_単価,_金額).
%
実務のプログラムはもう少し、項目、データチェックも多く、述語名も違うが。
kconsoleやteratermから、
?- 6/7+50179+2+3000+118.
のように入力する。1970年代前半は紙テープベースのオフィスコンピュータ。
伝票を読み取りながら紙テープ穿孔機を機関銃のように打って私も
オペレーションしていた。行末のピリオドが当時は"+"だったが。
それ以外は30数年前と同じ。
615デフォルトの名無しさん:2006/06/08(木) 09:01:35
行頭に%を付加すれば空白を挿入できると思ったのだが、
ちゃんと対策ができているのだね。
616デフォルトの名無しさん:2006/06/08(木) 09:56:29
>>614 またまた間違えた。
insert into 売上 values (_出荷日文字列, ... ) だったね。

valuesと ( の間に空白があるのは、こうしないとop定義だけで
Prolog項を構成できない。オペレータを駆使してSQLをインラインに
展開したいのだが、この例からも見て取れるようにうまくいかない。

?- select 顧客番号,金額 into X from 売上 where 顧客番号='50179'.

の場合も期待した実行が不可能なのはすぐに解るだろう。
617デフォルトの名無しさん:2006/06/08(木) 10:12:26
ここのところもっぱら、>>612氏に笑われるような領域の話題です。
私が書き込み続けているからそうなります。
前スレでのやりとりはあまりよく知らないのですが、もうすこし、
重い領域の話題は出てきませんか。
618デフォルトの名無しさん:2006/06/08(木) 18:30:43
白田秀彰の「インターネットの法と慣習」 第26回 法律とプログラミング
から引用して、Prolog のおもしろいそして適切とおもわれる使い方をご紹介します。

ttp://hotwired.goo.ne.jp/original/shirata/060228/
-----------------------------------------------------------
Prologを使った学生寮の規則の単純化の例がとても印象に残っている。私が覚えている限りではこうだ。

(1) 古くから続く学生寮には複雑な規則集がある。たくさんの条件分岐や例外規則が含まれていてとてもわかりにくい。

(2) そこで、その複雑な規則集をPrologのホーン節(真偽判定のみが記述された単純な文)に置き換えて表現する。

(3) 実行させれば、当然のように矛盾が存在するのでエラーが出る。

(4) Prolog化された規則集をデバッグし、さらに実行が効率的になるようにソース・コードの整理を進める。

(5) Prolog的観点からみてキレイに整理された規則集を、Prologのソース・コードから再び自然言語に翻訳しなおす。

(6) すっきりキレイにわかりやすくなった規則集のできあがり。
-----------------------------------------------------------
619デフォルトの名無しさん:2006/06/09(金) 11:56:23
>>614 そういう入力方法が現役であることに驚きます。
web経由など受注方法を工夫して、自動化できないのですか。

>>616 それで、
1) あくまでSQLの構文に近いを項を生成するようにする(SQLもどきになる?)。
2) sql_call(_SQL文字列) のような述語で呼び出し、_SQL文字列の構成は
呼び出す前にconcat_atomなどを使って行う。

のどちらを選択することが望ましいとお考えですか。
620デフォルトの名無しさん:2006/06/09(金) 23:01:52
>>618
そう、その方向性はちょっと考えてみた事がある。
客の要求を積み上げていって、それに矛盾が無いか、
条件が足りない点は無いかなどを検証する、というのは
Prologとか使うといい感じに組めないだろうか。

具体的にどうすればいいかは全然イメージまとまらないがなー。
621デフォルトの名無しさん:2006/06/10(土) 05:13:06
http://www.catb.org/jargon/html/B/bondage-and-discipline-language.html

Prolog が B&D 言語のリストに入ってる...
そんなもんなのかなぁ...
622デフォルトの名無しさん:2006/06/11(日) 06:21:47
>>619
受注簿を見ながらの入力はさすがに時代遅れ。あとせいぜい2年かな。

もともとSQL(Prologでなく)で書かれていたコードの移植というケースもある。
そういう場合も想定するなら、不完全でも 1) を用意する意味はある。
それからconcat_atomの仕様は他のスクリプト言語に較べ重いと思う。
623デフォルトの名無しさん:2006/06/14(水) 09:45:57
一連の書き込みにコメント
ひとつは、経験あるプログラマが経営者であって、システム管理者である、
というような極めて恵まれた条件では、Prolog以外の言語でも、実は
相当の高いパフォーマンス、低コストを実現できるのではないかという
疑問。Prologでは仕様記述の省略が利いたのかも知れないがそれぞれの
言語ここを強調すればというところはあると思う。
もう一つは、
Small is beautiful. ということは確かに認めるが、だからといって、
大企業ではPrologは向かないということにはならない。現状それ向きの
仕様になっていないというなら、改良すればよい。
624デフォルトの名無しさん:2006/06/14(水) 11:00:45
>>623
>大企業ではPrologは向かないということにはならない。現状それ向きの
>仕様になっていないというなら、改良すればよい。

具体的なイメージはありますか? 単なる一般論ですか?
625デフォルトの名無しさん:2006/06/14(水) 13:10:31
オブジェクト指向との相性云々だか、シンプルな仕様に慣れ親しんだ
Prologプログラマにとってオブジェクトを論理引数として引き回すのは
苦痛かもしれない。しかし、この言語以外のプログラマにとっては
当たり前のことで何の障碍にもならない。
Prologには資源とそれを管理するという視点がない。この点は確かに
問題であるのだが、ESPの時代とは、OOPの設計も変ってきている。
時代の要請を取り込んだ本格的なオブジェクト指向Prologの再構築が
必要だし、可能だと思う。
626デフォルトの名無しさん:2006/06/14(水) 13:29:08
>>264
事務計算をやってる立場から考えてみる。
COBOLって何か。
十進演算に豪たるものがあり、あとは書式制御。それだけ。
機械語とのインターフェイスを持ち、{ ... } のなかはすべて、
GHCのガード部のコミットのような機構により、すべて決定的に
実行されるようなProlog仕様の拡張が可能ならば、Javaではなく、
PrologがCOBOLの後継言語になる可能性はまだあると思う。
627デフォルトの名無しさん:2006/06/14(水) 13:36:37
>>626
COBOLはファイルシステムの管理に十進演算だけなどというレベルを
超えたコストを掛けており、その機構を無視しては語ったことにならない。
628デフォルトの名無しさん:2006/06/14(水) 16:09:41
もう事務屋黙れや
629lf:2006/06/14(水) 18:38:38
どれが誰の発言なのかがわからないので、議論がはっきりしません。
できれば皆(特に事務処理の実務にprologを使っているといっていた人)
コテハンをつけて欲しいです。
630If:2006/06/14(水) 20:45:52
なんでしょうか
6311f:2006/06/14(水) 21:11:59
これでいいですか
632|f:2006/06/14(水) 22:38:24
だめ
633lt:2006/06/14(水) 22:49:29
じゃあこれで
634!f:2006/06/15(木) 00:48:01
よんだ?
635デフォルトの名無しさん:2006/06/15(木) 00:49:23
>>625
>時代の要請を取り込んだ本格的なオブジェクト指向Prologの再構築が
>必要だし、可能だと思う。

だから具体的にいえよ
無理だろうがな
636デフォルトの名無しさん:2006/06/15(木) 01:04:30
637:-?:2006/06/15(木) 14:13:58
オブジェクト指向Prologって、恐ろしいものができそうな悪寒。
638デフォルトの名無しさん:2006/06/15(木) 16:32:13
>>625
つ Erlang
639デフォルトの名無しさん:2006/06/15(木) 18:41:07
>>637
つ visual prolog
640デフォルトの名無しさん:2006/06/15(木) 20:21:02
googleで prolog object oriented programming で検索したらけっこう出てきた。
641野尻湖:2006/06/19(月) 11:24:26
Prologユーザの数だけオブジェクト指向Prologはありそう。

今日のオブジェクト指向利用者から見てESPはどこが使いにくいのかな。
使いにくかった、というべきか・・・
642デフォルトの名無しさん:2006/06/19(月) 20:19:57
>>641
ESPが節を継承で階層的に整理できた記憶はあるんだけど、
オブジェクト指向で最重要な「カプセル化」もちゃんとやってたっけ?

俺、当時の時点で、ESP経験10行、OOPL経験0行。
643デフォルトの名無しさん:2006/06/20(火) 06:22:45
言語仕様上カプセル化出来なくても
各インスタンスの値が独立してて
メソッドでそれにアクセス出来るならOOPは出来るよ

その場合、使う側が直接フィールドを弄らないように気をつける
JavaScriptやPerlのOOPは確かそうじゃなかったっけ?

むしろOOPLとして最重要なのはポリモフィズムだと思う


分かりにくくてスマソ
644デフォルトの名無しさん:2006/06/20(火) 08:24:25
ビヤーン系の OO とアラン系の OO と、どっちを正とするかでそこら辺は変わって来るね。
OOPL で一番大事なのはメッセージパッシングだ。
645野尻湖:2006/06/20(火) 11:18:50
プログラミング態度(姿勢)としての
差分プログラミングという視点はどうでしょう。
646デフォルトの名無しさん:2006/06/20(火) 18:45:15
OOよりまず型の導入が先ではあるまいか
647デフォルトの名無しさん:2006/06/20(火) 18:52:26
先に型だけ入れちゃうとOOPLとして半端になるかと
入れるならOOと同時の方が型とかクラスとかの関係がスッキリする
648デフォルトの名無しさん:2006/06/20(火) 18:52:51
型なんてあると、泥沼にはまりそうな悪寒。
649デフォルトの名無しさん:2006/06/21(水) 01:34:58
650デフォルトの名無しさん:2006/06/21(水) 20:55:47
プログラム教えてくださいっていったら教えてもらえますか??
651デフォルトの名無しさん:2006/06/21(水) 20:59:08
単発質問スレ立てたりしてなきゃ教えてあげます。
652デフォルトの名無しさん:2006/06/21(水) 21:03:21
ありがとうございます!!
探索プロセスに関するプログラムなんですけど…。
教えて頂けますか?
653デフォルトの名無しさん:2006/06/21(水) 22:27:33
>>652
まずはじめに、
1. 周囲の人間に尋ねたか?
2. 図書館の資料を漁ったか?
3. 先生に泣きついたか?
それでダメなら、
Prologのシステム名、環境、課題等を示すこと。
654デフォルトの名無しさん:2006/06/21(水) 22:58:35
>>652
まずはじめに、
1. 「!」を使わない
2. ageない
3. 調べてないのに「調べたけど見つかりませんでした」と言わない
655652:2006/06/21(水) 23:12:34
調べましたよ。
googleで調べても詳しいことは見つかりませんでしたし。
図書館にも行きましたが、いまいちよくわかりませんでした。

今作ってるのは、A*アルゴリズムの探索プログラムです。
どなたか教えていただけないでしょうか?
656デフォルトの名無しさん:2006/06/21(水) 23:43:34
このスレの人達は痛いでつね。
657デフォルトの名無しさん:2006/06/21(水) 23:59:12
>>655
>googleで調べても詳しいことは見つかりませんでしたし。
ttp://www.google.co.jp/search?hl=ja&q=a-star+prolog&&lr=
ttp://www.google.co.jp/search?hl=ja&q=%E3%82%A8%E3%83%BC%E3%82%B9%E3%82%BF%E3%83%BC+%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0&lr=lang_ja

これ以上詳しく解説しろと言うのなら俺にはむりだ。
658デフォルトの名無しさん:2006/06/22(木) 00:47:30
>>649
Robert Kowalski and Fariba Sadri
"Prolog became a niche language and was overshadowed by C++ and Java"
659デフォルトの名無しさん:2006/06/22(木) 09:53:08
>>655
図書館に行ってもA*すらわからないようでは調べたとは言わん。行っただけ。

660デフォルトの名無しさん:2006/06/22(木) 09:53:47
>>655
「Prolog と AI 2
AIプログラミング」 I.Bratko著 安部憲広・田中和明訳
近代科学社 1996 IABN4-7649-0254-0

にかなり詳しい説明がある。
661660:2006/06/22(木) 09:55:54
訂正 IABN4 は ISBN4 のまちがい
662660:2006/06/22(木) 19:31:19
再訂正 ICBM4のまちがいだった
663デフォルトの名無しさん:2006/06/22(木) 19:36:41
つまんねーんですけど
664お前と同じ受講科目:2006/06/26(月) 12:24:05
>>655

 おまえ、水曜1・2限に知識情報処理演習受けているよな?

先生かTAにきけよ。ここできくなよ。DQN?
665デフォルトの名無しさん:2006/06/26(月) 12:46:36
>>655>>664
関西学院大学理工学部情報科学科
とかいうところ?
666デフォルトの名無しさん:2006/06/27(火) 19:12:51
667デフォルトの名無しさん:2006/08/02(水) 13:37:32
過疎ってきてるね
668デフォルトの名無しさん:2006/08/02(水) 13:55:10
ナンプレ解こうぜ
669デフォルトの名無しさん:2006/08/15(火) 20:21:14
ICOTの渕一博先生が御逝去されました。

http://www.asahi.com/obituaries/update/0814/008.html

関連スレということで場所をお借りして、
先生の御冥福をお祈りしたいと思います。
670デフォルトの名無しさん:2006/08/15(火) 20:32:50
671デフォルトの名無しさん:2006/10/03(火) 19:21:56
prologでのテキスト処理について触れたページって全然ないな
672デフォルトの名無しさん:2006/10/03(火) 23:09:32
今のご時世テキスト処理って言ったらスクリプト衆だからなぁ。
673デフォルトの名無しさん:2006/10/20(金) 17:07:59
誰かS-PrologのマニュアルをHTMLかPS/PDFに直してくれんかのう
ウチのjgroffじゃ必ず化ける
674デフォルトの名無しさん:2006/10/21(土) 01:42:22
>673
S-Prolog にマニュアルなんてあったっけ?
675デフォルトの名無しさん:2006/10/21(土) 16:44:19
SLOG.FINなどがあるよ
さとうさんのページから落とせるアーカイブにある
676デフォルトの名無しさん:2006/10/21(土) 21:54:43
>675
ああ、あったあった。
普通にテキストエディタで読んでたな
677デフォルトの名無しさん:2006/10/23(月) 13:32:46
そうなあ
地道に整形するか
678デフォルトの名無しさん:2006/10/23(月) 18:32:49
>677
Prologで整形してみるとか
679デフォルトの名無しさん:2006/10/23(月) 18:40:44
prologって(意外と)text整形に向いてないよなあ。
構造解析は楽だけど、非定型な文字列からちょっと正規表現で
抜き出してくるような処理が面倒。
680デフォルトの名無しさん:2006/10/24(火) 16:34:06
schemeでのgaucheみたいな処理系が欲しいな
681デフォルトの名無しさん:2006/10/30(月) 20:18:21
申し訳ないんですが
差分リストについて簡単に説明してもらえますか?
一応調べたんですが
[a,b,c]と[c]で作った[a,b]が差分リストなのか
[a,b,c]と[c]で差分リストなのかよくわかりません
682デフォルトの名無しさん:2006/10/31(火) 17:06:26
どうしてまずYAHOOやgooで調べないんだ?失礼じゃないか?
683デフォルトの名無しさん:2006/11/01(水) 08:26:54
なぜ調べないか→
調べるということがどういうことかわかってないから。
「一応調べた」などと書いてしまうのは→
調べるということがどういうことかわかってないということに気付いてすらいないから。
684デフォルトの名無しさん:2006/11/01(水) 19:05:26
「一応調べた」というのは「拝啓」みたいなもので、特に意味はない。
685デフォルトの名無しさん:2006/11/02(木) 18:31:51
厨房でごめんなさい
prologで言語処理する場合の例を教えてください
再帰でだめぽ。。
686デフォルトの名無しさん:2006/11/02(木) 19:57:48
どうしてまずYAHOOやgooで調べないんだ?失礼じゃないか?
687デフォルトの名無しさん:2006/11/02(木) 20:07:47
しかも質問の意味がわからなさすぎる
サイキダメポって何
688デフォルトの名無しさん:2006/11/04(土) 00:18:57
再起不能ってやつかぁ・・・
689デフォルトの名無しさん:2006/11/04(土) 01:59:42
誰がうまいこといえと
690デフォルトの名無しさん:2006/11/04(土) 04:31:15
勃起不能に見えた
691デフォルトの名無しさん:2006/12/01(金) 17:44:50
SWI-Prolog / XPCEでグラフ書くサンプルない?
692デフォルトの名無しさん:2006/12/06(水) 18:49:43
swi-pl で乱数を生成するには random/1 でいいみたいですけど,
モジュールをロードしなければいけないんですよね?
それでそのモジュールのロードのしかたが分からないのですが,
どうすればいいのでしょうか?
693デフォルトの名無しさん:2006/12/08(金) 00:19:23
windowsなら、これでチッサナwindowがでるはず…
manualとreference
http://hcs.science.uva.nl/projects/xpce/UserGuide/
http://gollem.science.uva.nl:8080/

Welcome to SWI-Prolog (Multi-threaded, Version 5.6.23)
Copyright (c) 1990-2006 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

1 ?- use_module(library(pce)).
%  library(lists) compiled into lists 0.00 sec, 10,116 bytes
% library(quintus) compiled into quintus 0.03 sec, 22,604 bytes
% library(pce) loaded into pce 0.13 sec, 323,420 bytes

Yes
2 ?- new(@demo,dialog('Demo Window')).

Yes
3 ?- send(@demo,open).

fileから読み込む場合は、
:- use_module(library(pce)).
で動くはず.

普段の環境がubuntuだし、xpceも使わないから詳しいことはムリ。
後は
ttp://hcs.science.uva.nl/projects/xpce/UserGuide/sec-2.2.html
を見てくれ。
694デフォルトの名無しさん:2006/12/08(金) 18:03:43
神・・・!
695デフォルトの名無しさん:2006/12/09(土) 18:58:05
お前等処理系何使ってるよ?
俺はS-Prolog
696デフォルトの名無しさん:2006/12/10(日) 16:48:30
SWI-Prolog.

ところで,引数の結果(true/fail)を反転させる

not(X) :- X, !, fail.
not(_).

って,カットを使わない書き方ある?
697デフォルトの名無しさん:2006/12/14(木) 14:39:44
無い
698デフォルトの名無しさん:2007/01/05(金) 14:00:43
S-Prologは改造せんとつらかろ。ネタか?といいつつ漏れはJLogだが。
699デフォルトの名無しさん:2007/01/05(金) 14:48:20
改造のベースにいいよ
700デフォルトの名無しさん:2007/02/13(火) 22:55:29
Prologよくわかんないんだけど、
「工藤真一は蘭が好きだ」と「コナンは工藤真一である」から
「コナンは蘭が好きだ」を推論するみたいなのって
Prologでどう書けばいいんでしょうか。
701デフォルトの名無しさん:2007/02/13(火) 23:13:33
>>700
いろいろやりかたあるんだろうけど、原理としては、

likes(工藤真一,蘭).
likes(V,W) :- likes(U,W), identicalPerson(U,V).
likes(V,W) :- likes(U,W), identicalPerson(V,U).
identicalPerson(コナン,工藤真一).

という公理系(知識)をシステムに与えておくんだろうな。

で、?- likes(X,Y) とか ?- likes(コナン,Y) とかをシステムに訊けばいい。
?- likes(コナン, 蘭) とか訊けば、「コナンは蘭が好きだ」が証明できるか検証できる。

実際のプログラミングでは仕様次第でさらに洗練する余地あるけど、考え方はこんなかんじ。
702デフォルトの名無しさん:2007/02/13(火) 23:39:45
ありがとうございます。早速やってみたんですが、以下のようになってしまいました。処理系はSWI-Prologです。

$ cat try.swi
likes(shinichi,ran).
likes(V,W) :- likes(U,W), identicalPerson(U,V).
likes(V,W) :- likes(U,W), identicalPerson(V,U).
identicalPerson(konan,shinichi).
$ prolog -s try.swi
[中略]
?- likes(konan,X).
ERROR: Out of local stack
Exception: (27,926) likes(_L502743, _G158) ?(←デバッグモードにはいった?)

何かもうひと工夫いるのでしょうか。
703700:2007/02/13(火) 23:53:30
ああそうか。そうだなwww>>701
ごめん、恥ずかしいし、一旦逃げるわ。スタコラ
704701:2007/02/13(火) 23:55:07
ああそうか、そうだなwww>>702
ごめん恥ずかしいので一旦逃げるわ。
(>>703は完璧なアンカー間違い、ってことで俺のあわて具合がわかるだろう)
705デフォルトの名無しさん:2007/02/14(水) 01:18:55
>>702
この場合、事実は
likes(shinichi,ran).                   真一は蘭が好き。
identicalPerson(konan,shinichi).           コナンは真一と同一人物。
のふたつ。
推論規則は
likes(V,W) :- likes(U,W), identicalPerson(U,V).  UはWが好き且つUはWと同一人物ならば、VはWが好き。
ひとつで充分。なおprologではこの3項目の順序は関係ない。

規則がひとつしかないと、どんな不都合があるか?
その不都合の回避方法は?
なぜ>>701は恥ずかしがっているか?
などを考えてみると良い勉強になると思う。
706デフォルトの名無しさん:2007/02/14(水) 02:14:08
である(A,B) :- 同一人物(A,B).
である(A,B) :- 同一人物(A,C),である(C,B).
同一人物(コナン,工藤真一).
好きだ(工藤真一,蘭).
好きだ(A,B) :- である(A,C),好きだ(C,B).
好きだ(A,B) :- である(B,C),好きだ(A,C).
/* 大体こんな感じになるのでは。でも相当問題が残っている */
?- 好きだ(X,Y). /* はうまくいく。 */
707デフォルトの名無しさん:2007/02/14(水) 07:17:33
>>706 問題点
1) 同一人物の引数順が自由でない。
2) 同一人物(まゆ,蘭). を追加して ?- 好きだ(X,Y). を
実行すると、解として、
X = コナン,
Y = まゆ が二度現れる。
708デフォルトの名無しさん:2007/02/14(水) 08:33:51
同一人物はいかにも重い。実は(A,B) :- ... でしょうw

709705:2007/02/14(水) 09:42:41
間違った。ひとつで充分な規則は、
likes(V,W) :- likes(U,W), !, identicalPerson(V,U).
(UはWが好き かつ VはUと同一人物 ならば VはWが好き。)
だった。

ごめん>>701を茶化してる場合じゃなかった、漏いらの方が恥ずかしい。。。
710デフォルトの名無しさん:2007/02/17(土) 06:07:06
順序構造をある程度考えないと無限ループに陥りやすいんじゃない
特に、よく考えないで再帰するのはちょっと
711デフォルトの名無しさん:2007/02/17(土) 08:13:33
囲碁・将棋で「早見え」といいますね。数十手先の局面の画像が
瞬時に浮かぶ。「早」はその早(速)さの度合いをいっている。
Prologの再帰を書くときに、こうして、ああなって、そうしてと
頭の中でDebugのようなことはしないから、「見え」してるには
違いないのだが、未来の局面の画像にあたるようなものがないね。
何を見ているのだろう。
712デフォルトの名無しさん:2007/03/17(土) 10:17:03
棋士になるのと同じくらい、小さな時から不断の努力と経験を積んだ、
Prologプログラマが一人でもいたら面白いですね。
四歳の頃から毎日毎日Prolog。そういう人に会いたい。
713デフォルトの名無しさん:2007/03/17(土) 13:16:30
ホーア論理でしか思考できないバカが生まれそう。様相論理とかには死んでも対応できない。
714デフォルトの名無しさん:2007/04/07(土) 02:10:53
手続きでしか思考できないバカですが...

> 様相論理とかには死んでも対応できない。
何か不都合があるんですか?
715デフォルトの名無しさん:2007/04/09(月) 07:15:59
阿含経を理解できないとバカかということになりますね。
716デフォルトの名無しさん:2007/04/09(月) 07:24:04
ほらバカがきたぞ
717デフォルトの名無しさん:2007/04/09(月) 07:31:03
おはよう(笑)
718デフォルトの名無しさん:2007/04/11(水) 23:32:58
>>713

>様相論理とかには死んでも対応できない。

様相論理が使える MProlog とか Qu-Prolog とかを使っていればいいんじゃね。
719デフォルトの名無しさん:2007/04/19(木) 17:24:43
SWI Prologでprologの勉強を始めようとしています。
図書館でPROLOG入門(ISBN4-7819-352-5)と言う本を借りてきて
最初の例
apple.
?- apple.
と入力してみるのですが、どうも本の通りになりません。
どうしたらよいでしょうか。
どうやらプロンプトに始めから?-とでているので、
何かモードのような物があるのでしょうか。
720デフォルトの名無しさん:2007/04/19(木) 18:28:56
1 ?- [user].
|: apple.
|: (ここでCtrl-D)
% user://1 compiled 0.01 sec, 256 bytes

Yes
2 ?- apple.

Yes
3 ?-
721デフォルトの名無しさん:2007/04/19(木) 22:37:51
>>719 Prologの解説書としては
「法律家のための コンピュータ利用法 論理プログラミング入門」
加賀山茂著 有斐閣 ISBN4-641-07541-7 という本がおもしろいです。
Prologの解説書だけで50冊、部分的に解説した物も含めれば100冊近く
発刊されていてそれぞれ特長があり、どれもおもしろいです。
後藤滋樹さんの本は最もオーソドックスな解説書かもしれません。
722デフォルトの名無しさん:2007/04/20(金) 09:33:46
>>679
相当な亀ですが。
Prologで書かれた、正規表現を使っての検索述語を含む
ライブラリはどこかに公開されていますか。
723デフォルトの名無しさん:2007/04/21(土) 08:03:12
>>719
プロンプトをbackspaceで消してassertするのは
Prolog-KABAの流儀かな
724デフォルトの名無しさん:2007/04/27(金) 09:42:46
>720,721,723
有難うございます。
処理系によって違うみたいですね。
とりあえず>720さんのやり方でうまくいったので、
マニュアルを見ながらがんばってみたいと思います。
725デフォルトの名無しさん:2007/05/11(金) 07:30:47
このスレを見てる人に質問です。
Prologと他の系とデータ交換はどのような方法をとっていますか。
現在のPrologのシンプルな仕様から見て、複雑なロジック部分だけ
Prologを呼び出すという使われかたが多いのではないでしょうか。
その際の呼ばれかたに関する話題が少なかったように思います。
私はというと、固有のポート番号を割り当ててのWebに類似した
インターフェイスを持つPrologサーバーを主体にしています。
これは速い方法ではありません。みなさんの解決法をききたい。

726デフォルトの名無しさん:2007/05/13(日) 19:05:03
Prologどころかプログラミングの初心者です。Prologがこの頃流行らない
のは、グラフィックが不得手だからとききました。
1) どうしてPrologがグラフィックを得意としないのか
2) グラフィックが得意でない言語はなぜ流行らないのか
を教えてください。
727デフォルトの名無しさん:2007/05/13(日) 20:02:56
>>726
前提条件の「グラフィックが増えてだから」に納得できない
なので(2)はスルーするよ

1) Prologが得意としないのではなく、Prolog用のグラフィックライブラリを人が得意としないから
 そして人は「人が不得手ではなく、Prologが不得手なのだ」と錯覚する
 と思っている
728デフォルトの名無しさん:2007/05/16(水) 18:29:19
>>726
代表的なPrologの処理系にはグラフィックライブラリがあり、それを
利用するためのPrologの組込述語がある。ですから、>>727
通りだとおもいます。
グラフィックのビットマップ全体を計算して書き換える部分を
X is M * N,
のようなPrologのSubgoalで処理する場合、その処理が数十万回の
繰り返しを伴うような場合は、スタックのpush,popの情報量の多い
Prologは確かに不向きです。AdobePhotoshopをPrologで書き換える
なんてちょっと考えられないですね。
729デフォルトの名無しさん:2007/05/21(月) 05:57:13
>>722
これまた亀ですが、
少なくとも私は見たことない。公開されてるものは
ないのではないか。
730デフォルトの名無しさん:2007/05/21(月) 11:16:42
文字検索というと以下のようなコードが代表的なものですね。
data(abcdefghijklmnop).
?- atom_chars(Data,L),
append(_,[A|R],L),
append(B,[C|_],R),
member(A,[c,e,f]),C @>= k,C @=< m,
concat([A,B,C],X).
質問2行目からmemberから始まる4行目から解析して
最後のconcatのA,B,Cを見つけ出すことは難しいですね。
ここでは質問者が陽にconcat/2を与えています。
search(Data,Q,X) といった述語を定義しようと思ったときの
課題ということですが。
731ミスタイプ:2007/05/21(月) 11:18:36
質問2行目からmemberから始まる4行目から解析して ->
質問2行目からmemberから始まる4行目まで解析して
732730:2007/05/21(月) 11:31:35
さらに訂正
?- data(Data),atom_chars(Data,L),
...
ですね。
733デフォルトの名無しさん:2007/05/23(水) 16:02:14
>>730
確かに検索の場合はこのような質問もすることはあるが、
置換には対応できないだろう。やはり、きっちりと規則を
書いて、その上で検索や置換をしていくのが、
Prologプログラマとしての正しい態度だと思う。
734デフォルトの名無しさん:2007/05/25(金) 01:07:17
学校の課題なんですけど、家系図が与えられ、
人名Aと家族関係の述語名(定義済み)Pを与えて、AのPにあたる人名Bを求める述語relation(P,A,B)を定義するにはどうしたらいいですか?
735デフォルトの名無しさん:2007/05/25(金) 01:44:40
課題は自分で解きましょう。
736デフォルトの名無しさん:2007/05/25(金) 07:24:43
>>734
relation(P,A,B) :- P(A,B). と定義したいところですね.これは、
prologでは不可なのです。関数部分に変数を書くことはできません。
仮りに実行時 ?- ... ,P(A,B), ... の時に
Pが具体化されている(例えばP=兄弟)としても、 それ以前の問題として、
?- assertz((relation(A,B) :- P(A,B))). がエラーとなります。
それで、P(A,B) のところに少なくとも二つの「メタ述語」を使います。
関数部分にPがこないように。Pが引数となるように。
737デフォルトの名無しさん:2007/05/25(金) 07:32:15
?- assertz((relation(P,A,B) :- P(A,B))). がエラーとなります。 に訂正。頭部の引数のPが落ちてた。
738デフォルトの名無しさん:2007/05/25(金) 15:11:36
ありがとうございました。解決しました。
739デフォルトの名無しさん:2007/05/25(金) 22:53:55
>736
> それで、P(A,B) のところに少なくとも二つの「メタ述語」を使います。
2つというのがわからない。

relation(P,A,B) :- call(P,A,B).

では駄目?
ひょっとして処理系依存かな。
740デフォルトの名無しさん:2007/05/26(土) 06:38:31
>>739
なるほど、そうですね。私が使っているIF/Prologでは
relation(P,A,B) :- call(P,[A,B]). と定義できます。これはISO標準では
ないので、SWI/Prolog や GNU prolog で確かめてみたところ
上記のcall/2はありませんが、
relation(P,A,B) :- call(P,A,B).  で定義できます。ただ、引数をいくつ
までとれるかは処理系によって異なり SWIが最大6 GNUは11のようです。
ISOの標準規格は call/1 しかなかったように思うのですが、最近追加
されたのでしょうか?


741デフォルトの名無しさん:2007/05/26(土) 07:28:19
SWI/PrologはSWI-Prologが正しい。
742デフォルトの名無しさん:2007/05/28(月) 20:54:19
>>740
正確さを欠いていました。call/2はあります。第二引数をPの引数ならびと
するのではなく、Pの第一引数と解釈して、存在します。
それにしても、このcall/2-6は不自然ですね。どうしてこういうことに
なってしまったのでしょう。
743デフォルトの名無しさん:2007/06/06(水) 21:26:50
KL1 の話で申し訳ないんですが、KL1 には Prolog のような (p ; q) や not(p) はありませんよね?
これらを使いたいときにはどのようにするのが普通なのでしょうか。

KL1、興味あって調べているんですが、どうにも資料が少なくて大変です orz
744デフォルトの名無しさん:2007/06/10(日) 05:00:36
>>743
実際にKL1を動かしたことことはないが…
Prologのように失敗する述語を書いたら負けなんジャマイカ
つまり(p ; q)のpやqは常に成功するように記述する
ただしリストを具体化することで結果を示す
成功なら要素を持つリスト、失敗なら空リスト
するとpやqが本来1引数なら2引数にして
p(X, Y1), q(X, Y2), merge(Y1, Y2, Y)
と書ける
Yが空リストに具体化されればどちらも失敗
そうでなければどちらかあるいは両方が成功
not(p)はそもそもpが失敗しなければ不要
要は常に成功してリストを具体化する
KL1プログラミングとはプロセスネットワークの構築

と、共立出版のGHC本を読んだだけの俺が妄想してみた
745デフォルトの名無しさん:2007/06/10(日) 11:02:56
なるほど。なんか新しい世界が拓けた気がする。
とてもありがとうございました m(_ _)m
746デフォルトの名無しさん:2007/06/12(火) 17:14:00
prologで微分をするプログラムを作ったのですが計算した結果が、例えば、
0*x^2+a*(2*x^1*1)+(0*x+b*1)+0
のように無駄に長くなってしまいます。そこでこれを簡単化する述語simple(P)を作りたいのですがどのようにしたら良いでしょうか?
?- simple(0*x^2+a*(2*x^1*1)+(0*x+b*1)+0).
2*a*x+b
yes
できれば上のような動作がするぐらいのものが作りたいです。
少なくとも余計な0,1を除去するくらいはしたいのですが・・・
お願いします。
747デフォルトの名無しさん:2007/06/12(火) 21:15:05
simple1(0*_, 0).
simple1(_*0, 0).
simple1(0+E, F) :- simple1(E, F).
simple1(E+0, F) :- simple1(E, F).
simple1(1*E, F) :- simple1(E, F).
simple1(E*1, F) :- simple1(E, F).
simple1(E^1, F) :- simple1(E, F).
simple1(E1+E2, F1+F2) :- simple1(E1, F1), simple1(E2, F2).
simple1(E1*E2, F1*F2) :- simple1(E1, F1), simple1(E2, F2).
simple1(E1^E2, F1^F2) :- simple1(E1, F1), simple1(E2, F2).
simple1(E, E).

simple(E,G) :- simple1(E,F), (E = F -> F = G; simple(F,G)).

ただし->を使っているのが今一つ。cutで書き換えるにはどうすればいいんだろう?
748デフォルトの名無しさん:2007/06/13(水) 13:42:23
simple(E,G) :- simple1(E,F), simple(E,F,G).
simple(E,E,E):-!.
simple(_,F,G):-simple(F,G).

因みに、simple1のゴールの最初にも全てカットがあったほうがよいと思う。
  simple1(_*0, 0):-!.
  simple1(0+E, F) :- !,simple1(E, F).
749デフォルトの名無しさん:2007/06/27(水) 03:10:39
KL1 では、次の main01 と main02 はどちらも終了しないと思ったんですけど、この認識で合ってますか?

main01 :- foo(42, X)
main02 :- foo(Y, Y).
foo(X, X).

KLIC の make は諦めました。自分の知識じゃどうにもむりぽ (´・ω・`)
750デフォルトの名無しさん:2007/06/27(水) 05:44:41
とりあえず実行した結果、終了しなかった。
1 perpetually suspending goals found だって。

Debian とかだと KLIC のバイナリ配布してるよ。
751デフォルトの名無しさん:2007/06/27(水) 10:51:40
>>750
ありがとうございます。お手数をおかけいたしました……。

Debian ではバイナリ配布していたんですね。
KLIC のために Linux 導入するかどうか、ちょいと検討してみます (´・ω・`)
752初心者:2007/06/27(水) 10:54:09
集合XとYの差集合Zをdelを使ってもとめるprologのプログラム
はどうすればいいのか誰か教えてください。
753デフォルトの名無しさん:2007/06/27(水) 11:47:40
差集合(X,[],X).
差集合(X,[A|R],Z) :- del(A,X,X2),差集合(X2,R,Z).

delの定義は自分でやってみてください。
754デフォルトの名無しさん:2007/06/27(水) 11:53:11
Yを明示するには、
差集合(X,[],X).
差集合(X,Y,Z) :- Y=[A|R],del(A,X,X2),差集合(X2,R,Z).
755デフォルトの名無しさん:2007/06/27(水) 11:58:31
わざわざ以下のように定義し直すこともある。

差集合(X,Y,Z) :- 差集合の一(X,Y,Z).

差集合の一(X,[],X).
差集合の一(X,[A|R],Z) :- del(A,X,X2),差集合の一(X2,R,Z).
756デフォルトの名無しさん:2007/06/27(水) 14:54:17
リストL1の要素であるがL2の要素ではないものを
バックトラップでもとめるPrologプログラムを作るには
どうすればいいのだろう?だれか教授ください。
757思考者:2007/06/27(水) 14:59:02
リストL1の要素であるがL2の要素ではないものを
バックトラップでもとめるPrologプログラムを作るには
どうすればいいのだろう?だれか教授ください。
758デフォルトの名無しさん:2007/06/27(水) 15:32:14
リストL1の要素であるがL2の要素ではないものをバックトラップでもとめるPrologプログラム(L1,L2,X) :-
member(X,L1),not(member(X,L2)).
759デフォルトの名無しさん:2007/06/27(水) 15:37:11
member/2は多くの処理系で組込述語になっているが、
定義するとすれば、
member(A,[A|R]).
member(A,[_|R]) :- member(A,R).
760デフォルトの名無しさん:2007/06/27(水) 15:43:21
実際には差がありませんが、
member(A,[A|_]).
member(A,[_|R]) :- member(A,R).

に第一節を訂正します。
761デフォルトの名無しさん:2007/06/28(木) 09:49:19
>>758 の述語名はさすがに長すぎるだろうから、
差集合バックトラック版(X,Y,_差集合要素) :- member(_差集合要素,X),not(member(_差集合要素,Y)).
として、これを使って差集合を表すリストを得るには
差集合(X,Y,Z) :- findall(_差集合要素,差集合バックトラック版(X,Y,_差集合要素),Z).
でよい。
findall/3という便利な組込述語があります。
述語名の後スラッシュと整数が書かれることが多いですが、
この整数は引数の数を示しています。
762デフォルトの名無しさん:2007/06/29(金) 14:32:53
>>753
del(_,[],[]).
del(A,[A|R1],R2) :- del(A,R1,R2).
del(A,[B|R1],[B|R2]) :- not(A=B),del(A,R1,R2).
763デフォルトの名無しさん:2007/07/02(月) 13:23:13
>>762
このほうがスタック効率と無駄なバックトラックを発生させずにすむ

del(_,[],[]):-!.
del(A,[A|R1],R2) :- !,del(A,R1,R2).
del(A,[B|R1],[B|R2]) :- del(A,R1,R2).
764デフォルトの名無しさん:2007/07/02(月) 13:49:35
>>763
そうですね。
ただ、第二節の定義のような末尾以外のカットをバグの原因となるとして
嫌うPrologプログラマが多いですね。
冗長であっても論理式としての完全さを追求した方がよいと
いう立場から>>762を書きました。

765迷問者:2007/07/03(火) 09:02:44
キーボードから項を入力し、それをディスプレイに表示し、
stopの入力で処理を終了させるprologプログラムはどう書けば
いいのか教えてください。
766デフォルトの名無しさん:2007/07/03(火) 09:22:36
>>765
入力項を表示 :- read(X),(X=stop;write(X),nl,入力項を表示).

767766:2007/07/03(火) 09:31:05
(X=stop;write(X),nl,入力項を表示).
の部分は
入力項を表示(stop) :- !.
入力項を表示(X) :- write(X),write('.'),nl,入力項を表示. /* ピリオド付けました */
入力項を表示 :- read(X),入力項を表示(X).
でもよい。
実は最も一般的な書き方は、
repeat.
repeat :- repeat.
入力項を表示 :- repeat,read(X),(X=stop;write(X),write('.'),nl,fail).

というバックトラックを強調した定義かも知れません。
768迷者:2007/07/03(火) 13:57:40
入力ストリーム(キーボード)から整数Nを一つ入力し
Nが偶数ならばgusu.txt.のファイルに、奇数ならkisu.txt.ファイルに
書き出すPrologプログラムはどう書けばいいのですか?
769デフォルトの名無しさん:2007/07/03(火) 14:24:03
>>768
なぜPrologで?
770デフォルトの名無しさん:2007/07/03(火) 14:27:06
>>768
仮にキーボードを標準入力ファイル stdin とします。
偶数奇数で書き分ける :- open(stdin,read,Input),read(X),偶数奇数で書き分ける(X),clo
se(Input).
偶数奇数で書き分ける(X) :- 0 is X mod 2,open('gusu.txt',append,Output),write(Outpu
t,X),close(Output).
偶数奇数で書き分ける(X) :- 1 is X mod 2,open('kisu.txt',append,Output),write(Outpu
t,X),close(Output).
771デフォルトの名無しさん:2007/07/03(火) 14:27:13
日本語が使えるProlog処理系はありませんか?
フリーでWindowsで動くとありがたいです。

772デフォルトの名無しさん:2007/07/03(火) 14:42:14
>>771
SWI-Prolog はOSSです。
K-Prolog は 個人だとライセンス料8000円くらいです。
どちらも
:- op(800,xfx,は).
:- op(750,xf,才).
:- op(850,xf,だ).
私 は 58 才 だ. /* これ立派な述語定義です */

くらいのことはやれます。
773デフォルトの名無しさん:2007/07/03(火) 15:36:35
>>771
これはSWI-Prologで使っている西暦和暦変換の中の一部です。
西暦和暦変換の二(_元号開始時西暦整数,_最終年号,_西暦年整数,_和暦年) :-
_元号開始時西暦浮動小数点数 is _元号開始時西暦整数 * 1.0,
_西暦年浮動小数点数 is _西暦年整数 * 1.0,
_西暦年浮動小数点数 < _元号開始時西暦浮動小数点数 + _最終年号,
Y is _西暦年整数 - _元号開始時西暦整数 + 1,
年漢字表現(Y,L),
atom_chars(_和暦年,L),!.
774773:2007/07/03(火) 15:42:44
ごめんなさい。「私が使っている」です。SWI-Prologに付いてくる
DEMOプログラムではありません。
775デフォルトの名無しさん:2007/07/04(水) 22:02:11
JVM上で動くPrologない??
776デフォルトの名無しさん:2007/07/04(水) 22:09:34
Prologって並列処理書けるの?
777デフォルトの名無しさん:2007/07/04(水) 22:20:52
昔はGHCといえばGuarded Horn Clauseでした。今は…
778デフォルトの名無しさん:2007/07/04(水) 23:15:38
779デフォルトの名無しさん:2007/07/05(木) 01:04:23
>>775
jPrologとかJPrologとか
780デフォルトの名無しさん:2007/07/05(木) 01:23:39
横槍スマソ。
当方prolog初心者。

flattenのプログラムをappend使わないで書きたいんだけど、
いかんせん差分リストがよくわからないので書けない・・・。
どうか御助言頂けないだろうかorz
781デフォルトの名無しさん:2007/07/05(木) 02:18:00
俺もヘタレなんでアレだがSWI-Prologではこれで動いたよ

flatten(X, Y) :- flatten(X, Y, []).

flatten([], Y, Y).
flatten([X|Rest], Y, Z) :- flatten_element(X, Y, Z1), flatten(Rest, Z1, Z), !.

flatten_element(X, [X|Z], Z) :- var(X), !.
flatten_element(X, [X|Z], Z) :- \+ is_list(X), !.
flatten_element(X, Y, Z) :- flatten(X, Y, Z).
782初心者:2007/07/05(木) 08:13:17
>>777
AITEC(ICOT)はグラスゴー大学に対して抗議したのだろうか。
783デフォルトの名無しさん:2007/07/05(木) 08:15:13
>>775
P#とかも調べてみたら?
784デフォルトの名無しさん:2007/07/05(木) 08:21:43
>>776
昔はC言語インターフェイスを使って書いたもの。
真っ先に作ったのが fork()を呼びだす Thread述語 だった。
今はSWI-Prologが使われることが多くなり、これを
書く必要がなくなった。
785780:2007/07/05(木) 10:11:48
おお、ありがとん
参考にさせて頂きます

・・・へたれですまないんだけど、"\+"って何の記号ですか?orz
特殊記号だからググれない('A`)
あー本借りた方がいいかな・・・
786780:2007/07/05(木) 10:18:30
連投スマソ。
意味はノットかな?
違ってたら恥ずかしいなorz
787デフォルトの名無しさん:2007/07/05(木) 10:20:55
notで正解。
788780:2007/07/05(木) 10:25:49
有難う、勉強になりますた(^ω^)
789デフォルトの名無しさん:2007/07/05(木) 10:51:47
\+ のほかに not も同じ意味で組込述語になっている処理系が
多いと思います。
Webアプリで<form>+<input>,<textarea>タグなどを使って
質問をサーバに送るときなどは\+だと字化けする危険があります。
もしnot/1が組込述語にない場合は
not(X) :- \+(X).
を定義して、以後notを使った方が無難です。
790デフォルトの名無しさん:2007/07/05(木) 13:40:11
学期末だなぁ
791デフォルトの名無しさん:2007/07/05(木) 14:53:08
>>778>>779サンクス
並列できるのか。
だったら並列ばやりであるし、prolog復権するかな?

個人的にはSQLに適用したりすると面白そうなのでjrologで遊んでみるかな。
792デフォルトの名無しさん:2007/07/05(木) 15:04:26
>>791
それはない
793デフォルトの名無しさん:2007/07/05(木) 15:07:14
>>791
並列(thread)が出来ないとPrologサーバの実行制御が上手く
いきませんね。
Prologの場合、仮に外部データベースの参照がないとしても、
数秒を要する質問は当たり前で、その間次の質問が受け付け
られなくなってしまう。
794デフォルトの名無しさん:2007/07/05(木) 15:15:48
>>791
jrologはないけど、2010年ころから、
Prologの大反攻が始まると予告しておきます。
795デフォルトの名無しさん:2007/07/05(木) 17:31:05
>>781
こういうプログラムを見るとPrologって凄いな思う。
796デフォルトの名無しさん:2007/07/05(木) 18:16:07
>>781
flatten/3 の方の第二節の第二、第三引数にのみ着目すると
flatten(_,Y,Z) :- flatten_element(_,Y,Z1),flatten(_,Z1,Z),!.
であり、これは
先祖(Y,Z) :- 親子(Y,Z).
先祖(Y,Z) :- 親子(Y,Z1),先祖(Z1,Z).
親子(頼朝,義朝).
親子(義朝,為義).
の変数パターンと全く同じだということがわかります。
ある程度経験を積んだプログラマは不完備データ構造という
決して易しくない述語定義を書き進めるうちに、ここは、
「多分あのパターンに違いない」とほとんど考えることなく
flatten/3の第二節を書き上げてしまいます。
>>795で凄いっていったのはそんな点です。
797デフォルトの名無しさん:2007/07/05(木) 22:01:41
>781が悪いわけじゃないけど、>781のようなプログラムがPrologの普及を
妨げている原因だと思う。こんな汚いコードが頻出するのはたまらん。
798デフォルトの名無しさん:2007/07/06(金) 00:59:53
>>797
汚いってカット?
とりあえず外してみたけどどっちもどっちなんだよね

flatten(X, Y) :- flatten(X, Y, []).

flatten([], Y, Y).
flatten([X|Rest], Y, Z) :- flatten_element(X, Y, Z1), flatten(Rest, Z1, Z).

flatten_element(X, [X|Z], Z) :- var(X).
flatten_element(X, [X|Z], Z) :- not(var(X)), not(is_list(X)).
flatten_element(X, Y, Z) :- not(var(X)), is_list(X), flatten(X, Y, Z).
799デフォルトの名無しさん:2007/07/06(金) 04:21:26
appendを使ってはいけないとなると、しょうがないなぁ、と思う。
私のもほとんど差なし。
flatten(X,Y) :- flatten(X,Y,R),R=[].
flatten([],R,R).
flatten([L|R1],L2,R) :- is_list(L),flatten(L,L2,R3),flatten(R1,R3,R).
flatten([A|R1],[A|R2],R) :- not(is_list(A)),flatten(R1,R2,R).
800デフォルトの名無しさん:2007/07/06(金) 07:44:02
ちなみに>781は検索して出てきたfallten/2を差分リストに改変しただけ
801デフォルトの名無しさん:2007/07/06(金) 15:52:42
へたれを自称してる>>781
単位落としそうな>>795が無理やり褒めるからだろ…
802デフォルトの名無しさん:2007/07/07(土) 07:18:54
いや、flattenを3引数にして、その第一節の第三引数をRにする、
flatten([],R,R).
だけで大変なことなんだよ。ヒントなしに初心者に課題として与えたら、
三ヶ月かかる。>>796に書いたように、ほとんど無意識に指が勝手に動く
感じでこういう述語定義ができることはもっと評価されていい。
Haskellのスレの連中のようにならならいように気をつけよう。
803デフォルトの名無しさん:2007/07/07(土) 15:46:26
>>781から>>798の様に
カットを自動で外すようにprologコードで演繹させる事ってできる?
804デフォルトの名無しさん:2007/07/07(土) 16:51:19
>>803
flatten_element(X, [X|Z], Z) :- var(X), !.
->
flatten_elemnet(A,B,C) :- A=X,B=[X|Z],C=Z,var(X). に変換。
第二節を以下のように変換
flatten_element(A,B,C) :- A=X,B=[X|Z],C=Z,not((A=X,B=[X|Z],C=Z,var(X))),is_list(X).
本体部分を整理して、
flatten_elemnet(A,B,C) :- A=X,B=[X|Z],C=Z,not(var(X)),is_list(X).
を導く。
以下略。 要するにカットの存在する節の頭部のユニフィケーションと
本体の副目標全部を否定してから、それに連接して現在節の
頭部ユニフィケーションと本体そのものを記述すればよい。
ただし、副作用があるとその副作用の結果は期待通りなるとは
かぎらない。
805デフォルトの名無しさん:2007/07/07(土) 17:01:56
副作用があるとたとえば
p. が一節だけ定義されているとすると、
retract(p) は成功するが 二回目以降のretract(p)は失敗してしまう。
したがって、副作用の結果どころか、質問の真偽もどうなるか
わからない。
806デフォルトの名無しさん:2007/07/07(土) 20:21:38
>>802
いや、それはその通りだんだが、そもそもそういう技巧を必要としてしまうところが
Prologの普及を妨げたんじゃないか、ということでしょ。
807デフォルトの名無しさん:2007/07/07(土) 20:22:13
だんだがって何だよ… orz
808デフォルトの名無しさん:2007/07/08(日) 06:18:18
>>806 普通はこうですか。
flatten([],[]).
flatten([A|R],L) :- is_list(A),flatten(A,L1),flatten(R,L2),append(L1,L2,L).
flatten([A|R],[A|R1]) :- not(is_list(A)),flatten(R,R1).

append/3 も重リストの親戚だからあまり差はないなぁ。初心者が
三ヶ月かかるといったのは、コルメライワのグループが最初の
Prologらしきものを開発してからappend/3を発見するまでに
三ヶ月を要したという故事によるわけで・・。
809808:2007/07/08(日) 06:31:51
発言撤回。
短く言い切るように努めること。
素直に>>808の定義を書き、「これでよし」とする姿勢がやはり大事です。
810デフォルトの名無しさん:2007/07/08(日) 07:26:10
lisp知ってれば数分で作れたんじゃね
811デフォルトの名無しさん:2007/07/08(日) 08:11:14
無意識に>781が出てくる実力は素晴らしいが、
美しいのは>808であるという感性はなくさないようにしたいものだ。
代数的にも綺麗(catamorphism)だしね。
812デフォルトの名無しさん:2007/07/08(日) 08:13:16
>781から>808への変換アルゴリズムを書けないかな?
813デフォルトの名無しさん:2007/07/08(日) 08:36:39
三ヶ月って、どんだけ無能なんだよw
814デフォルトの名無しさん:2007/07/08(日) 13:09:32
>>810
Lisperには論理変数の神秘はわからなかったのでは
ないでしょうか。
815デフォルトの名無しさん:2007/07/08(日) 22:07:35
はあ?神秘っていきなり何だこいつw
何か主張したいなら「〜ないでしょうか。」の続き書けよ
さっぱり意味がわからん
816デフォルトの名無しさん:2007/07/09(月) 00:10:59
>>815
だって、1972年のことだから、コルメライワたちだって
みんなLisperですよ。


817デフォルトの名無しさん:2007/07/09(月) 03:33:29
prologで足し算ってどうかくの?
1+1とか。
(+ 11)?
i = 1+1?
さっぱりわからん。
818デフォルトの名無しさん:2007/07/09(月) 05:43:02
>>817 なにか試されているような気がする質問ですが・・・
一番一般的な答えは、is/2 という組込述語があり、
is(_評価値,_関数) の形式になっているというものです。より親しみやすさを求めて
:- op(700,xfx,is). というオペレータ定義を処理系があらかじめしていて、その結果
_評価値 is _関数 で評価できます。
?- X is 1+1,Y is X * 2 + 3.
X = 2,
Y = 7 ですね。 ここでの_関数は処理系に用意されたものにかぎるので、
自分で関数を増やすにはisに代わる述語を定義します。たとえば、
:- op(700,xfx,は).
_評価値 は _関数 :- 自作の関数(_関数,_評価値).
_評価値 は _関数 :- _評価値 is _関数.
の2節を定義することにより、拡張した関数評価述語 は/2 が定義できます。
一番簡単な自作関数の定義は
自作関数(私の年令,58). のようなものです。これで、
?- X は 自作関数.
X = 58
となります。これでは _関数 が 式であるときの評価(たとえば 私の年令 + 6)が
できていないので実現方法は次のレスで書きます。
実はPrologの関数評価述語はPrologプログラムの鬼門です。
これはPrologプログラムの双方向性という魅惑的な性質がこの述語の使用に
よって切れてしまうからです。この話はさらに後に続けます。
819粗忽プログラマ818:2007/07/09(月) 06:01:14
例によって訂正。
?- X は 自作関数. ---> ?- X は 私の年令. でした。
820デフォルトの名無しさん:2007/07/09(月) 15:15:51
たかだか足し算でそんなに考えるなんて
ウンコめんどくさい言語だな。
wikipedia読む感じ、ドット対(x.y)みたいなの
をたくさんつくって、それをたぐっていって答えを出す
データベースみたいな言語という印象を受けた。
821デフォルトの名無しさん:2007/07/09(月) 15:52:56
>>820
"1" さんに "1" をおみあげに "+" してくださいと
依頼するのがオブジェクト指向です。うんと考えた結果こうなりました。
まあ、足し算というけれど関数型言語のスレにいってごらんなさい。
これはまた大変なことだから。
それをたぐって答えをだすデータベースみたいな言語という印象に
私も賛成です。少なくとも私はPrologをそういうとらえ方でみる"派"です。
822デフォルトの名無しさん:2007/07/09(月) 18:42:30
誰か、なんで>781でflattenができるのか教えてください。
特に第三引数を何につかってるのかさっぱりわかりません。

これって常識なんでしょうか?
823デフォルトの名無しさん:2007/07/09(月) 19:43:30
copy([],[]).
copy([A|R1],[A|R2]) :- copy(R1,R2). これはわかりますね?
?- copy([1,2,3],X).
X = [1,2,3] になります。ここで注目して欲しいのは第一節の定義です。
copy([],[]). この第二引数の[]です。これは
[1,2,3|[]] の最後の | の後の[]になることを期待して記述されています。
ここを[]でなくRにしておこうということです。
[1,2,3|R] ですね。論理という観点からは問題のある言い方になりますが、
このRが後から[4,5,6]に決まったとすると[1,2,3|[4,5,6]]=[1,2,3,4,5,6]
となります。今度はflatten/3の第二節に注目しましょう。
flatten([X|Rest], Y, Z) :- flatten_element(X, Y, Z1), flatten(Rest, Z1, Z). R
第二引数の本体(:-より右)に注目して、
flatten_element(X, Y, Z1) は Xの変換値であるYの後ろにZ1が付くことを
期待してるな、とわかります。
このZ1はRest部分の変換値であり、よく見る何も解決できていない、論理変数Zで終わっています。
[1,2,3,4,5|Z] といったリストになるのでしょう。さて上のリストの例で
いうと Z1 は [4,5,6] にあたります。こういうテクニックを使って、
Xの変換値[1,2,3]に残りの変換値[4,5,6]を付けて[1,2,3,4,5,6|Z]が
作られるくらいに理解してください。

flatten(X, Y) :- flatten(X, Y, []). の本体の第三引数[]は
最終的に上記のZ=[] となりリストとして不完備でなく完成した形となります。
?- flatten([[1,2,3],4,5,6],X).
X = [1,2,3,4,5,6]
上手に説明できているとは思えませんが、要所のいくらかを挙げたので、
もう一度考えてみてください。
824デフォルトの名無しさん:2007/07/09(月) 19:56:08
>>822
常識ってかイディオムだね。
差分リストとPrologでぐぐればそこそこ引っかかるよ。
825デフォルトの名無しさん:2007/07/09(月) 20:30:29
>>808見ても明快とは思えないんだよなあ・・・
>>832の説明見ても要領得ないことも。
もうちっと論理的に説明してくださいよ。
826デフォルトの名無しさん:2007/07/09(月) 20:35:44
>>832 が気になる
827デフォルトの名無しさん:2007/07/09(月) 20:46:12
prologでキモイのは、
>>808なら
>flatten([A|R],L) :- is_list(A),flatten(A,L1),flatten(R,L2),append(L1,L2,L).

左から読み進むと、いきなり未知のL1, L2が登場してしまうとこ。

flatten([A|R],L) これは判る。[A|R] == L、Lをcar/cdrで分解したものがA|R
:- これも適当な参考書読めばルールの定義だと判る。
is_list(A) 名前からリストかどうかを判定する述語だろう事が判る。
flatten(A,L1), ここではた、と躓くが、A == L1か。なるほど、しかし何故コレが必要なのか理解できない。
flatten(R,L2), L1と同様、R == L2か。しかし何故コレが以下同文
append(L1,L2,L). ここで疑問に思う。A == L1、R == L2ならなぜappend(A,R,L).ではダメなのか。
828デフォルトの名無しさん:2007/07/09(月) 20:53:03
ああ判った。
キモイprologの構文だとflatten(A,L1),の結果がL1に入るんだったっけ。
残りを見てみよう。
flatten([],[]). nil同士が真であると。当たり前である。
flatten([A|R],[A|R1]) :- not(is_list(A)),flatten(R,R1).
Aがアトムならflatten(R,R1). ?
Aは放置か?
829デフォルトの名無しさん:2007/07/09(月) 20:53:23
>>825
[] の flatten は []
[A|R] のとき A がリストならば、 flatten は「A の flatten」と「R の flatten」を append したリスト
[A|R] のとき A がリストでないならば、flatten は「先頭が A で以降が R-flatten」のリスト

を書くと >>808 になるかと思う。
けど、個人的にはこうやっちゃうな。

flatten2([],[]). 
flatten2([A|R],L) :- flatten2(A,L1), flatten2(R,L2), append(L1,L2,L).
flatten2(X,[X]).


>>827
A == L じゃなくて A の flatten が L
まー、in/out が分かり難いのは慣れだな慣れ
830デフォルトの名無しさん:2007/07/09(月) 20:55:54
あー、これは規則の定義だから、述語判定でAを消費したとしても、
左辺にAがあるわけだからAは不変で結果として残るわけか。
なんかすげー判りにくいと思わん?
831デフォルトの名無しさん:2007/07/09(月) 20:58:36
>>830
パターンマッチは、もう慣れてくれとしか。
832デフォルトの名無しさん:2007/07/09(月) 21:04:31
>>829
カット入れ忘れてた(´・ω・`)
833デフォルトの名無しさん:2007/07/09(月) 21:06:15
って、入れ忘れてるってレベルじゃねぇな。死んでくる(´;ω;`)
834デフォルトの名無しさん:2007/07/09(月) 21:37:05
カット入れ忘れとか、この程度の量でミスするのってどうなの?
prolog大丈夫なの?
デバッグ大変なの?
835デフォルトの名無しさん:2007/07/09(月) 21:42:03
( ´ ・ ω ・ ` )
836デフォルトの名無しさん:2007/07/09(月) 21:44:04
なんていうか…入力と出力とか、原因と結果とか、そういう区別をする世界じゃないんだよ。
述語ってのは、各引数が特定の条件を満たすときに成功するって概念なの。
で、自由変数があったら、その条件を満たすような値を探して、見つかったら単一化して成功するわけ。

わかりやすいのが、例えば plus/3 とか。
plus(X, Y, Z) は、 X + Y = Z な関係であるときに成功する。
plus(1, 2, Z) だと Z が 3 に単一化されて成功する。
plus(X, 2, 3) なら X が 1 に単一化されて成功する。

「左辺」は、別に「述語判定」だけをやってるわけじゃなくて、定義の一部になってる。
my_not(true, false).
my_not(false, true).
みたいな、「左辺」だけで完結する定義もたくさんある。

デバッグは、あんまりやりやすくはないかも。
837デフォルトの名無しさん:2007/07/09(月) 22:00:14
というか論理型言語はプログラムを作ること事態が設計と実装とテストを兼ねている
この辺手続き型に慣れてきた人間には苦痛でしかないね
てか今でも苦痛だけど
838デフォルトの名無しさん:2007/07/09(月) 22:02:31
haskellとどっちが大変だと思う?
839デフォルトの名無しさん:2007/07/09(月) 22:14:54
ロームっていう会社がアメリカに独立法人を持っていた。ところが
作る半導体が不良品の山、大赤字でロームの経営危機が訪れた。
ドラム缶いっぱいの不良品の山を前にした社長突然閃いた。テスターが
故障しているのではないか? 結局、ドラム缶は宝の山に変じたとのこと。

不良品かどうかわからないが、ドラム缶いっぱいの述語定義をしておけば
宝はいつでも取り出せるというのが、Prologのプログラミングスタイルです。
入力がどうの出力がどうのということは、最後の最後のサービスです。
モデルをせっせと作りましょう。この社会をそのまま記述しましょう。
そうすればいつかいい記事が取り出せますよ。
840デフォルトの名無しさん:2007/07/09(月) 22:23:51
>>838
Prologは4時間の講習でだいだい書けるようになるからね。
比較にならない。
841デフォルトの名無しさん:2007/07/09(月) 22:24:29
>>827
まるで、オブジェクト指向を関数ポインタで説明してるみたいだw
未知のパラダイムを理解するのに既知のパラダイムに置き換えるのって
結局遠回りなんだよね。
842デフォルトの名無しさん:2007/07/09(月) 22:34:51
>>823
ありがとうございます!
ものすごくわかりやすい説明でした。

これがProlog programmingの本質、かどうかはわかりませんが
ちょっと面白い技巧ですね。
843デフォルトの名無しさん:2007/07/09(月) 22:34:52
>>834
カットの入れ忘れはエラーチェックが甘いみたいなもんだから、まぁ油断だな。
844デフォルトの名無しさん:2007/07/10(火) 04:56:30
>>838
重リストは最も難しい課題のひとつです。
Prologは6つの組み合わせのユニフィケーションしかありません。
Prologプログラマが理屈をこねる余地はほとんどありません。
一方Haskellプログラマは一言でいうとスノッブです。
845デフォルトの名無しさん:2007/07/10(火) 05:14:22
>>836
再帰述語、述語に限らず再帰関数でも、デバッグとかトレースと
いうことは不可能に近い、そういう課題に多用されますね。
複雑なことを、一言で言い切ってしまうために再帰的なわけですから。
Prologのデバッガがわかりやすいか、詳細すぎるかは、私は
全く使用しないのでわかりません。再帰を使用しないとPrologには
なりませんから、数学的とでもいうような直感が少々要求されるのかも
知れません。
846デフォルトの名無しさん:2007/07/10(火) 06:00:42
OnLispの最後の方にある埋め込みprologで遊んでるんですが、
prolog理解する上で何か足りない物ってありますか?
〜のデータ型がないとかは別にいいんで、
「これができないから糞」みたいなの

<規則> : (<- <文> <クエリ>)
<クエリ> : (not <クエリ> )
     : (and <クエリ>* )
     : (lisp <Lispの式> )
     : (is <変数> <Lisp の式> )
     : (cut)
     : (fail)
     : <文>
<文> : ( <シンボル> <引数>* )
<引数> : <変数>
     : <Lisp の式>
<変数> : ? <シンボル>
足りないオペレーターはlispコード埋め込んで補うみたいな事
やってま
847デフォルトの名無しさん:2007/07/10(火) 10:07:23
>>846
あなたの環境を知らないからまともなコメントはできないけれど、
Prologでどうしても必要なのはfindall/3ですね。これないと、
どうにもならないですね。
848847:2007/07/10(火) 10:30:43
unifyや is 入出力を除くとPrologでどうしても必要な述語は
member/2 repeat/0 findall/3 sub_atom/3 atom_chars/2 だと
思います。この中でどうしても処理系さんお願い、速いの用意して!
というのは findall/3 と atom_chars/2 ですね。
849デフォルトの名無しさん:2007/07/10(火) 12:17:20
sub_atom/3 ではなくて sub_atom/5 でした。非決定性の仕様になっています。
それから、勿論、型判定の述語 atom/1 integer/1 や var/1 などは重要です。
850デフォルトの名無しさん:2007/07/10(火) 13:31:57
実践っぽい意見ありがとうございます。
とりあえずfindall相当のことができるかどうか調べてみます。
851デフォルトの名無しさん:2007/07/11(水) 03:48:47
Prologでデバッガ(ステッパー)書いて、いつも困るのが ! です。
スレを立てたっていいくらいのテーマですが、
しばらくこのコードを競い合いませんか。
852851:2007/07/11(水) 17:24:05
bit誌 1986年6月号に戸村哲・小方一郎 両氏による「Prolog in Prolog」と
いう記事があり、そのなかに、
solve(Var,_) :- var(Var),!,fail.
solve( !,V) :- !,cut(V).
solve(true,_) :- !,true.
solve(fail,_) :- !,fail.
solve((A,B),V) :- !,solve(A,V),(var(V),solve(B,V);nonvar(V),true).
solve((A;B),V) :- !,(solve(A,V);solve(B,V)).
solve(P,V) :- functor(P,Functor,Arg),not(predicate_type(Functor/Arg,linear)),!,cal
l(P).
solve(P,V) :- !,clause(P,Q),solve(Q,W),(nonvar(W),!,fail;true).
cut(_).
cut(cut).
という部分があります。私も基本的にこのアイデアを永く拝借してきました。
雑誌のコードには一箇所バグがありました。それから、solve/2の下から
2番目の節は組込述語の場合clause/2がエラーとなるため、その判定を
追加しています。処理系によって判定述語が異なると思います。
853851:2007/07/12(木) 04:45:45
訂正します。
スレを立てたっていいくらいのテーマと書きましたが、これは ! の
解釈方法ではなく、PrologによるPrologのデバッグやより高水準な
言語について議論したいということです。カットだけだとさすがに
すぐに終わってしまいます。適切な表現になっていませんでした。
>>852 の 本体がfunctor/3から始まる節は私が追加したものです。
元々の記事にはこの節はありません。
854デフォルトの名無しさん:2007/07/12(木) 18:18:54
>>837
Prologボケしていて、なんだかわからなくなった。
実務では、要求仕様をそのままコード化するのがPrologプログラミングで、
記号の列を受け取って、論理式を組み立てるだけ。
自分が設計してる余地はほとんどない。というか感覚がない。
設計って何だったかな。
855デフォルトの名無しさん:2007/07/13(金) 00:38:17
設計=要求に従うテストコードを書き連ねること
856デフォルトの名無しさん:2007/07/13(金) 08:25:51
PrologによるPrologインタプリタ(デバッガ)が出てきたところで、
質問ですが、オンメモリーデータベースとPrologを繋いで
使っている方はいますか。
特に、単位節としてでなく、インタプリタの clause/2 より前に、
データベースから、あたかも、Head :- Body を取り出すかのように、
あらたな目標を発生させているケースがあれば、詳しくその評価を
教えてください。
857デフォルトの名無しさん:2007/07/13(金) 09:22:13
デバッガとカットが干渉するという意味がわからないのですが…
普通にstep実行はできますよね?
858デフォルトの名無しさん:2007/07/13(金) 09:47:29
clause/2 で一節づつ取り出していくケースでは、
>>852 に示したような細工をしないと、カットが
働きません。一度 ! を通過してもバックトラック後
clause/2の次の節を実行してしまいます。
つまり、clause/2に対して、もうやらなくていいよと、
教えるよい方法がないということです。
859858:2007/07/13(金) 10:12:56
clause/2 で 次の候補節を実行してしまいます。
と云うべきでしょうね。
860デフォルトの名無しさん:2007/07/13(金) 10:36:57
>>852 を少し整理して、インタプリタを
solve((A,B)) :- !,solve(A),solve(B).
solve((A;B)) :- !,(solve(A);solve(B)).
solve(P) :- functor(P,Functor,Arg),not(predicate_type(Functor/Arg,linear)),
!,call(P).
solve(P) :- !,clause(P,Q),solve(Q).
と定義します。
% テストデータ1
t1(X) :- !,X=1.
t1(2).
% テストデータ2
t2(X) :- X=1,!.
t2(2).
?- solve(t1(X)).
X = 1;
X = 2;
no
?- solve(t2(X)).
X = 1;
X = 2;
no
カットが全く働きません。
861デフォルトの名無しさん:2007/07/13(金) 10:40:04
すいません、少々分からない演算子があって困っております。
"@"なのですが、しばしばイコールやグレーター等と出てきますが、どういった意味なのでしょうか。

例えば
1 < 2 と 1 @< 2 の意味の違いがよくわからないです
参考書開いたのですが、記述が見当たりませんorz
教えて頂けませんか?
862デフォルトの名無しさん:2007/07/13(金) 10:59:40
> >= =< < は数値比較演算子。
@> @>= @=< @< は全ての項を対象とした比較演算子です。
ルールは無条件に 複合項 > atom > 数値 で
整数は浮動小数点数に変換されて比較されるようです。
atom同士の比較では一文字目からの文字コード比較になります。
複合項同士の比較では最初に関数部分、これが同じ時は、
引数の数によって比較され、さらにこれも同じ時は、
第一引数から順に再帰的に比較されていきます。
863861:2007/07/13(金) 20:31:57
>862
およそ理解出来ました。
有難う御座いました!
864デフォルトの名無しさん:2007/07/14(土) 13:06:04
昨夜、友人から >>852
?- solve((member(A,[1,2]),!,member(B,[3,4])),V).
A = 1,
B = 3,
V = _115478;
A = 1,
B = 4,
V = _115478;
A = 1,
B = _115464,
V = cut;
A = 2,
B = 3,
V = _115478;
A = 2,
B = 4,
V = _115478;
A = 2,
B = _115464,
V = cut;
no のような結果になるのではとの指摘がありました。たしかに
私の呼び出し環境の説明不足というか、定義が不足でした。この述語は
solve(P) :- solve(P,V),(nonvar(V),!,fail;var(V)).
の定義をして、solve/1で呼びだします。
?- solve((member(A,[1,2]),!,member(B,[3,4]))).
これで上手くいくはずです。
865デフォルトの名無しさん:2007/07/15(日) 13:47:48
cut の細工はうまいと思った。
…理解するのに何時間かかかったけど。

自前でバックトラック実装しちゃえば、そのへんで悩まなくて済んで楽かな、と思って書いてみた。
…全然楽じゃなかった。
しかも結構悩んだ。

やっぱり難しいね、 Prolog。
866デフォルトの名無しさん:2007/07/15(日) 16:34:42
Prologの難しさの9割は、cut演算子の仕様のせいだな。
有効範囲をsyntacticに明示する構文を導入するとか、もう少し工夫のしようがあったと思う。
867デフォルトの名無しさん:2007/07/15(日) 18:15:20
solveと聞くとゼビウス思い出してしまう。
こういういらん記憶は消せないものか。
知って後悔するより知らずにいた方が幸せなことがあるだろう。
蓄えた情報を得て幻滅していくしかないならば、世界を矮小化して
見る癖が発達してしまう。そうすると他の知っておくべき事までもが
こんなものかと感じてしまう。貴重な物事を見過ごしたかもしれない、
そんな確信すら持てなくなるのかもしれない。
こうして、いつか世界のシステムが透けて見えると感じた時、
それでも絶望せずに生き続けられるだろうか?
868デフォルトの名無しさん:2007/07/15(日) 18:29:31
869デフォルトの名無しさん:2007/07/25(水) 13:07:02
これわかる?
「指定するデータを1つだけ含むリストにおいて、指定するデータでリストを2分割する述語を作れ。」
870デフォルトの名無しさん:2007/07/25(水) 13:45:55
>>869
分割([A|R],A,[],R) :- !.
分割([B|R],A,[B|R1],R2) :- 分割(R,A,R1,R2).
871デフォルトの名無しさん:2007/07/25(水) 14:18:16
'2分割'([_指定するデータ|_残りリスト],_指定するデータ,[],_残りリスト) :- !.
'2分割'([_データ|_残りリスト],_指定するデータ,[_データ|_残りリスト分割前],_分割後リスト
) :- '2分割'(_残りリスト,_指定するデータ,_残りリスト分割前,_分割後リスト).

重々しくてよくないね。
872デフォルトの名無しさん:2007/07/25(水) 16:47:14
分割(L,A,X,Y) :- append(X,[A|Y],L).
873デフォルトの名無しさん:2007/07/25(水) 18:52:12
やっぱり、Prologは凄い。
874デフォルトの名無しさん:2007/07/25(水) 18:58:59
appendは可逆ですが、
fib(0, 0).
fib(1, 1).
fib(N, F) :-
N > 1,
N1 is N-1, fib(N1, F1),
N2 is N-2, fib(N2, F2),
F is F1+F2.

fib(N,F).で全部出てこないのはなんでですの?
875デフォルトの名無しさん:2007/07/25(水) 19:30:56
>>874
これは >>818 で書き掛けてそのままになっている話です。
is/2 は言語仕様で方向性があります。すなわち双方向にはなりえない。
?- X is 3+4.
X = 7 にもちろんなりますが、
?- 7 is X+Y. はエラーになります。
fib/2が非可逆なのはそのせいです。
>>836 にでてくる plus/3 ですと
?- plus(3,4,X).
X = 7 の他に
?- plus(3,X,7).
X = 4 も可能ですが(差を表す)
やはり、
?- plus(X,Y,7). は不可の言語仕様になっています。

is/2 には方向性があり、is/2を本体側に含む節は双方向性を
失います。
876デフォルトの名無しさん:2007/07/25(水) 20:00:17
そこがprologの不純なところだ。

2^32 * 3個のplus節があるように見せかけられない。
877デフォルトの名無しさん:2007/07/25(水) 21:30:51
なるほどisが悪さしてるのか
Prolog バージョン2ではその辺を解消して欲しいね
878デフォルトの名無しさん:2007/07/26(木) 04:29:19
>>876 >>877
そうですね。
?- plus(X,Y,7). ですが、X,Yを生成器とするのと、
XまたはYが具体化されるのを待つ、遅延実行とする
方向の二案がありそうですね。

Prologのプログラミングではリバースエンジニアリングに
含みを残す意味で、双方向性は結構意識します。
数値計算を可能な限り避けて、述語にまとめたりもします。
しかしこれこそ、不純ですね。
879デフォルトの名無しさん:2007/07/26(木) 10:41:14
話を変えて、
このスレ、漸く900に近づいてきたけれど Part 2。
Lisp Scheme は Part 17。
これは一体どういうこと?
この問題について誰か分析してください。
880デフォルトの名無しさん:2007/07/26(木) 23:17:21
あっちは半分くらいは Lisp を実装するスレだから
881デフォルトの名無しさん:2007/07/26(木) 23:21:48
じゃあこっちもprolog実装しようぜ
882デフォルトの名無しさん:2007/07/27(金) 09:51:28
>>851
この問題を解決するため、Prolog-KABA には
through/0 という多段カットに機能する組込述語があった。(バグもあった)
PSIのKL0では absolute_cut/1 や absolute_cut_and_fail/1 が
これに当たると思う。absolute_cutの引数にはLevelが来て、
Level段階上位の呼び出し節の選択肢を消す。
883デフォルトの名無しさん:2007/07/31(火) 09:11:41
「Prologの技芸」古本一点Amazonにある。
ttp://www.amazon.co.jp/gp/offer-listing/4320097106/ref=sr_1_olp_72/250-9247267-6873809?ie=UTF8&s=books&qid=1185840489&sr=1-72

買い逃していた人、どうでしょう。
884デフォルトの名無しさん:2007/07/31(火) 10:47:39
図書館に置いてないかな?
885デフォルトの名無しさん:2007/07/31(火) 16:40:25
is/2の双方向性のはなしのつづき
:- op(700,xfx,は).
負数が対象外ですが、

X は A + B :-
i2s(A,A2),
i2s(B,B2),
i2s(X,X2),
足し算(A2,B2,X2),
i2s(X,X2),
i2s(B,B2),
i2s(A,A2).

足し算(0,S,S).
足し算(s(S),S2,s(S3)) :- 足し算(S,S2,S3).

i2s(X,Y) :-
var(X),
var(Y),!.
i2s(0,0) :- !.
i2s(A,A2) :-
integer(A),
var(A2),
B is A-1,
i2s(B,S),
A2=s(S),!.
i2s(A,s(S)) :-
i2s(B,S),
A is B+1,!.
886デフォルトの名無しさん:2007/07/31(火) 17:27:57
2chで先頭から数文字分スペース入れるのにはどうすればいいんですか?
887デフォルトの名無しさん:2007/07/31(火) 20:58:09
>>886
& n b s p ;
888デフォルトの名無しさん:2007/08/01(水) 07:32:59
>>887 ありがとう
i2s(X,Y) :-
  var(X),
  var(Y),!.
i2s(0,0) :- !.
i2s(A,A2) :-
  integer(A),
  var(A2),
  B is A-1,
  i2s(B,S),
  A2=s(S),!.
i2s(A,s(S)) :-
  i2s(B,S),
  A is B+1,!.

これでうまくいくのかな
889デフォルトの名無しさん:2007/08/01(水) 07:38:05
本体はメダカの右側に少し書き進めた方がよさそう。
その上で折り返して   か。スペース4個送ったつもりだけれど2個に
なってる。
890デフォルトの名無しさん:2007/08/01(水) 19:19:40
>>888
それって、こうやってかちゅ〜しゃで覗くと汚くなるんだよな〜
891デフォルトの名無しさん:2007/08/01(水) 20:06:37
私はFirefoxで直接読み書きしているので、>>888はきれいです。
892デフォルトの名無しさん:2007/08/01(水) 20:27:50
cutオペレータの明快な説明ってないでしょうか?
どこまでのバックトラックが抑止されるのかが、なんとなくでしかわからない…

呼び出された節中のcutの効果は呼び出し側にも及ぶんですよね?
893デフォルトの名無しさん:2007/08/02(木) 07:03:10
>>892
これまで発行されたProlog本の中で、どれが一番CUTの説明が
的確かコンテストをしてみましょうか。50冊くらいの候補を、
次に載せてみます。
894デフォルトの名無しさん:2007/08/03(金) 23:26:54
>>892
prologプログラムの実行 = AND-OR木の生成
cut = cutを含む節の呼び出し点に相当するORノード以下の枝刈り
895デフォルトの名無しさん:2007/08/07(火) 11:17:26
>>892
「Prologの技芸」の説明が圧倒的であった記憶から、これの要約から
入ろうと思った。第11章「カットと否定」は22頁あり、これだけで
独立した小論文の趣がある。カットの影響範囲というか、類縁関係に
ある概念も押さえられている。カットの意味的な種類やその背景に
ついても存分に述べられている。多分言い尽くされているのだろうが、
説明は重層的でプログラム例も単純なものでなく、どうにも要約なんて
できそうにない。
残念ながら初心者が読んだら確実に投げ出すだろう。簡単に理解したい
という場合を想定すると、ほとんどの読者に不向きというのが私の感想。
とにもかくにも読んでみてください。
896デフォルトの名無しさん:2007/08/07(火) 15:36:36
>>895 は何も具体的なことをいってない。ちょっと反省して、
といってもCutとは関係ないのですが、
u(1). が定義済みで、
?- u(X),assertz(u(2)).
X = 1;
no
で、つまりassertz(u(2))はこの質問のバックラック時の対象節には
なりません。最初の環境で、
?- repeat,u(X),assertz(u(2)).
X = 1; /* 一回目 u(X) */
X = 1; /* 二回目 u(X) */
X = 2;
X = 1; /* 三回目 u(X) */
X = 2;
X = 2;
X = 2; /* ここまで X = 2 が3個になる */
X = 1; /* 四回目 u(X) */
...
となる。このあたりになると、初心者にはちょっと解りにくい。
Cutの簡単な例を考えていて、唐突に連想した。
考えどころは、u(X) が実行される時の環境が保存されるということ。
repeatへ戻ってからの二回目のu(X)時にはu(2)は今度は定義済みであると
考える。
関数型言語でクロージャが再評価されているようだから、これですんなり
解る人も多いのかも知れない。repeat/0の定義は
repeat.
repeat :- repeat.
897デフォルトの名無しさん:2007/08/07(火) 16:26:55
「An Introduction to Language Processing with Perl and Prolog」
という本が2006年に出ています。私は英語は苦手であまり詳しくは
読んでないのですが、ざーと見渡したところ、すばらしい。
これほど、プログラミングに焦点をあてた自然言語処理本が
あっただろうか。何故かPerlについてはほとんど言及されて
いないのですが、Prologについては懇切丁寧な解説があります。
その中に、Cuts の説明が2頁ほど載っていますが、この説明が
なかなかのもので転載できないのが残念。
898誤爆的:2007/08/07(火) 17:12:50
> 京都に旅行したとき、三十三間堂でたくさんの手と顔
> を持った千一体の仏像を見た。なぜ、何種類かの何本も
> 手や顔があるのかと聞くと、ガイドは「同時に何人かの
> 違った悩みを救えるように」という答えであった。また
> なぜ本尊の他に似たような仏像が左右に五百体ずつ千
> 体もあるのかと聞くと「より多くの人びとを一度に救
> えるように」ということであった。これを聞いた博士
> は、「ポリプロセッシング」(またはマルチプロセッシン
> グ) および、「分散プロセッシング」の概念の神髄が数
> 百年前から日本にあったことがわかりすっかり感服した
> と、エッカート博士は外交辞令と巧みな比喩をほどよく
> まぶしながら、その熱のこもった講演を結んだ。

bit誌1978年9月号「エッカート講演ハイライト」森敬
899デフォルトの名無しさん:2007/08/07(火) 17:25:06
Wikipedia で ジョン・エッカートをひいたら、
彼がストアード・プログラム方式の最初の概念提示者である
ことが載っていなかった。たしか、これは米国の裁判で確定
した公式な事実の筈。それでそれに関する記事を探したついで
が上記のbit誌の記事です。私も高等学校の頃三十三間堂に
行ったけれど、このような神髄を感知することはできなかった。
900デフォルトの名無しさん:2007/08/08(水) 15:54:56
Cutだが、
1) 呼び出し側は呼びだした述語(副目標)の中で!が実行されても、影響を受けない。
その副目標が非決定性に見えるか、決定性に見えるかだけである。
!を含む節で!を通過すると、
2) その節の!までに副目標を実行されてきている時は、以後その時点の、
論理変数の束縛に固定される。再度束縛され直すことはない。
3) !以後の副目標がバックトラックされて、再び!が実行される状態になったら
この述語呼び出しは偽となる。
4) これは!以後の非決定性の副目標呼び出しを何ら妨げるものではない。
5) この節を含む述語の定義にこの節以後に節定義があるときは、この
定義はないものとなる。
6) !を通過するまでの連接した副目標情報と、5)で示した定義節情報は
スタックからポップする事が可能になる。
901デフォルトの名無しさん:2007/08/09(木) 09:13:58
Prologでは副目標が実行される時、その節定義環境が保存される。
>>896 を唐突に書いたのは、実はこのことを示したかったからだ。
このことから、2)に示した!が実行されるまでの連接した副目標は
その時点の変数の束縛を除けば、!通過後に、5)と同様、スタックから
その節定義環境を取り除くことができる。>>900はその件について
舌足らずだった。
902デフォルトの名無しさん:2007/08/09(木) 13:47:11
多分そうなるんだろうなと思って確かめていなかった事。

?- var(X),findall(X,member(_,[1,2,3]),L).

L = [_G331, _G325, _G319]

Yes
?-
findall/3から [X,X,X] のようなリストを生成することは
難しいようです。
903デフォルトの名無しさん:2007/08/09(木) 13:50:35
もちろんこれもだめ。
?- X=Y,findall(X,member(_,[1,2,3]),L),Y=3.

X = 3,
Y = 3,
L = [_G331, G325, _G319]

yes
?- L = [3,3,3] にはなりません。
904デフォルトの名無しさん:2007/08/10(金) 17:20:18
tuPrologってどう?
905デフォルトの名無しさん:2007/08/14(火) 08:53:17
Prologの言語仕様だが、
1) 論理変数は必ず_から始まる。
2) 数字から始まっても以後に数字以外が出現する文字列はアトムであり
表記上、'で囲む必要はない。
の方がいいのでは。
906デフォルトの名無しさん:2007/08/14(火) 11:03:30
って言われてもな
907デフォルトの名無しさん:2007/08/15(水) 09:32:04
>>904
インストールの仕方がわからない・・・
908デフォルトの名無しさん:2007/08/20(月) 13:13:25
909デフォルトの名無しさん:2007/08/21(火) 19:09:40
Prologってあまりメリットないの?
910デフォルトの名無しさん:2007/08/21(火) 19:48:44
生産性ではやはり、一番だよ。仕様が与えられて、
プログラムができあがるまでの時間ね。多分群を抜く。
ただ不向きの局面も多々あるから。
911デフォルトの名無しさん:2007/08/21(火) 20:13:16
問題は不向きの場面が多すぎることだな。
912デフォルトの名無しさん:2007/08/21(火) 20:59:42
バックトラックして、バインドし直す。これを途方もなく繰り返す。
どうしたって遅くなる。
ビットマップを操作するような課題には全く不向き。
それともう一つ。
現出するアトムをHeap領域に登録していく。
ファイル操作やデータベース参照だと、何十万、何百万と
いうアトムが現れるから、もし、実行体からのリンクが
存在すると、メモリー不足になる懸念がある。ほとんどの
場合バックトラックしてこのリンクは切れているのだが、
GCの対象となるから、その時間は馬鹿にならない。
やはり、小規模なシステム向きかな。
913デフォルトの名無しさん:2007/08/21(火) 21:12:05
>>909
最大のメリットは電子的に仕様を受けて(私の場合メール)、
その仕様を編集するだけでプログラムができてしまうこと。
ある程度の理解力のある人だと(経営者はほとんど)、Prologを
全く知らないひとでも、ソースに何が書いてあるか完全に
理解する。したがって詳細な仕様書やマニュアルがいらない。
これは、今はやりの関数型では絶対に不可能。
大きなプログラム仕様の変更でもほとんどの場合一時間以内には、
完全に仕上がる。
現在のPrologはこれらの点についてあまりに過小評価されている。
人のうわさに動かされるのがこの世界の常だが。
914デフォルトの名無しさん:2007/08/22(水) 08:03:14
>>912 それと、
例えば、単位節でデータベースで100万節定義されているとする。この環境で
ファイルから節を次々読み込むと、読み込んだ節で生成されるアトムが
既に存在するか検索する。100万節が4引数だとしても最大400万のアトムを
Heap領域のアトムテーブルに対してリンクをたどりながら検索に
行くことになる。
これでは、4GHzクラスのCPUであっても全然速くならない。
単位節データベースの参照でも、第一節から順にヒットするまで
リンクをたどり、さらに平均百万項を超えるユニフィケーションが必要だ。
大規模システムを担うには課題が多い。
915デフォルトの名無しさん:2007/08/22(水) 11:27:59
Hash使ってないの?
916デフォルトの名無しさん:2007/08/22(水) 11:47:14
私の使っているIF/Prologではハッシュは使われていない。
SWI-Prologも同様だとおもう。
PSIではこれは節の参照用だが第一引数に限定して、indexが振られていた。
917デフォルトの名無しさん:2007/08/22(水) 12:58:43
今後の希望だが、できる限りオンメモリデータベースとして
完全なものになっていって欲しい。
サーバ・クライアントモデル。排他制御、保護機構など。
もちろん大量データへの備えも含めて。
918デフォルトの名無しさん:2007/08/22(水) 13:28:21



Haskellの布教に来ました

Haskellは参照透過性があります。一度簡約された部分は二度と変更できません。
Haskellは型とデータのパターンマッチがあります。ホーン節の簡約と同等です。
Haskellはモナドの導入によって副作用を隠蔽できます。Prologは副作用を含む構造を安易に書けてしまいます。
HaskellはProlog以上に複雑な型が書けます。多様型の導入によって生産性が劇的に向上します。
Haskellは遅延評価によって再帰的な構造を、必要な部分だけを簡約して評価することができます。

Haskellは仕様書の表す論理構造を書く手段として適しています。
919デフォルトの名無しさん:2007/08/22(水) 13:55:19
>>918
>>912 >>913 あたりを目にされてのレスなのかな。
布教内容については特に異論はありません。

ただ、Haskellのプログラムを見て、一目で意味のわかる素人はいません。
それから、メールの内容を形態素解析と補助的なプログラム(Prologだと
論理変数を生成するような述語)だけで、プログラムに編集することは、
事実上不可能だと思います。
920デフォルトの名無しさん:2007/08/23(木) 10:57:28
布教内容については特に異論はありません、なんて書いたけれど、
実はHaskellについてはわからないところだらけ。
モナドなど特にわからない。布教だけでなく、出張教授もして欲しい。

話は変わりますが、ファイルの参照も
?- select * into X from file(File) where #1 = 氏名 and #2 = 薬師寺如来.
でできるようにすると便利ですよ。#1,#2を確定するためのcut情報(UNIXの)の
定義が必要ですが。
921デフォルトの名無しさん:2007/08/23(木) 11:03:56
間違い。 where #1 = 薬師寺如来 and #2 = 薬師寺. でした。
位置情報(仏像,#1,1,16).
位置情報(仏像,#2,17,30).
位置情報(仏像,#3,31,255).
のような定義をしておきます。
922デフォルトの名無しさん:2007/08/23(木) 11:19:13
あ、それから ?- select * into X from file(仏像) ・・・ ですね。
この場合述語の引数からのリンクではありませんてした。
COBOLなどで作成したファイルはほとんど固定長ですから、
こういう参照が可能です。宣言型言語での参照で少しは
副作用述語が散らばらずに済みます。
923デフォルトの名無しさん:2007/08/24(金) 13:39:43
Prologプログラマの間では、SQLの評価は低く、私もこれに
拘るつもりはありません。UNIX流の文字の延長的なファイル
概念を捨てて、必ずオンメモリにリストとして、取り込んで処理をする。
open see close seen read get_char などは極めて例外的にしか使わない
仕様になって欲しい。
924デフォルトの名無しさん:2007/08/24(金) 15:13:46
洋書ですが、
Prolog by Example (ハードカバー)
Helder Coelho (著), Jose C. Cotta (著)
# 出版社: Springer-Verlag Berlin and Heidelberg GmbH & Co. K (1998/02)
# 言語 英語
# ISBN-10: 3540183132
# ISBN-13: 978-3540183136
という本、Amazonで 価格が53856円するのですが、
どんな本だかご存じの方いますか?
925デフォルトの名無しさん:2007/08/24(金) 16:07:03
>>905
>2) 数字から始まっても以後に数字以外が出現する文字列はアトムであり
>表記上、'で囲む必要はない。

そうすると
6is 1+2+3

6 is 1+2+3
と書かなければならないぞ。耐えられるのか。
926デフォルトの名無しさん:2007/08/24(金) 16:59:16
6is 1+2+3 が奇態なのである。
6is1+2+3 は許されないし、X=6, Xis 1+2+3 も許されない。
こんな表記は即刻廃止にするべきだ。
927デフォルトの名無しさん:2007/08/24(金) 18:33:55
賛成だがまあどうでもいいかな。
928デフォルトの名無しさん:2007/08/24(金) 19:31:39
2xを2*xの省略形と見なすという馬鹿な仕様にもある意味魅力を感じる
929デフォルトの名無しさん:2007/08/24(金) 20:37:11
そんなのあったのかよ・・・
930デフォルトの名無しさん:2007/08/24(金) 22:15:58
ないってw
いやたぶん

>>916
http://www.ifcomputer.co.jp/IFProlog/Specifications/Overview/home_jp.html
>バイナリツリーやハッシュテーブルが自動的に生成されるので、
>IF/Prologは、高い実行性能とスケーラビリティを達成しつつ、
>プログラマからはリニア的な観点で見えかつ生産性とわかりやすさも達成します。

こんなこと書いてあるけど、それは別の話?
931デフォルトの名無しさん:2007/08/24(金) 23:24:45
>>924
通貨とか間違っただけじゃね?
これと中身は同じと思われ
ISBN-10: 0387183132
ISBN-13: 978-0387183138
10年違ってもページ数同じだし
932デフォルトの名無しさん:2007/08/25(土) 03:42:11
>>930
うーん、確かにそういう記述がありますね。
1000節単位くらいのassertzで参照がどんどん遅くなるのですが、
別の理由(例えばGC)などによるのかなぁ。
listingに至っては最後に登録したものは数秒以上かかったり。
933デフォルトの名無しさん:2007/08/25(土) 21:19:45
>>905
例えばLispなんかは基本的に空白で区切ればなんでもアリに近い世界だと思うけど、
Prologはもっと数式(とか論理式)の見た目に近づけてあると思うんだよね。
そのへんの一貫性の問題じゃないかな。
934デフォルトの名無しさん:2007/08/26(日) 07:50:33
>>918
率直に言って、わかりにくく、読みにくく、覚えにくい。
学習し終わるまでの時間はPrologの20倍を超えるだろう。
>多様型の導入によって生産性が劇的に向上します。
これはさすがに誇大広告。
935デフォルトの名無しさん:2007/09/03(月) 11:12:43
1) ?- db(A,B,C),A > B. は可。
2) ?- A > B,db(A,B,C). のような制約は不可。
さて、RDB参照でdb/3からselect文への変換を考えます。
1+) ?- select * into X from db,member([A,B,C],X),A > B. これはちょっと堪らない。

2+) ?- select * into X from db where #1 > #2,member([A,B,C],X).
にしたいわけですね。
1) を 2+)に変換するか(従来のPrologのコードを利用する場合)、
2) を 2+)に変換してくれるような、
インタプリタの拡張は、どんな方法、表記法がありますか。
936デフォルトの名無しさん:2007/09/05(水) 19:49:36
>>935
イテレータ風に
1) {} をSQL再構成区間とする。
2) { A>B,db(A,B,C) } のように記述される。
3) db/3があることによって、これを 2+) に変換する。
そういう述語 {}/1 を定義する。
4) db/3 が中核的な副目標であること。
5) 中核的な副目標の引数が連接する他の副目標の引数と
して存在するときは、可能ならばwhere 条件に引き込む。
上記の指針で{}区間内を実行時に再構成する。
937デフォルトの名無しさん:2007/09/06(木) 04:18:16
述語 {}/1 としてセルフインタプリタを組むということですか。
938デフォルトの名無しさん:2007/09/06(木) 04:50:26
>>936 もう一度話を整理すると、
..., db(A,B,C), ... ,A > B, ... をSQLのselect文に変換したい。
ただ、db/3を変換するだけだと
..., select * into X from db, ... , A > B, ... となる。
これをdatabase fetchを減らすべく
..., select * into X from db where #1 > #2, ... に変換できないか、
という課題でした。>>936 の解では原文の
..., db(A,B,C), ... , A > B, ... の適当な区間を
..., { db(A,B,C), ... ,A > B }, ... のように{}で括ればよいと
いうことになります。従前のコードに手を入れるのだとすると、
最小の手間であり、実用的な対処のように思います。
939デフォルトの名無しさん:2007/09/08(土) 10:55:14
以前INAPでErlangに関する発表があって、私は知識がなく、
さっぱりわからなかったのですが、"Programming Erlang"と
いう本があることを知りすこし読んでみた。いい本です。
けっしてコードは多くはないが、説明は懇切丁寧(らしい)。
最初の部分を読み中間を跳ばして、後半のコードの意味の解読に
現在は苦労している。
ErlangはPrologの影響が強いようで、関数型言語特有の記号の
多用がない。知らない人から見ると、几帳面で重苦しいJavaタイプ
の言語に見えるだろう。Prolog屋から見ると逆にシンプルで
心地よい。

Erlangで書かれたPrologがないかと思ってWebを探索したが、
今のところ見つからない。誰かご存じの方居ませんか。
おまえが書けば良いじゃないかと言われそうだが、自身で
書くというレベルには私はまだまだ。
940デフォルトの名無しさん:2007/09/09(日) 10:49:48
>>935 - >>936 辺りの話は、現在のPrologプログラマは
関心がないかも知れない。もう少しRDBとPrologの関係一般については
「PROLOG データベース・システム」 D リー著 安部憲広訳 近代科学社
1985年 ISBN4-7649-0106-4
に詳しく書いてある。論理式 SQL(ここではELというサブ言語) ML Prologの
コード比較という事をして見せているのはこの本だけだろう。MLに関心の
ある人にも勧められる本といえる。
941デフォルトの名無しさん:2007/09/10(月) 09:52:41
ジョン サマーソン 「古典主義建築の系譜」 鈴木博之訳 美術出版社
と言う本があります。BBC放送の教養番組で著者自身が語って訊かせる
原稿らしい。この本全体をPrologでコード化できたらなと思う。

こんな突拍子もないことを考えたのは、1984-5年頃、Prolog-KABA上に
ファサードの表現をPrologで記述するという試みがあったことを
思い出したから。多分Prolog-KABAだから、若干の図像を含んだもの
だったんだろうけれど、私は拝見する機会がなかった。

サマーソン卿の老獪な語りのうちどんな部分が論理式になりうるか
興味がある。
942デフォルトの名無しさん:2007/09/10(月) 10:01:33
質問。
囲碁、将棋のような盤上ゲームのルールを定義する場合、必ず現れる、
「交互着手の原則」はPrologではどのように定義されますか。
943デフォルトの名無しさん:2007/09/10(月) 22:38:46
next_player(black, white).
next_player(white, black).
囲碁ならこうなるんじゃね?
944デフォルトの名無しさん:2007/09/11(火) 13:22:59
% こんな定義は?
交互着手の原則(0,_).
交互着手の原則(_手目,黒) :-
  棋譜(_手目,黒,_着手座標,_考慮時間),
  _前の手 is _手目 - 1,
  交互着手の原則(_前の手,白).
交互着手の原則(_手目,白) :-
  棋譜(_手目,白,_着手座標,_考慮時間),
  _前の手 is _手目 - 1,
  交互着手の原則(_前の手,黒).

% 実際の使われ方は

着手(_手目,_石の種類,_着手座標,_考慮時間) :-
  着手可能性(_手目,_石の種類,_着手座標),
  交互着手の原則(_手目,_石の種類),
  棋譜の登録(_手目,_石の種類,_着手座標,_考慮時間)
945944:2007/09/11(火) 17:13:05
% 大間違い。せめて以下でないと。この定義だめですね->考え直します。
% こんな定義は?
交互着手の原則(0,_).
交互着手の原則(_手目,黒) :-
  _前の手 is _手目 - 1,
  棋譜(_前の手,白,_着手座標,_考慮時間),
  交互着手の原則(_前の手,白).
交互着手の原則(_手目,白) :-
  _前の手 is _手目 - 1,
  棋譜(_前の手,黒,_着手座標,_考慮時間),
  交互着手の原則(_前の手,黒).

% 一々初手まで確かめる定義が必要か?

着手(_手目,_石の種類,_着手座標,_考慮時間) :-
  着手可能性(_手目,_石の種類,_着手座標),
  交互着手の原則(_手目,_石の種類),
  棋譜の登録(_手目,_石の種類,_着手座標,_考慮時間).
  
946デフォルトの名無しさん:2007/09/12(水) 18:56:54
同じ定義を白と黒で繰り返しているのが嫌かも。
抽象化したいところ。
947デフォルトの名無しさん:2007/09/13(木) 08:34:49
% 交互着手の原則は逆順棋譜が与えられたとき、以下の述語で定義される
交互着手の原則([_]).
交互着手の原則([[_最新の手番|_],[_一手前の手番|R1]|R]) :-
  次の手番(_一手前の手番,_最新の手番),
  交互着手の原則([[_一手前の手番|R1]|R]).

次の手番(_手番,_次の手番) :-
  手番の種類(L),
  member(_手番,L),
  member(_次の手番,L),
  not(_手番=_次の手番).

% 囲碁の場合は (一般化するなら第一引数として_ゲーム名を追加する必要がある)
手番の種類([白,黒]).

さらに、以下の定義が必要
% 盤上ゲームとは逆順棋譜のことだと考えよう!
% 逆順棋譜に於いては、交互着手の原則が成立する必要がある。
% 逆順棋譜の形式定義
948デフォルトの名無しさん:2007/09/13(木) 09:02:09
囲碁だと黒、白、で格好がつくが、将棋だと先手、後手。
手番の種類(将棋,[先手,後手]).
となり、陳腐だ。
同一人が続けて着手できないということをいいたいのだから、
もう少しなんとかならぬものか。
949デフォルトの名無しさん:2007/09/13(木) 10:35:07
next_player(X, X) :- fail.
950デフォルトの名無しさん:2007/09/13(木) 10:51:36
そうか。コマの種類検査に拘ったのがいけなかったのか。
951デフォルトの名無しさん:2007/09/24(月) 15:04:44
誰か教えてください。
7年ぶりにPSIに火を入れようと思ったら、キーボードがなくなっていた。
コネクタは違うがそっくりの三菱のME1000という古いUNIXワークステーションの
キーボードと間違えて、廃品業者に出してしまった。
電気的に共通するのならコネクターの配線を付け替えて、
流用したのだが、どんなものだろう。
三菱電機の古い技術者の方よろしくお願いします。
952デフォルトの名無しさん:2007/09/28(金) 19:18:14
>>673
>>695

S-Prologには無名変数がらみの不具合が多かった、
という話がSLOG.FINの「"履歴"」に載ってるけど、
その修正漏れっぽい現象を見つけたので記念カキコ。

| ?- X=_, X=nonvar, Y=c(_), Y=c(nonvar), write([X,Y]), nl.
[nonvar,c(_)]

X = nonvar
Y = c(_) ->;
no
953デフォルトの名無しさん:2007/09/28(金) 19:34:34
こっちのほうがいいか

| ?- X=_, X=nonvar, X=another-nonvar.
no

| ?- Y=c(_), Y=c(nonvar), Y=c(another-nonvar).

Y = c(_) ->;
no
954デフォルトの名無しさん:2007/09/29(土) 03:19:40
IF/Prolog V5.2A の不可解なバグ。
[user] ?- sub_atom(abcccd,P,1,N,c).

P = 2
N = 3 ;

P = 3
N = 2 ;

no
955デフォルトの名無しさん:2007/09/29(土) 04:39:31
[]の型がリストでもアトムでもなくて不自由しまくる難儀な処理系も知っているぜ
956デフォルトの名無しさん:2007/09/30(日) 09:56:59
comp.lang.prologで今、パイナップルとかなんとかいう人が、
かたくなにリスト処理の使用を拒んでいてなんか面白い
957デフォルトの名無しさん:2007/10/01(月) 05:50:09
エジンバラ構文以外にはどんなのがあるのかな?
958デフォルトの名無しさん:2007/10/01(月) 17:34:51
マルセイユ系っていうのかな。
LISPのS式のような構文。中島秀之さんが育てていた
Prolog/KRなんかもこの系統だ。
959デフォルトの名無しさん:2007/10/01(月) 18:16:46
INAP2007 が今月の4-6日の日程でドイツのワルツブルグ大で
開催されます。ヨーロッパでの開催ということでかなり盛り
上がってるのではないかと思います。

http://inap.dialogengines.com/
960デフォルトの名無しさん:2007/10/11(木) 00:51:43
一般の業務ソリューションでPrologって使われることがありますか?
961デフォルトの名無しさん:2007/10/11(木) 00:56:38
うん
962デフォルトの名無しさん:2007/10/11(木) 01:38:10
どんな?
963デフォルトの名無しさん:2007/10/11(木) 01:45:11
一般の業務
964デフォルトの名無しさん:2007/10/11(木) 16:43:04
>>960
日本では少ないようですね。
米国では結構あるらしいですが。
企業業務とは則ち記号処理なのに一般企業が
業務用に記号処理言語を採用しないことは
奇妙ですね。
役員会議を初めとする会議録、業務日誌の分析。
企業の末端活動の記録である会計伝票の摘要解析に
手を付けないのは何故でしょうか。
965デフォルトの名無しさん:2007/10/11(木) 18:33:07
日本語は区切るのすら難しいからPrologの出番なんてない
966デフォルトの名無しさん:2007/10/11(木) 21:01:29
Excel使い>SQL使い>Prolog使い
かな?
やっぱ一般業務はある程度枯れた環境じゃないと
967デフォルトの名無しさん:2007/10/12(金) 07:29:29
>>965
形態素解析はJumanを使いますが、それでも
結構複雑な解析ができますよ。
968デフォルトの名無しさん:2007/10/12(金) 07:41:38
>>966
全くの初心者を対象にした場合の使い易さでは
カルクものは馬鹿にならないですね。
ブログミングもデータベースも一覧で対象データが
使い手に「見えている」環境を想定していません。
Prologのlistingにして然りです。一方、カルクものは
見えているけど計算が大変という問題を解決しています。
盲点だったかも知れません。
969デフォルトの名無しさん:2007/10/12(金) 08:27:04
>>960
私の所は年商100億円の卸売業(小売業に換算すると10-30億くらいか)ですが、
20年弱、営業、総務の実務はPrologインタプリタのみです。
インタプリタトップから売上伝票を入力し、入力検査、管理帳票出力、
請求書等の印刷まで行います。
?- 請求書発行('20070930').
のような感じてすね。
データベースはProlog内部データベースとPostgreSQLの併用になっています。
経理は最終的に帳票作成が面倒だったので、有無曲折はありましたが
現在は"弥生"です。データベースを使う会計ソフトではないので、データの
Prologへの移転に苦労しています。
弥生以前の"大番頭"を導入する前にPrologインタプリタトップから
「完全な摘要入力」による自動仕訳システムを作ったのですが、
厳密な日本語入力が面倒ということで実際には使用しませんでした。
970デフォルトの名無しさん:2007/10/12(金) 21:21:40
メガネのミキがprologを業務に利用してるらしいが、詳細は不明
971デフォルトの名無しさん:2007/10/12(金) 21:29:16
>>967
今まで MeCab とか試してみたが、人間のほうがやっぱり圧倒的に高性能だった。
俺がなんか間違ってるのかな?さしつかえない範囲でサンプルとか設定を見せてくれません?
972デフォルトの名無しさん:2007/10/13(土) 01:32:20
形態素解析なら、人間の方が高機能でも、
疲れたり飽きたりするし、処理速度も遅いよ。
973デフォルトの名無しさん:2007/10/13(土) 08:32:46
>>971
辞書は追加していますが、jumanrcファイルなどの設定は変えていません。
上に出てきた会計伝票の摘要処理だとほとんどが
?- 形態素解析(文,'社長大阪出張、新幹線往復代金',X).
X = ['社長','大阪','出張','、','新幹線','往復','代金']
というレベルです。これでも、一々文字検索をしながら
構成していくよりは、全段がしっかりあるだけまし、ということです。
少々分解されすぎて困るということは確かにあって、
?- 形態素解析(文,'第一回選手権大会参加者名簿をください',X).
X = ['第','一','回','選手権','大会','参加','者','名簿','を','ください']
この後、例えば、第一回と再結合する必要部分を見つけ出すのが実は大変です。
974973:2007/10/13(土) 21:35:02
全段 -> 前段
975デフォルトの名無しさん:2007/10/14(日) 20:10:29
むー。これを見るかぎり、形態素解析より上位の層での差ってことか……まだまだ修行が足りないです。
976デフォルトの名無しさん:2007/10/16(火) 22:49:29
Prolog入門によい処理系と教科書をおしえてください。
C++やPerl, make, Bisonは一応使えます。
977デフォルトの名無しさん:2007/10/17(水) 07:42:09
処理系は SWI-Prolog です。
教科書は、「Prologへの入門」I.Bratko著 安部憲広訳が有名です。原書は
「Prolog Programming for Artificial Inteligence」という分厚い本ですが
何故か日本では入門編と応用編「AIプログラミング」といった体裁で分冊されました。
原書は11月に最新版が出版されますから横に並べて読まれるとよいと思います。
この本の他に
「Prologの技芸」という人気本がありますが、現在なんと絶版です。私は、
「Prologを学ぶ -文化とその実践-」 杉崎昭生著という本を推薦します。

そのほか典型的な教科書タイプの本も10冊以上出版されていますが、
「情報学概論 Prologプログラミング」吉田要著 や
「Prologプログラム入門」安部憲広著 が代表的なものでしょう。
やや高度な応用を期待する場合は、
「Prologとその応用2」溝口文雄監修 溝口文雄・武田正之・畝見達夫・溝口理一郎共著
「自然言語解析の基礎」田中穂積著の第4章。
「自然言語処理入門」岡田直之著の第4章。
「エキスパート・システム入門」安部憲広・滝寛和共著の第2章。
「PROLOGデータベース・システム」D・リー著 安部憲広訳

「楽しいプログラミング2 記号の世界」中島秀之・上田和紀共著も良い本
だと思いますが、校本の故か読み難い。
「PROLOGを楽しむ」松田紀之著も同様です。この2冊は楽しい本だと思います。

奇書としては、「法律家のための コンピュータ利用法 論理プログラミング入門」加賀山茂著
という本があります。徹頭徹尾Prologについて書いてある本ですが、
実に面白い本です。

978デフォルトの名無しさん:2007/10/17(水) 08:53:10
Prolog Programming for Artificail Intelligence ですね。エルが一つ
抜けた。それから、
「Prologを学ぶ -文化とその実践-」 杉崎昭生著の推薦理由は
この本だけが、処理系を用意してプログラミングすることなしに、
ぐいぐい読み進むだけでProlog言語の概要を理解できる本では
ないかということです。それが可能なのは著者がPrologを上手に
利用して、そのコードとノウハウの中から著作が自然と生まれて
いることに起因するのではないかと推察しています。
979デフォルトの名無しさん:2007/10/17(水) 22:20:05
ありがとうございます。
アマゾンでチェックして読んでみます。
980デフォルトの名無しさん:2007/10/24(水) 23:33:27
ネタで、これからProlog勉強してCGI作るハメになってしまったのだが、
環境変数にアクセスしたり、データ構造をファイルにシリアライズしたりできるものなの?
981デフォルトの名無しさん:2007/10/25(木) 01:09:47
>>980
処理系によると思うけれど
getenv/2とsub_atom/5(/の後の数字は引数の数)の二つを使ってQueryStringを
分解する。
シリアライズの意味はよく知らないが、
writeq(_項) で項がどんなに複雑な構造体であっても
ストリームに書き出せる。XMLのタグ構造で表現したいときは
そういうライブラリがない場合には
functor/3とarg/3いう述語の組み合わせか、
=.. (/2でユニブと読む)という述語で
構造体を関数部分と引数に分解できるので再帰的に
タグとして書き出せばよい。
982デフォルトの名無しさん:2007/10/25(木) 06:48:36
>>981
メソッドがGET(htmlからのリクエストの時のformタグのaction="GET")の
時の話。
メソッドがPOST(action="POST")の時は、標準入力から渡されるから、
get_char/1 を使って再帰的に一度文字のならびのリストを構成する。
それをatom_chars/2を使ってatom(文字列)に
変換してから(変換しなくてできるが)、
Content-Length: Char-Code: 等を
探して必要な情報部分をsub_atom/5で切り出す。
983デフォルトの名無しさん:2007/10/25(木) 13:28:03
Char-Code: はなかった。あるのはAccept-Charset: かな。
984デフォルトの名無しさん:2007/10/25(木) 18:35:53
文字列処理をしたいのに、文字列全体をatomにする理由がわからない。
文字のlistのままの方がはるかに柔軟だと思うが。
985980:2007/10/25(木) 19:55:22
>>981-984
情報あんがと。
ようするにそういうモジュールとか無いから、CやPerlで大昔やったように自前でやらなくちゃいけないって事ね。
しかも明らかに向かない言語で。

初心者なのにそんなマゾいことやらされるなんて、考えただけでもゾクゾクしてきました
986デフォルトの名無しさん:2007/10/25(木) 20:25:28
>>984
sub_atom/5が非決定性の述語でそれ自体でsplitの
能力があり、しかも対象文字列に対して全解が得られる。
検索語を指定してその前部分と後部分に分けて処理する。

append/3を多用するスタイルも魅力的だが、このように
sub_atom/5を多用するスタイルもある。
987デフォルトの名無しさん:2007/10/25(木) 20:35:01
>>985
Prologはライブラリなしでその場でプログラミングするスタイルで
あるのは確かだ。ただ、大昔やったことかも知れないが、Perlで書く
コードとほとんど長さで差がなく、しかも、この言語の方が文字列を
解析するコードを表現するのに適しているので、最終的には生産性が
高い。
どこかのサイトにPrologはReadOnlyProgram言語でPerlは
WriteOnlyProgram言語であるという記述があったが、
可読性の良さという観点ではCやPerlとPrologでは比較にならない。
988デフォルトの名無しさん:2007/10/25(木) 20:43:40
日本人が水のコストをタダだと思っていると批判的に指摘される
ことがあるらしい。多くのプログラマはライブラリの参照コストを
ゼロだと誤解しているようだ。ライブラリを引いてる隙があったら
コードを書けばよいというのが、Prologのスタイルだ。
一度書いたら、以後はすぐに書けるようになるから、事実上、
自分の中にライブラリを持つことになる。
989デフォルトの名無しさん:2007/10/26(金) 04:55:55
>>987
PrologがReadOnlyであるというのは、
可読性だけはすばらしいが、プログラムを書こうとすると、
カットの効果など、わけがわからない点が多く、さっぱり
書き進まないという揶揄です。(Haskellなどに較べて)
一方、PerlをWriteOnlyというのは、書いたときは意味が
解っていても、後で読むとなにを書いたのかさっぱり解らなく
なるの意味かな。それともただただ文字を書き出すだけの言語と
いうことだろうか。
990デフォルトの名無しさん:2007/10/26(金) 08:27:44
991デフォルトの名無しさん:2007/10/26(金) 16:15:54
>>989
Perl のソレは「後でコードが読めない」の意味だと思う。
992デフォルトの名無しさん:2007/10/26(金) 20:09:20
>>990
乙。
3年がかりで1000か。一日平均一レス。

確か990を超えるとスレが落ちやすいそうだから、埋めるか保守するかが必要かな。
993デフォルトの名無しさん:2007/10/26(金) 20:22:58
埋めついでに、感謝の意を表したいと思います。
私にはよく分からないけど、このスレの内容はとても面白いと思う。

同じくこのスレに興味を持っている人の例。

http://page.freett.com/shelarcy/diary_2005-04.html#aprile232005
http://page.freett.com/shelarcy/log/2006/diary_05.html#he_is_not_real_expert_all_till_range_end_of_the_world

この人はITProのHaskell連載の著者の方です。
http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248215/
994デフォルトの名無しさん:2007/10/27(土) 14:54:14
.
995デフォルトの名無しさん:2007/10/27(土) 14:55:07
.
996デフォルトの名無しさん:2007/10/27(土) 14:55:38
.
997デフォルトの名無しさん:2007/10/27(土) 14:56:25
.
998デフォルトの名無しさん:2007/10/27(土) 15:00:25
.
999デフォルトの名無しさん:2007/10/27(土) 15:01:14
.
1000小倉優子 ◆YUKOH0W58Q :2007/10/27(土) 15:02:00
1000ならジュースでも飲むか
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。