1 :
デフォルトの名無しさん :
2007/10/26(金) 08:26:46
2 :
デフォルトの名無しさん :2007/10/26(金) 09:09:35
2
最新のスレッド(Prolog) :- 3.
乙(1).
ERROR: Undefined procedure: 乙/1
live(乙一).
ERROR: Suspended writer: 乙一
:- 乙(>>(1)).
?- halt.
半日で(67)か。age進行のスレが多いのだな。 ちょっと質問です。 皆さんが使っているTCP/IP関連の述語を教えてください。 組込、ユーザ定義を問わず。 できれば、引数の定義域が解るといいな。 ライブラリを作ろうとか、標準化を考えようなどと いうのではないけれど、皆さんがどのレベルまで 抽象化して使っているかは知りたい。
本当の意味でのPrologの第一世代は1960年生まれですね。 大学卒業時にICOTの活動が始まったという世代です。 この人達が、リタイアするのは2020年以降。ここから Prologの再興が始まるのでしょうね。具体的には、 金も少しはあり、青春時代の思い出に浸る余裕を持った 人たちが、集まって論理プログラミングをテーマとする 会社を興す。研究会を始める。そんな動きが期待されます。 だから当分は、Prologでまったり、ですね。
12 :
デフォルトの名無しさん :2007/11/03(土) 00:39:09
最近prologを勉強し始めました。 疑問なのですが、prologで作ったプログラムをGUI化することはできるのでしょうか? javaでプログラムのGUI化はしたことがあるんですが、 prologはどうやればいいのか見当もつきません。 どなたか教えて頂けませんでしょうか?
>>12 ISOの標準ではグラフィックについての言及はありません。したがって、
個々の処理系対応ということになります。
・ Windows環境のみですが最もグラフィック述語の完備しているのはVisualPrologでしょう
・ SWI-PrologはXPCEというグラフィックライブラリを最初に付加インストールしておけば
・ MinervaやPrologCafeといったJava系PrologはJavaのクラスを呼びだすことによって可能だと思います。
・ K-PrologだとTCK/TLのインターフェイスがあるのでこれを使うのでしょう。
write等CUI用の述語を含む定義を ?- cui2gui(foo/0). のように一発で
GUI対応のひな形に変換する述語や外部コマンドの存在は聞いたことがありません。
なお、VisualProlog,Minerva,K-Prolog は有料です。
>>13 >>14 に代表的なProlog処理系を挙げたと思うのですが、この中で、
日本語処理が満足な水準なのは、
SWI-Prolog K-Prolog Minerva IF/Prolog(上にはない) AZ-Prolog
で他はだめですね。私にとってはこれは絶対的な条件ですから、
他のPrologは興味がありません。
悲しむべきお知らせ。 "PROLOG Programming for Artificail Intelligence" Ivan Bratko著の 最新版の出版が来年の五月に延びてしまいました。
1980年代から90年代にかけて、Prologが全盛期であったことは 大方の認めるところ。この時期に書かれたPrologの記事は その微妙な時期的な問題から、今日Web上で参照することが 難しい。著作権、版権の問題があり、勝手に公開することは 勿論できません。しかし、これは残念なことです。 今日も、"Functional Grammer in Prolog" Simon C.Dik著と いう本を開いてため息をついてしまいました。本を開いたら、 いきなりヒバリのさえずりが聞こえた、という例えがあり ますが、そんな本です。ああ、こんな本を、Webが良いというなら そこに公開してあげたいな。そっくり、タイプするくらいの 手間なら厭わないのに。残念。 Prologの本って、和書も含めて、そんな本だらけです。当時は ちょっと馬鹿にして読まなかった本が実に工夫されて良く書けて いる。どれも味があります。 私、もうすぐ死ぬのかな?
例え ではなくて 譬えか
19 :
デフォルトの名無しさん :2007/11/06(火) 03:57:12
>>15 で日本語処理という話がでましたが
極めて簡単な日本語処理テストの方法を書いておきます。
?- assertz((山田(_太郎) :- write(_太郎))).
yes
?- 山田(太郎).
太郎
yes
?-
この通り動けばほぼ合格とみてよいでしょう。
ただ、文字コードのある領域だけエラーになると
いう例もあったので、完全ではありません。
20 :
12 :2007/11/06(火) 07:57:26
皆様ありがとうございます。 prologで作ったプログラムはHTMLで表示可能なのでしょうか? 現在、prologで旅行経路検索プログラムを作っているのですが、 これをWeb上でクリックや数字を入力して利用できるようにしたいのです。 やはり素人には難しいですか?
ラッパー被せたらなにも問題ないと思うけど、、 まあ、標準出力のはじめにヘッダー吐くようにしておけば、あとは普通に標準出力でかまわないね。 ただ、インタラクティブな操作はすこし難儀そうだ。
自宅サーバの場合は問題ないが、サーバがプロバイダの環境にあるときは、 サーバサイドでPrologが使えることが条件。一番簡単な方法は CGIをPerlでやって、その中でsystem("Prolog ... ")でPrologを呼びだす。 引数の中にtmpnam(一時的なファイル名)を含めておく。 GETメソッドの入力情報はそのままQUERY_STRINGをPrologでgetenvすればよい。 Prologは受け取った情報を解析して(splitの処理)利用し、結果を ... ?- atom_append(TMPNAM,'.html',HTMLファイル名), open(HTMLファイル名,write,Output), ... ,write(Output,'<html>\n'), ... ,write(Output,'</html>\n'), close(Output),halt. これで、Perl側のsystem("prolog ... ") は終了するから、 print "Location: tmpnamのURL " print ".html\n\n" までやってそれからPerlを終了させればよい。POSTメソッドの場合は 後で。GETを使うかPOSTを使うかはあなたに主導権があるから、 一応これでできるはず。
QUERY_STRINGから受け取った情報はPrologで読める形式に戻す
必要がある。
使うPrologにライブラリがあれば別だが、ないと、
以下のようなパーツが必要になる。
% *** user: replace_query_2 / 3 ***
replace_query_2('2','F',/) :- ! .
replace_query_2('2','8','(') :- ! .
replace_query_2('2','9',')') :- ! .
replace_query_2('2','B',+) :- ! .
replace_query_2('2','D',-) :- ! .
replace_query_2('2','7','''') :- ! .
replace_query_2('2','7','''') :- ! .
<略>
漢字コードの変換はさらに面倒。
これは長くなるので、どうしても必要なら、
http://pc11.2ch.net/test/read.cgi/mysv/1188833105/ で質問してください。
漢字コードを極力使わないためにはHTMLファイルの selectタグを <select name="ekimei"> <option value="shibuya">渋谷</option> <option value="shinjuku">新宿</option> </select> のように返ってくる値をローマ字に変換すればよい。 勿論inputタグは使わない。 これに徹すればPrologの解析部分は随分と楽です。
tuPrologがなかなかいい件
27 :
23 :2007/11/07(水) 16:34:28
>>26 まぁ単体で使っていいことはないんだけどね.
俺は自前のJavaプログラムからtuPrologの機能使ってるんだが,
かなりいい感じ.Java同士だから相性抜群てとこかな.
マニュアルもしっかりしてるところも嬉しい.
Javaから使った場合は最高(使いやすさは).
使い方はダウンロード&解凍→ 2p.jarってのが実行ファイル
これがIDEっぽい感じ.
日本語は△ってとこかな.
IDE使うと日本語は書けない.
でも,テキストエディタで書いてtuPrologで読込むと
文字化けして日本語が全部"□"になってしまうんだが,
きっちり認識されてて,実行できる.
>>28 ありがとう。version 2.1 が動きました。
IDE風の実行環境では、
>>19 の日本語テストは完全に動きました。
OSはRedhat9なのですが、文字コードがEUCのせいですね。
FedoraCore5でもやってみましたが、同じ結果となりました。 一つ気になることは Output という表示で '太郎' となることです。 ?- tell(temp),山田(太郎),told. を実行してファイルtempを見てみるとやはり、'太郎'になっています。 'を削除するというやっかいな仕事が後に残りそうです。
私のFedoreCore5の環境は # mkdir $JAVA_HOME/jre/lib/fonts/fallback # ln -s /usr/share/fonts/japanese/TruType/*.ttf $JAVA_HOME/jre/lib/fonts/fallback/. が掛かっています。
32 :
31 :2007/11/07(水) 20:33:22
/TruType/ ではなく /TrueType/ ですね。
このtuPrologを使うと、JavaServletからPrologを 呼びだすというようなことが自在になるのでしょうか。 そうだとすると、面白いですね。 MinervaだとJavaAPIの各クラスが簡単な指定で、 Prologの述語として定義できてしまいます。 tuPrologではどうでしょうか。
36 :
34 :2007/11/07(水) 23:18:43
以下のような参照をしたい場合があります。 ?- _締日@>='20070901',_締日@=<'20071031',売掛(_顧客,_締日,_前残,_入金,_売上). これは普通のPrologインタプリタではエラーとなります。それをなんとかしたい。 という場合があるということです。 ?- 売掛(_顧客,_締日,_前残,入金,売上),_締日@>='20070901',_締日@=<'20071031'. で何故だめなのか? 外部のデータベースを参照する場合具合が悪いのです。あとの質問が ?- select * into X from 売掛, member([_顧客,_締日,_前残,_入金,_売上],X), _締日@>='20070901',_締日@=<'20071031'. に変換されたとします。これですと、売掛テーブルに50万タップルあったと するとスタックオーバーフローの危険が生じます。TCP/IP経由で これだけのデータを受け取るのには相当の時間もかかるでしょう。それで、 ?- select * into X from 売掛 where 締日>='20070901' and 締日<='20071031'. に変換したいものです。 <以下、続く>
?- select * into X from 売掛 where 締日>='20070901' and 締日<='20071031', member([_顧客,_締日,_前残,_入金,_売上],X). でしたね。memberを落としてしまいました。 後の質問から、この節を導くのが難しいのですが、最初に示したエラーに なる質問からだとそれほど難しくありません。 基本的にはtracer(debugger) の話ですが、制約論理プログラムや遅延評価への ヒントもすこしは含む話になります。
39 :
デフォルトの名無しさん :2007/11/09(金) 07:52:40
Prologの内部データベースを参照しているコードでは ?- 売掛(_顧客,_締日,_前残,入金,売上),_締日@>='20070901',_締日@=<'20071031'. の順序であり、これを外部データベース参照用に切り替えたいという要求も 当然ありますから、難しいとは言ったけれど、この話の最後に研究してみましょう。
Prologでまったり-2に書いた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). これに Var @>= atom がエラーにならないように細工しましょう。 solve(fail,_) :- !,fail. の後に solve(Var @>= X,_) :- (var(Var);var(X)),!. を挿入することで エラーになることは回避できます。しかし、これではただtrueと解釈した ことと変わりません。Var @>= X をどこかに保存して、後で、利用したい。
... , 売掛(_顧客,_締め日,_前残,_入金,_売上), ... で参照(照会の方がいいか)時、 Prologデータベースに述語定義がある場合とない場合がある。ここでは話を わかりやすくするために、述語定義のない場合のみ扱う。 solve(P,V) :- functor(P,F,A),predicate_type(F/A,undefined),solve(# P,V),!. を solve(P,V) :- !,clause(P,Q),solve(Q,W),(nonvar(W),!,fail;true). の上に挿入する。 そして、述語 #/1 の定義を solve(# P,V) :- !, ここにデータベース照会のBODYが来る solve(P,V) :- functor(P,F,A),predicate_type(F/A,undefined),solve(# P,V),!. solve(P,V) :- !,clause(P,Q),solve(Q,W),(nonvar(W),!,fail;true). インタプリタの定義は節の構成としてはこんな感じでよい。問題は、制約情報の渡し方だ。 そして、データベース照会述語 #/1 の定義。 結論を言ってしまえば、制約情報の伝達は assertz(制約情報(_締日 @>= '20070901')) のような述語定義で渡すことはできない。
この問題の簡単な実験をする。 ?- X = Y,assertz(foo(Y)),foo(Z),Z==X. no になる。assertz時の Y に対するリンクから foo(Z) のZは 切り離されている。ただし、間違えて、 ?- X = Y,assertz(foo(Y)),foo(Z),Z=X. としないように。 後でこういう失敗の例を挙げるがX,Yとは無関係であっても、 Zは単なる変数、XやYと単一化してしまう。これだと実験にならない。
述語定義による変数情報の受け渡しがうまくないとすると、 引数による渡しということになる。ストリームを架ける。 全ての述語定義の第一引数にこのストリームを付加すると いう行き方もあるが、それはしたくない。 solveの変更だけですむだろうか。 solve(V1 @>= V2,V,V1 @>= V2) :- (var(V1);var(V2)),!. solve(# P,V,L) :- !, solve(P,V,L) :- functor(P,F,A),predicate_type(F/A,undefined),solve(# P,V,L),!. solve(P,V,L) :- !,clause(P,Q),solve(Q,W,L),(nonvar(W),!,fail;true). でどうか。 これだと ?- _締日 @>= '20070901',_締日 @=< '20071031', のような場合には対応できない。 Lを重リストにする、という案がすぐに浮かぶが重リスト自体初心者には 理解しにくいので、 solve(P,V,L,L) :- functor(P,F,A),not(predicate_type(F/A,undefined)),not(predicate_type(F/A,linear)),!,call(P). solve(V1 @>= V2,V,L1,[V1 @>= V2|L1]) :- (var(V1);var(V2)),!. solve(# P,V,L1,L2) :- !, ここで 変数情報から where 締日 >= '20070901' and 締日 <= '20071031', を生成する solve(P,V,L1,L2) :- functor(P,F,A),predicate_type(F/A,undefined),solve(# P,V,L1,L2),!. solve(P,V,L1,L2) :- !,clause(P,Q),solve(Q,W,L1,L2),(nonvar(W),!,fail;true).
これで、solveの節定義は大体できあがり。最後に、 #/1の定義。 # _副目標 :- _副目標 =.. [_関係表名|_引数ならび], select cname into _属性名ならび from col where tname=_関係表名, 条件の選別(_属性名ならび,_引数ならび,_条件句候補), ( not(_条件句候補=[]), 条件句の作成(_条件句候補,_条件句), select * into X from _関係表名 where _条件句; _条件句候補=[], select * into X from _関係表名 ), member(_引数ならび,X). あとは、条件の選別/4で [_締日 @>= '20070901',_締日 @=< '20071031']を [締日 >= '20070901',締日 <= '20071031'] に変換します。
条件の選別([],[],[],VL) :- ! . 条件の選別([[A|_]|R1],[B|R2],[A = B|R],VL) :- \+(var(B)), 条件の選別(R1,R2,R,VL), ! . 条件の選別([[A]|R1],[B|R2],[A >= B2|R],VL) :- var(B), member(B1 @>= B2,VL), B==B1, 条件の選別(R1,R2,R,VL), !. 条件の選別([[A]|R1],[B|R2],[A <= B2|R],VL) :- var(B), member(B1 @=< B2,VL), B==B1, 条件の選別(R1,R2,R,VL), !. 条件の選別([_|R1],[_|R2],R,VL) :- 条件の選別(R1,R2,R,VL). 条件句の生成/4 は and で繋いでいるだけです。
条件句の生成/4 出はなくて 条件句の作成/4 でした。 以上で大体(細部には問題有り)できあがりですが、もう一度どうして こんなことを長々書くのか説明して終わります。 15年以上前ですが、Prolog処理系の作成者として有名なK氏とSQLの集約命令に ついて、雑談していました。その中でK氏がSQLのgroup by 句はよくない。 あれですんなり理解できる素人は少ないとの意見を述べられました。そして、 PrologのQueryのようなもので代替するべきことを暗に指摘しました。 私もK氏とまったく同意見でその時以来これは私のテーマの一つとなり、 実務で使用するデータベース照会述語を少しずつSQLからProlog述語に置き換えて いったのです。今回は最も単純なものを載せました。 このほかにも、中島秀之氏が提唱されたことのある「項記述」を借用したもの などに奥行きを感じました。これは、述語呼び出しに手を入れるもので、 売掛(_顧客,{_締日|_締日@>='20070901',_締日@=<'20071031'},_前残,_入金,_売上), のような呼び出し方になります。もとの副目標としての形式を毀してしまうので、 使いにくいのですが、考えてみれば、_締日 @>= '20070901', を呼び出しの 前に追加挿入することも同じことですから、これでよいのかも知れません。
乙 おもしろかった。
>>45 大変なミス。# _副目標 :- ... はsolve/4のインラインでないと変数情報が
渡せませんでした。
solve(# P,V,L1,L2) :-
!,
P =.. [_関係表名|_引数ならび],
select cname into _属性名ならび from col where tname=_関係表名,
条件の選別(_属性名ならび,_引数ならび,_条件句候補,L1),
( not(_条件句候補=[]),
条件句の作成(_条件句候補,_条件句),
select *
into X
from _関係表名
where _条件句;
_条件句候補=[],
select *
into X
from _関係表名
),
member(_引数ならび,X).
でなくてはいけません。ただし、( ) の部分は別述語として定義する
べきでしょう。
Prologの変数同士の単一化には陥穽があって、 条件の選別([[A]|R1],[B|R2],[A >= B2|R],VL) :- var(B), member(B1 @>= B2,VL), B==B1, 条件の選別(R1,R2,R,VL), ! . を 条件の選別([[A]|R1],[B|R2],[A >= B2|R]) :- var(B), member(B @>= B2,VL), 条件の選別(R1,R2,R,VL), ! . とやると、 select * into X from 売掛 where 顧客番号='20070901' and 締日>='20070901' and 前残>='20070901' and 入金>='20070901' and 売上>='20070901', というQueryを生成して見事に失敗します。 初心者の人はなぜそうなるか考えてみてください。
顧客番号 ではなく 顧客 ね。
>>48 solve(# P,V,L1,L2) :- !,データベース呼び出し(P,L1).
データベース呼び出し(_副目標,L1) :-
_副目標 =.. [_関係表名|_引数ならび],
select cname into _属性名ならび from col where tname=_関係表名,
条件の選別(_属性名ならび,_引数ならび,_条件句候補),
...
でよいのか。
またしくじった!! solve(# P,V,L1,L2) :- !,データベース呼び出し(P,L1). データベース呼び出し(_副目標,L1) :- _副目標 =.. [_関係表名|_引数ならび], select cname into _属性名ならび from col where tname=_関係表名, 条件の選別(_属性名ならび,_引数ならび,_条件句候補,L1), ... ですね。
どなたか、P# の使い方を教えてください。Redhat9 で mono が動いています。 # cat ap.pl ap([],X,X). ap([U|X],Y,[U|Z]) :- ap(X,Y,Z). # mono /root/psharp/Psharp-1.1.3/PsharpIntrp.exe P# 1.1.3 Copyright(C) 2003 J.J.Cook Based on: Prolog Cafe 0.4.4, 0.6.1 Copyright(C) 1997-2003 M.Banbara and N.Tamura Small Prolog Interpreter | ?- compile(ap). {translating ap.pl into C#...} {ap.pl translated, 1523 msec} yes | ?-halt. # ls -l *.cs -rw-r--r-- 1 root root 4290 11月 9 20:06 Ap_3.cs # mcs /r:Psharp.dll /out:Ap_3.exe Ap_3.cs error CS5001: Program `Ap_3.exe' does not contain a static `Main' method suitable for an entry point Compilation failed: 1 error(s), 0 warnings # これは何が起きているのでしょうか。
>>45 友人からバグがあるとの指摘を受けました。確かに。
'条件の選別'([],[],[],_) :- ! .
'条件の選別'([[A|_]|R1],[B|R2],[A = B|R],VL) :-
\+(var(B)),
'条件の選別'(R1,R2,R,VL),
! .
'条件の選別'([[A|_]|R1],[B|R2],[U2|R],VL) :-
var(B),
member(U,VL,VR),
U =.. [Func,B1,B2],
B==B1,
関数変換(Func,A,B2,U2),
'条件の選別'([[A|_]|R1],[B|R2],R,VR),
! .
'条件の選別'([_|R1],[_|R2],R,VL) :-
'条件の選別'(R1,R2,R,VL) .
関数変換(@>=,A,B2,U2) :- U2=..[>=,A,B2],!.
関数変換(@=<,A,B2,U2) :- U2=..[<=,A,B2],!.
関数変換(=<,A,B2,U2) :- U2=..[<=,A,B2],!.
関数変換(Func,A,B2,U2) :- U2=..[Func,A,B2],!.
member(A,[A|R],R).
member(A,[_|R],R2) :- member(A,R,R2).
再帰の末尾の呼び出し方が間違ってました。一つの引数に対して
式が複数あることもありますから。
例: 締日>='20070901' and 締日<='20071031'
これでもだめですね。うーん。・・・ 一引数増やして・・・ '条件の選別'(A,B,C,D) :- '条件の選別'(A,B,C,D,D). で呼びます。 '条件の選別'([],[],[],_,_) :- ! . '条件の選別'([[A|_]|R1],[B|R2],[A = B|R],VL,VL2) :- \+(var(B)), '条件の選別'(R1,R2,R,VL,VL), ! . '条件の選別'([[A|_]|R1],[B|R2],[U2|R],VL,VL2) :- var(B), member(U,VL2,VR), U =.. [Func,B1,B2], B==B1, 関数変換(Func,A,B2,U2), '条件の選別'([[A|_]|R1],[B|R2],R,VL,VR), ! . '条件の選別'([_|R1],[_|R2],R,VL,_) :- '条件の選別'(R1,R2,R,VL,VL) . 一引数増やして第4引数に変数情報リストの原型を持ち回ることにしました。 一度使った情報は使わないようにしたかったのですが、引数の順序に整順に 変数情報が現れるわけではないので。
nbsp を入れ忘れましたね。すみません。第一引数か変化したときに リストを原型に戻すという手法ですね。なお、引数は _属性名リスト,_引数ならび,_解の収集欄,_変数情報リスト原型,_残りの変数情報リスト です。
以下は典型的なプログラムパターン。 fooの第二引数に予め、findall/3で述語定義から情報を収集しておくことが多い。 第二、第三引数を省略して述語呼び出しとバックトラックでやろうとすると失敗する。 foo([],_,_,[]). foo([A|R1],L,L2,[B|R2]) :- foo_2(L2,LR,A,B), foo([A|R1],L,LR,R2). foo([_|R],L,_,X) :- foo(R,L,L,X). foo_2(L,LR,A,B) :- member([A,B],L,LR).
今回もバグの山、粗忽の見本となりました。Prologでまったり2で 随分ベテランらしいプログラマがエラーの連続とするということは、 Prologというのは余程不完全な言語らしい、との評もいただきました。 バグの山となるのは私の性格と能力によるものでこんなことで、 Prologの評価が下がるのは残念です。 私のスレへの書き込み環境はFirefoxの縦六行の<textarea>で全く読み返しを しませんから(上にスクロールしたものも)ミスがでるのも仕方ないと 思っています。それどころか、Prologプログラミングの理想は 思考経路が陽に現れたものではないかとさえ思っています。誤謬も含めて、 そのプログラムを読んだ人が、ああ、この人はああ考え、こう考えて、 ここのコードを書いたのだなと解るコードこそ、論理プログラミングの 極致ではないか。コピペや参照を極力避けて、狭い窓の中での 即時的なミニマムな思考がPrologのプログラミングとして現れている、 そう人が感じてくれるコードを書きたいものです。 とんでもない、エラーや思い違いが貴重なこともあるのではないか。 このプログラミング言語が世に現れたちょうど同じ頃、サティの音楽が 街に溢れ始めました。
あなたをベテランだと考えている人間はごく少数だと思われます。
60 :
デフォルトの名無しさん :2007/11/23(金) 17:25:30
w-zero3というwillcomの携帯(WS003SH)にswi-prologをインストールされた方もしいらっしゃれば、手順を詳しく教えていただけないでしょうか?
下のページを見ながら挑戦しているのですが、いくつかあるpl.exeどれをインストール・実行しても「有効なPocketPCアプリケーションではありません」と出て実行できないのです。
ttp://www.rainer-keuchel.de/wince/swi-prolog.html また、swi-prolog以外で、windows mobile で実行できるprolog環境でおすすめのものがありましたら是非教えていただきたく思います。
このためだけにwilcomの携帯を購入する訳にもいかないので、この話私はパス。
こういう風にやればいいの?
つけてみた
A「私は右から二番目。Bと隣り合わせ」 B「私の隣には嘘をついてない人がいる」 C「私は嘘をつかない人だから、妬まれて2人に挟まれてる」 D「私の左は悪い人、右は良い人」 ABCDのうち、2人が嘘つき。並んでる順番を求めなさい。 ってのを見て、Prologでやろうと思ったが書き方が分からん。
66 :
デフォルトの名無しさん :2007/12/18(火) 17:58:46
/* # 一度で書き込めないので、前半 A「私は右から二番目。Bと隣り合わせ」 B「私の隣には嘘をついてない人がいる」 C「私は嘘をつかない人だから、妬まれて2人に挟まれてる」 ==> 妬む2人は嘘つきということと解しておく D「私の左は悪い人、右は良い人」 ==> 悪い人=嘘つき、良い人=嘘をつかない人と解しておく ABCDのうち、2人が嘘つき。並んでる順番を求めなさい。 */ % 同値の定義 % 嘘つき(fail)の言っていることは嘘, % 嘘をつかない人(true)が言っていることは真実 % 嘘つき(fail)か嘘をつかない人(true)か、とその言明は同値 eqvalue(X,Y):- X , Y. eqvalue(X,Y):- \+ X , \+ Y. % すべての並び順を生成 map(Seed,A,B,C,D):- select(Seed,A,AR),select(AR,B,BR),select(BR,C,[D]). select([A|L],A,L). select([A|L],B,[A|R]):-select(L,B,R). % リストの要素 member(A,[A|_]). member(A,[_|L]):-member(A,L).
67 :
デフォルトの名無しさん :2007/12/18(火) 17:59:51
% 後半、タブが詰まってしまい、見づらいが。 go:- OrderMap=[('A',AOrder,ATF),('B',BOrder,BTF),('C',COrder,CTF),('D',DOrder,DTF)], % 名前、並び順、嘘つきかどうかなど組み合わせ表 setof([A,B,C,D],map([true,true,fail,fail],A,B,C,D),L), member([ATF,BTF,CTF,DTF],L), % A,B,C,Dの嘘つき・嘘をつかないの組み合わせを順次生成 map([1,2,3,4],AOrder,BOrder,COrder,DOrder), % A,B,C,Dの順序の組を順次生成 % 以下、各人の言明を検証する eqvalue(ATF,(AOrder is 3,(BOrder is AOrder-1;BOrder is AOrder+1)) ), % Aは三番目(右から二番)Bは隣 eqvalue(BTF,((NextB is BOrder-1,NextB>0; NextB is BOrder+1,NextB<5), % Bの隣、前か後ろで1以上5未満の位置 member((_,NextB,true),OrderMap)) ), % Bの隣は嘘をつかない人 eqvalue(CTF,(CTF, % Cは嘘をつかない人 member(COrder,[2,3]),BeforeC is COrder -1,AfterC is COrder+1, % Cは左右に人が配置できる位置 member((_,BeforeC,fail),OrderMap),member((_,AfterC,fail),OrderMap)) ), % 左右とも嘘つき eqvalue(DTF,(member(DOrder,[2,3]),BeforeD is DOrder -1,AfterD is DOrder+1, % Dは左右に人が配置できる位置 member((_,BeforeD,fail),OrderMap),member((_,AfterD,true),OrderMap)) ), % 左嘘つき,右嘘つきでない write(OrderMap),nl,fail. % 結果表示。全解を求めるためにfailさせる /* | ?-go. [(A,1,fail),(B,3,true),(C,4,fail),(D,2,true)] [(A,1,fail),(B,4,true),(C,2,fail),(D,3,true)] [(A,2,fail),(B,4,true),(C,1,fail),(D,3,true)] [(A,4,fail),(B,3,true),(C,1,fail),(D,2,true)] [(A,3,true),(B,2,true),(C,1,fail),(D,4,fail)] [(A,3,true),(B,2,true),(C,4,fail),(D,1,fail)] [(A,3,true),(B,4,true),(C,2,fail),(D,1,fail)] no */
保守。
Prologを使ってる方がいらっしゃるようなのでお聞きしたいのですが、 処理系によってはギガバイトクラスのデータに対しても使えるのでしょうか?
__t─-v-─ァ__ <:::::::::::::::::::::::::::::::> <´:::z-r─--v、:::::::::> く:::::{ | }ハ::}:::::〉 ,...:::' ̄ヾ<::::i ィ=z z=く 〉:::> ,...::::´::::::::::::::::::V:::レ´ ! `!::/ /:::::::::::::::::::::::::::::::}rj ≡≡ ≡≡|< . 〈:::::::::::::::::::::::::_::z-┤ u ''' i '' |ノ ヽ:::::::::::::::::ス_r- 、`¨l、 、__ ノ マイナーですから ヽ:::::::::::::::::::ヾ:::::`ー-{ヽー--‐ イ_..:-─::.、 \:::::::::::::::::::::::::::::::::ヽ-{チ-<::::::::::::::::l \:::::::::::::::::::\:::::::::::|o::::::::::::::::::::::l::l \::::::::::::::::::ヽ::::::::|::::::::::::::::::::::::l::l . 入::::::::::::::::::::::::::|:::::::::::::::::::::::l:〈
P# 日本語通るようにならないかなぁ。
>>73 ありがとう。
私はmonoでOSはKbuntuをutf-8のところをEUCに使っている。これだと、
何がおきても仕方がないのだけれど、PrologCafeを起動した場合、
ほぼ日本語は満足がいくレベル。それが# mono PsharpIntrp.exe
で起動されるPrologCafeではまったくダメ。
ひとつは、Windowsだとどうなのだろうということ。(私の家にはWindowsがない)
もうひとつは、Psharp.dllを変更できないかということ。
>>74 WindowsXPだと日本語使えなかったよ。
ちょっと質問なんですが、 file2list(File,List) :- see(File),findall(X,(repeat,read(X),(X=end_of_file,!,fail;true)),List),seen. は、随分と胡乱臭いコードなのですが、皆さんはどんな方法でさばいていますか?
> 胡乱臭い 妙な言い回しだな
胡乱な、かw
胡散臭い
胡乱臭い・・・これは面白い表現かもしれぬ!
repeat して findall って、確かに嫌なコードかも。 私なら再帰で書きたい。 file2list(File, List) :- see(File), file2list(List), seen. file2list(List) :- read(Token), (Token = end_of_file -> List = []; List = [Token|Next], file2list(Next)). とか。
>>81 一般に業務システムのように大量ファイルを扱う場合、
再帰で書くとヒープ領域に解放できないアトムがたまり、
システムダウンの危険が発生する。それで、repeat failの
間で処理を済ませる。こうすることで、アトムを極力GCの
対象になるようにするのが定石です。しかし、この場合は
第二引数のListに貯めていくのだから、どちらのアルゴリズムを
採用してもリストから指されるアトムや複合項があるわけで、
あまり差がないと言えるのでしょうか。
リストから指されるアトムや複合項 -> スタックから指されるアトムや複合項 の方がいいですね。
>>16 5月に第3版の邦訳が出るということでしょうか?
>>84 原書第4版のことでしょ
さらに延期されて2008年11月予定になってるけど
10年以上Prologの新刊が出てない我が国じゃ翻訳は期待できないね
そうですね。アメリカの出版社っていうのはかなり前から 近刊を打つんでしょうかね。延期が多いですね。
そうなんですか。 少しいじってみたらとても面白そうなので あちこち眺めてるところでした。
amazonで新刊を見ようと出版月日順にしたら 来年出版予定のがわんさか出てくるから困る
>>87 >>16 と "The Art of Prolog Advanced Programming Technichques"
(邦訳名はPrologの技芸)の二冊はすべてのプログラム学習書の中でも
飛び抜けた存在だと思いますよ。
プロログおもしろいよな 学校で学んでよかった 学校行ってなきゃLISPの方勉強してたかもしれない せんせーあんがとー
どっちもどっちだろ
ゲーム的な感覚はプロログの方があるね。反駁と単一化というトリックに 乗せて解くパズルというか。
生産性も3-4割は高いでしょ。黒川利明さんが言ってたんだから 結構信憑性がある。
prologとocamlにはまってC忘れて就活の筆記で出された C言語の問題を誤答しまくった俺が通りますよ 内定もらったけど最終面接で 「趣味もいいけどC,C++,Javaのどれかは常に使えるようにしとけ」と説教されたw
JavaやってるとC#出来なくなる C#やってるとJavaとC出来なくなる JavaとCやってると開放しようとしたり忘れたりする Prologやってると手続きがボロボロになる
ということは、今4年?
筆記にC出すなんて珍しい会社だな ってか推薦使えよ・・・
>>95 Prologの手続的解釈。ようするに心の持ち様。
>>94 「PROLOGデータベース・システム」D・リー著 安部憲広訳 近代科学社
は読んだかい?
Pは必ず失敗する、どう定義すればいいのかな。 P :- !,fail. でよさそうに見えるが、誰かが上にこう付け加えた。 P. P :- !,fail. 二行(節)目になった P :- !,fail. はPは必ず失敗するの意味を失うのだろうか。 注..Pの部分にはtrue,fail,!,以外の任意の項がくると考えてください。
質問です。SWI-Prologで以下の質問をすると、 ?- assertz(b(1)),b(X). ERROR: Undefined procedure: b/1 これがISOの標準なのですか?
次の場合とどうちがうのでしょうか。 ?- assertz((a(X) :- assertz(b(1)),b(X))). X = _G187 yes ?- a(X). X = 1; no となります。
>>102 ヒープエリアにb()という構造体が作られていないでしょうね。サブゴールは
ヒープエリアに構造体がないと実行できないに違いない。
ここでは、コントロールスタック上にだけ、b()の構造体が現れ、しかも、
その中の2つのb()がリンクされていない! そういう解釈になりますね。
ISO標準化かどうかは英文なので私には読めません。
>>103 上の解釈が正しければ、assertzでヒープエリアにb()が作られるので、
今度は参照可になるのでしょう。ちなみにIF/Prologではどちらも参照可でした。
>>104 コントロールスタック上にある構造体相互の参照はありませんね。
>>102 dynamic b/1.
をすればokだと思う
>>107 そういうのあるのですか。ありがとうございます。
prologは宣言的な言語だと言われているのに、 挙動の説明にヒープやスタックといった個別の実装モデルが必要となるのが悲しい。
>>109 それどころか、ISO標準のPrologの言語定義が
1) BNF的なもの 2)スタックモデルによる説明
の併記になっていることを知っているかい。
まあ、
>>102 以下は実装レベルの話だから、確かに低レベル。
他の言語で言えば、クロージャあたりに近い話だと思うけれど、 このassert(retract)問題は最初からPrologの弱点と見られていた ように思う。
>111 それはこっちの話だろ。 ?- assertz(a(1)),a(T),assertz(a(2)). T = 1; no ?- a(X). X = 1; X = 2; no ?-
1980年代にはPrologでやればソフトウェアの生産性は少しはましになるん じゃないかってそこら辺中でいわれていた。坂村健のようなひとでさえ、 シンポジウムのような席でもそんなことをいっていた。若き日のビルゲイツも 基本言語への採用を考慮し、最終的に見限ってVBの開発を指示したと いわれている。 さて、それでは、どこがPrologがCOBOL等の代替言語になることを阻んだのか、 Windowsの基本言語になりえなったのか、理由をあげてほしい。 現在、Prologをやってるひとには自明なことばかりだと思うが、Prologを知らない 人にPrologを解体して見せるつもりで皆さんあげてください。
COBOLを代替できなったという点は、
>>83 にちょっと出てきているが、
アトムの爆発ということだとおもう。Prologではアトムをヒープエリア
内に一旦記述して処理する戦略をとる。極めて大きな記号間の連鎖を表現しよう
とする記号処理言語ではどこかに対象となる情報すなわちアトムを保持せざるを
えない。この場合、初出のアトムに対し必ずメモリ内を検索し、無い事を確認して
新たに構造体を追加する。業務処理で一日一億のトランザクションを処理する
ケースだとこの参照時間だけで相当のものだ。やはり破壊代入だけで済ませる
言語には太刀打ちできない。さらに再帰で処理した場合はオーバーフローの危険が
あるし、バックトラックして再束縛する場合でも、ヒープエリアのGCは必ず
必要になる。実際、保険業務などをPrologで処理することを想定すると、すぐに
電話帳一冊分くらいの量のアトムが発生してしまう。
企業業務はほとんどが記号処理、シンボル処理であり、Prologはそういう意味では
極めて適した言語なのだが、残念ながら以上のような理由から、大規模な業務処理
には向いていない。
大規模な業務処理には向いていない。 しかし、小規模な業務処理には極めて向いているし、 未開拓の対象業務だらけという状態です。この点を 知らしめる必要はあります。 自分だけ儲けるためには静かに潜行するのが上策で しょうが。
BEST SOFTWARE WRITING
ある本に興味深い文があったので紹介。
Joel Spolsky (青木 靖 翻訳)
http://www.amazon.co.jp/dp/4798115819 (P 82)
> ところで、RDFを理解する秘訣はProlog言語のチュートリアルを読むことだ。そ
> のコンセプトはすっかり同じで、理解するのはそんなに難しくなく、そうして不
> 透明で不埒なRDFの仕様がはっきり分かるようになる。
ありゃ、1行目と2行目が逆になってしまった。すみません。
この頃ソースコード載りませんね。このスレこそソースを読みたいんだけどな。
データベースと組み合わせて使ってもやっぱり大規模な業務処理は無理なんですか?
>>121 create table をPrologで行うと、事情はまったく変わりませんね。
select * from を多用しても、全フィールドをアトムに変換しようとするでしょうから、
同じです。
select 商品 from 売上 ですと得られたtupplesの分のアトムが発生します。
Prologの直接のアトムの保管場所がデータベースに移るわけではないので、
本質的な差はないと考えます。
単一レベルの記憶であって、しかも巨大キャッシュメモリが存在し、データベースと
メモリーの境界を感じさせないシステムが当たり前になった時には、データベースを
Prologで置き換えることが可能になるでしょうから、大転回が起こると思いますが。
データベースと共用しても、PL/IやCOBOLを代替できはしない。 しかし、Prologの最も幸せなプログラミングは連想三つ組の単位節を Queryで極めて少量づつとりだし、それを組み立てて複雑な問題を 解く、というものだろう。データベースを前提にして、このような部分の プログラミングが大規模システムの一角を担うことはもちろん可能で システムの中で、論理系の部分だけ担うという現在のPrologの標準的な 立場とも合致する。現在のシステムにPrologが同居することになる。 それが可能なことなのか否かは、メインフレームのシステム管理に 知識がないから私には、これ以上何も言えないけれど、可能性は 以前から実はずーとあったのではないかと思っている。
読みかえしてみたら意味不明のところがあったので補足します。 連想三つ組にはたいした意味はありません。強調したかったのは巨大な データベースをQueryとして絞り込み、その情報の組み合わせで世界を把握する というプログラミング態度です。巨像の表面の何か所かの要点を押さえて、 全体の意味を読み取ろうとする、そんな態度ですね。
適材適所ですよ 今システムを構築している言語にエッセンスだけ吸収されれればこの先も生き残れる
>>125 論理式で記述するということが要点だと思います。Prologのインタプリタや
コンパイラから参照することは必須ではない。JavaゃC++からでも一向に
構わないけれど、論理記述の形式としては、Prologほどのものはなかなか
ないのだから、このかたちで修練を積んでほしい。
私はビジネスロジックをPrologで組んで、データの更新とかはRDBMSにまかせようと思っているのですが無謀ですかね? アトムが爆発するというのはタプルをPrologのデータとして読み込んでしまうからで、それをやると破綻するのはどんな言語でも同じだと思っています。 カーソルを移動しつつ順番に処理していったり、必要に応じてSQLクエリを発行するという部分をPrologで書けないかと思っているのですが。
>>127 >>115 以降私が延々とやっているのは、汎用機で極限的な量のトランザクションを
処理している業務の代行ができるかとどうかという話です。これができないと、
大規模業務処理に向いているとはいえないからです。
一方、どのくらいまでの量のトランザクションならPrologで処理しても問題が起きないか
という視点もありえます。絶対安全な事例をあげておきます。私のところで19年間
Prolog+RDBMSで処理し続けているものです。
適用業務:石油卸+小売業の販売管理一部財務管理
一日のデータ数:平均 5300 レコード
RDBMSの最大テーブル(売上)のtupple数:max 800万
この程度だとプログラミングテクニックへの制限はまったくありません。
以前はガソリンスタンドのPOSからのデータ収集もPrologで行っていた
のですが、現在はこの部分は元売り業者が収集してくれます。
それをファイルで受け取り、sub_atomで分解しながら20のアトムに
分解してデータベースへinsertしていきます。
バッチ処理でこれに約20分かかります。あとは、Webによる参照、
インタプリタによるデータ入力、psファイルの作成、すべての帳票印刷、
これらはすべてPrologで書かれています。
:現在は売上以外のTableデータはProlog単位節として管理する
ことにしていますが、それでも一つのPrologインタプリタユニットの
平均メモリ使用量は20MBで40MBを越えることはありません。
凄く初心者質問だと思うのですが Prolog に方程式を解かせることって出来ますか? ごく簡単な式で良いんです。例えば 2 + X = 5 とかそんな感じです。
ピーク時7000レコード近くあったのが店を何店か閉めて減ってしまいました. 20分と書いてあるのはこのピーク時の平均でした。今朝測ったら11分。 ただし、これは皆様ご存知の事情によるものです。
>>129 さすがにこの方程式解くプログラムなら私にも書けそう。
変数が二個以上入る連立方程式は、変数同士の関係についての
記述であると考えられます。
この変数同士の関係のことを制約といい、制約論理型言語と
いうものがその目的には相応しいとされます。つまり、今我々が
使っているPrologはこの制約を表現するのにやや欠けた仕様だ、
ということです。いくつかのPrologは自身をもう一層高水準に拡張
して制約論理型言語であると称しています。制約論理型言語の
なかにはPrologを土台としていないものもあります。詳しくはWikiか
何かで調べてください。
>>129 2 + X を解析するには、
?- functor(2+5,Func,Args).
Func='+',
Args=2,
yes
?- arg(1,2+5,A).
A=2
yes
?- arg(2,2+5,A).
A=5
yes
つまり3引数の述語functor や 2引数の述語argを組み合わせてルールをかきます。
argで取り出した項が変数であるか、整数であるか、はたまたそれは式であるか、
を問いかけながらの解析ということになります。
ごめんなさい。2 + X のはずが2行目から以後、2 + 5 になってしまいました。 5をX に置き換えて読んでください。
>>129 方程式の解法(A + B = C) :- integer(A),integer(C),var(B),B is C-A.
ではだめかw
そりゃ反則だw
>>134 パターン全部書けばいいね。
でも、integerではなくnumberですね。
方程式の解法(A + B = C) :- number(A),number(C),var(B),B is C-A. 方程式の解法(A + B = C) :- var(A),number(B),number(C),A is C-A. 方程式の解法(A * B = C) :- number(A),number(C),var(B),B is C/A. 延々と書いていく。 一般論になるけど、Prologプログラマにはこのように パターンを数え上げれるだけ挙げて、それから、 ルールを書こうという人と、最初からルールだけで 済まさないといられない人がいるみたいだね。 外延的な表記が好きか、内包的なのが好きかって いうことかな。
理想主義的解放 en(X,_) :- var(X), !. en(0,z) :- !. en(N,s(X1)) :- number(N), N > 0, N1 is N - 1, en(N1,X1). de(_,N) :- number(N), !. de(z,0) :- !. de(s(X),N) :- de(X,N1), N is N1 + 1. add(X,z,X) :- !. add(X,s(Y),s(Z)) :- add(X,Y,Z). eq(X + Y,Z) :- en(X,X1), en(Y,Y1), en(Z,Z1), add(X1,Y1,Z1), de(X1,X), de(Y1,Y), de(Z1,Z). enとdeが別定義なのがかっこ悪い。
>>129 わざわざ「Prologで〜できますか」と書いているところを見ると、
Prologにそういう機能が内蔵されているか、という質問のように思えるね。
それはまあ、ありませんw
方程式を解くというのも、どちらかというと個別的な知識でしょう。
ただし、自分の知っている「式変形の規則」をだだっと書き出して、
それを堂々巡りしないように順序立てるだけで、案外そこそこ動くものができるかもね
>>138 何かと思えば、、
自然数の加減算ならリストを経由してappendで解くという変態技もありそうだw
方程式を素で解くなら Mathematica とか Maple とか使うことになるな。
できたw | ?- length(Two,2), length(Five,5), append(Two,X,Five), length(X,N). Two = [_,_] Five = [_,_,_,_,_] X = [_,_,_] N = 3 ->; no
頭いいなw
a_plus_b_is_c(A, B, C) :- length(ListA, A), length(ListB, B), length(ListC, C), append(ListA, ListB, ListC). ?- a_plus_b_is_c(2, X, 7). X = 5 うおおおお
>>144 ざっと見て計算量がA×C以上になっちゃいそうだなw
?- a_plus_b_is_c(20000, X, 1000000). とかやったら凍ったw
いや、A×CじゃなくてA×B、A×(C−A)か。 あと、BのリストとCのリストの一部をユニファイする手間もあるけど。
>>138 > enとdeが別定義なのがかっこ悪い。
じゃあこんな感じで上昇的に
pn(P,N) :- pn(P,0, N).
pn(z,N, N).
pn(s(P1),N0, N) :- (var(N) -> true ; N0<N), N1 is N0+1, pn(P1,N1, N).
せっかく述語が分かれているから先に決めちゃうか pn(P,N) :- nonvar(N), pn(P,0, N), !. pn(P,N) :- pn(P,0, N). pn(z,N, N). pn(s(P1),N0, N) :- N1 is N0+1, pn(P1,N1, N).
>>149 これは is 評価を使わないでpnだけで行こうとすると
ループに陥るのかな?
無限ループに陥るのはNに自然数以外を与えたときで、 無限に成功するのは変数を与えたとき、のはずだけど、 is評価を使わずにというのは?
変数を ^ P、Nの両方に
>>151 pn/2,pn/3で加減算できるなら、add1を使わずしてpnだけで
これをできないものかと。
数値データと橋渡しをするには、どのみち整数の演算が必要なのでは?という話ではなくて?
>>154 そういう意味になる。
is/2に双方向性がないので
この述語を削りpnで書き換えれば双方向性を
実現できるのかなと。
>>155 演算の双方向性は>138の方式で実現可能。
encode/decodeの双方向性は十進文字列のparserを書けば可能かも。
>>156 ああ、そうだね。私が言ってるのは
'2倍'(A,B) :-
の定義をAの2倍がBになると書いて、
それが、自ずと、Bの2分の1がAで
あるという述語定義になっている、
ということ。そのためには、最初の
定義一発にis/2を含むわけには
いかないだろう、というような意味ですね。
pn/3で加減算っていうのはひょっとして、、 % P-Q = M-N pn(P,Q, M,N) :- var(M), !, pn_aux(Q, P,N, M). pn(P,Q, M,N) :- integer(M), integer(N), M >= N, !, pn_aux(Q, P,N, M), !. pn_aux(Q, Q,M, M). pn_aux(Q, s(P1),N0, M) :- N1 is N0+1, pn_aux(Q, P1,N1, M). twice(A,B) :- pn(PA,z, A,0), pn(PB,PA, A,0), pn(PB,z, B,0), !. | ?- twice(3,X). X = 6 ->; no | ?- twice(X,4). X = 2 ->; no | ?- twice(X,5). error: stack is over. 絶対マチガッテルよこんなのw
いやこうか twice(A,B) :- pn(PA,z, A,0), pn(PA,z, B,A), !. どうでもいいw
160 :
デフォルトの名無しさん :2008/05/04(日) 18:39:02
質問です。以下の表をprologで書きたいのですがわかりません。 お願いします。教えてください。 task| 内容 | 先行task | 期間 | 人数 ----------------------------------------------------------- a | 設計 | なし | 1 | 2人 ----------------------------------------------------------- b | 材料rの調達 | a | 3 | 4人 ----------------------------------------------------------- c | 材料zの調達 | b | 1 | 2 ----------------------------------------------------------- d | 材料Wの加工 | b | 2 | 3 ----------------------------------------------------------- e | 部品Yの加工 | b | 2 | 3 ----------------------------------------------------------- f | Xの組み立て | c,d | 2 | 2 ----------------------------------------------------------- g | Sの組み立て、検査 | e,f | 3 | 1
>>160 設計指針として
1) -- と | はいらないから、削除したりカンマに置き換えます。
2)行の最後はピリオドが必要です。
3)テーブルの名前が必要です。命名します。これが述語名となります。
4)Prologの構文規則に沿うように修正します。2人 -> 2, Xの組み立て -> 'Xの組み立て'
task管理(a,設計,なし,1,2).
task管理(b,材料rの調達,a,3,4).
task管理(c,材料zの調達,b,1,2).
task管理(d,材料Wの加工,b,2,3).
task管理(e,部品Yの加工,b,2,3).
task管理(f,'Xの組み立て',c,d,2,2).
task管理(g,'Sの組み立て、検査',e,f,3,1).
見出し情報はふくみません。(task,内容,先行task,期間,人数)
これを例えば以下のように処理します。アプリケーションの中にこの情報を組み込みます。
task管理照会(_task,_内容,_先行task,_期間,_人数) :- task管理(_task,_内容,_先行task,_期間,_人数) .
別に以下のように引数位置の意味を定義しておくこともあります。 task管理引数位置(1,task). task管理引数位置(2,内容). task管理引数位置(3,先行task). task管理引数位置(4,期間). task管理引数位置(5,人数).
この定義があると、 ?- 期間 が 2 の _定義節 は. _定義節 = task管理(d,材料Wの加工,b,2,3); _定義節 = task管理(f,'Xの組み立て',c,d,2,2) などと答える可能性が生まれます。
:- op(650,xfx,が).
:- op(640,xfx,の).
:- op(850,xf,は).
_項目名 が _値 の _定義節 は :- fonctor(_定義節,task管理,5),task管理引数位置(N,_項目名),arg(N,_定義節,_値),call(_定義節).
これで
>>163 の参照が可能になります。
165 :
160 :2008/05/04(日) 20:48:15
もし人数がない場合を考える。 task| 内容 | 先行task | 期間 | ----------------------------------------------------------- a | 設計 | なし | 1 | ----------------------------------------------------------- b | 材料rの調達 | a | 3 | ----------------------------------------------------------- c | 材料zの調達 | b | 1 | ----------------------------------------------------------- d | 材料Wの加工 | b | 2 | ----------------------------------------------------------- e | 部品Yの加工 | b | 2 | ----------------------------------------------------------- f | Xの組み立て | c,d | 2 | ----------------------------------------------------------- g | Sの組み立て、検査 | e,f | 3 | 次に続く。
166 :
160 :2008/05/04(日) 20:52:13
もし人数がない場合のプログラム。
scd(StartingTimes) :-
StartingTimes = [Sa,Sb,Sc,Sd,Se,Sf,Sg],
StartingTimes :: 0..20,
Ea #= Sa+1,
Eb #= Sb+3,
Ec #= Sc+1,
Ed #= Sd+2,
Ee #= Se+2,
Ef #= Sf+2,
Sb #>= Ea,
Sc #>= Ea,
Sd #>= Eb,
Se #>= Eb,
Sf #>= Ec, Sf #>= Ed,
Sg #>= Ee, Sg #>= Ef,
labeling(StartingTimes).
となって分かるのですが人数が入った瞬間分かりません。
この人数が入った場合の
>>160 のプログラムを教えてください。
>>165 ちょっとその前に、
ごめんなさい。c,d と e,f をよみまちがえていた。
c,d e,f の意味があいまいだけれども、
'c,d' 'e,f' とするか、
[c,d] , [e,f] とするか、
はたまた、定義節を二つに分解することになる
task管理(f,'Xの組み立て',c,2,2).
task管理(f,'Xの組み立て',d,2,2).
task管理(g,'Sの組み立て、検査',e,3,1).
task管理(g,'Sの組み立て、検査',f,3,1).
この定義は意味が違うように思えるのですが。
>>128 貴重な情報ありがとうございます。
購買系のシステムに適用できないか検討中でしたので参考になりました。
Prologの処理系は何か商用のものを利用されているのでしょうか?
>>168 私は20年間IF/Prologを使用してきましたが、5年前に国内では
販売を中止しました。シーメンスでは現在も販売していると思います。
日本CGIでも販売していたと思いますが、現在どうなっているか
知りません。
私はSWI-Prologへの移行準備中です。
>>166 cumulative制約を使えば,人数制約できると思う.
使い方は人数制限が6名なら,単に
cumulative([Sa,Sb,Sc,Sd,Se,Sf,Sg],[1,3,1,2,2,2,3],[2,4,2,3,3,2,1],6)
を付け加えればOKのはず.
参考:
ttp://www.sics.se/sicstus/docs/latest3/html/sicstus.html/Combinatorial-Constraints.html#Combinatorial-Constraints
>130-159 ありがとうございました。結局Prologで方程式を解くには ある程度は書けるにしても、何かしらのロジックが必要になるのですね。 >141 なるほど。そんな言語もあるのですね。一応調べてはみます。
>>171 Prologでは = に、=の左側の項と右側の項を単一化するという意味を
与えたので、方程式 2 + X = 5. を与えて、そのまま解けるということは
絶対にありません。
2 + X と 5を較べて、2 + 5は複合項 5は単項ですから、単一化のルールに
より偽となります。
=:= や is だとどういうルールになりますか
>>173 = については、意味を与えてしまったので、方程式と理解する余地を失ったと
言った方が適切かもしれません。
=:= は 左項 と 右項を共に関数評価した上で左項と右項を単一化します。
is は 左項 は 関数評価せず、右項だけ関数評価してから左項と単一化します。
変数は関数評価できないとされますから、
X =:= 3+4.
は左項を評価できずエラーとなります。一方、
X is 3+4 はX に 7が単一化されます。
整数や浮動小数点数は関数評価するとその値となります。
関数定義されていないアトムは関数評価されるとエラーとなります。
関数定義されているアトムとは、たとえば、timeのようなもので、
?- X is time.
X = 1210072210
と1990年からの積算時間が得られます。なほ、
?- time =:= time.
yes
となりそうですが、これは微妙ですね。左項の評価時の積算時間と右項の評価時の
積算時間が異なる可能性があります。
ですから、方程式の解法を組み込み述語として、Prologが持つようにするとなると、 = =:= is などは使えず、2 + X = 5 の = 記号をオペレータとして使われていない 記号か、オペレータとして定義されていても多義性を持たせても構わない記号に 置き換える必要があります。
かといって、述語にするにしても単純ではなさそうですね。 ユニフィケーションだけじゃ無理か。
Prologでは方程式は解けないという流れになっていますが, SWI-Prologや他の多くのPrologには,clp(R)やclp(fd)等の 制約論理プログラミングのパッケージが用意されているので, それを使えば,方程式も解けますよ.
そうか「Prologに解かせる」だから、Prolog言語と解釈する必要もなかったかもね
底まで沈むことを楽しみにしていたのだが、agatteしまったね。あと68だったんだけど。
ム板には「なぜ、 = が 代入 を 表す 記号 に なったか?」という スレがありますが、Prologの場合も = が適切だったのかという疑問は 残ります。unify/2でなぜいけない? 論理変数を含む単一化は独特で、 これを = で示して、ひけらかしたい誘惑はあります。それと = は やはり便利ですね。
SQLのgroup by句付き集約参照に当たる組込述語の書式を募集します。 案をお持ちの方はどしどし出してください。
>>115 アトムテーブルの参照はハッシュが使えたとしても、
相当の負荷が掛かるのだろうか。最終的には必ずアトム文字列の
strcmpが起こるとすると、アトム長が256バイトとか大きくなると
それだけで馬鹿になりませんね。
1億回で1秒くらいかねw
codepadにはPrologないなと思ったのでshelogが使えるか試したら動いたので報告。
>974 名前:デフォルトの名無しさん 投稿日:2008/05/19(月) 23:00:17
>schelogを使ってみた。
>Prologと考えるとトリッキーな文法だけど一応動いた。
>ただ、すぐにメモリーのリークでコケル。
>
ttp://codepad.org/cgNOmn0r >
>
>975 名前:デフォルトの名無しさん 投稿日:2008/05/19(月) 23:02:04
>
>>974 >例題はBratkoから拝借。
185 :
デフォルトの名無しさん :2008/05/21(水) 12:27:17
InterlogをUNIX系OSにも移植してくれないかな?
interlogなんてHPもなくなってるジャマイカw
Prologみたく演算子を追加できる言語ってyaccのような パーザジェネレータで扱える? 扱えないとしたら、CやJavaでProlog処理系を書くとき、 パーザは自前で書くのが普通? 検索してもProlog(DCG)「で」構文解析する情報ばかりで、 Prolog「を」解析する情報が見つけられないもので…
yacc 使うんなら演算子っぽいものを優先順位なしでパースして、 後から構文木を変更していくという手法がある
>>188 Java VM などと Warren AM の違いを質問しているのかな?
Prolog compiler の実装は、WAMが公開されたのでそれが主流になっている。 WAMでググってPDFファイルを熟読汁!
Prologを効率よく実行するためには、こういうアーキテクチャのコンピュータがあればよい、という、モデルとして、「Warrenの抽象機械(Warren's Abstrusion Machine)」というものがあります。 WAMはDavid Warrenという人が考案したものです。WAMは、そもそも、WarrenがPrologのコンパイリングの研究のために考えたものです。 そして、WAMは Prolog実行の本質をついていたので、WAM以降、 Prologマシンのアーキテクチャは強くWAMの影響を受けました。 WAM はレジスタベースの汎用マシンアーキテクチャを意識して, DEC-10 Prolog(当時主流だった Prolog 処理系)より洗練された機械語命令セットを持つコンパイル技術を提案しました。 今ではこの命令セットを持つ仮想マシンを WAM(Warren Abstract Machine) と呼びます。ちなみに標準のJavaバーチャルマシーンはスタックベースです。 WAM は,バックトラックが少なく,複雑なユニフィケーションも少ないという設計思想を前提に高速化を実現しようとしました。 David WarrenはSB-Prologの作者の一人です。SB-PrologはStony BrookにあるSUNYのDavid WarrenとSuzanne Dietrichによって作られ、メンテナンスがアリゾナ大学に移って、現在に至ります。 SB-Prologの実行系は、実は、WAMのインタープリタです。つまり、CでWAMの仮想マシン・インタープリタを記述し、実行はWAMインタープリタが行います。 SB-Prologでは、そのほとんどの機能がPrologで記述してあり、Prologのコンパイルがネイティブな機械語でなく、WAMへコンパイルします。 WAMは、極力"ごみ"データが少なくなるように工夫されていますが、大規模な応用プログラムを扱うためには Garbage Collectionが必要となってくるのでWAMを拡張した抽象マシンがいくつか研究されています。 SB-Prologのソースを読むと質問の答が得られると思います。
AndroidにはJavaのサブセット内で書かれたDalvik VMが含まれているが、これはレジスタベースになっている。 Dalvikは現在インタプリタ形式だが実機発売時期に合わせてJITに変更するらしい。
WAMの命令セットは、Prologの本質をついてるかはわからんが、暗黙的な操作が 多くて大変扱いづらい。手続き型言語の悪い所の見本のような感じ。 誰かがそろそろPrologのVMを再設計してもいい頃。
Prolog のコンパイルスキーム Prologコード → WAM (Warren's Abstract Machine) コード → アセンブリコード → 実アセンブリ WAMは、レジスタの少ないCPUには向かないのでSWI-Prologは遅いです。 それに比べるとSICStus/QUINtus は、Threaded code というのを使っているのでかなり速い。 AndroidのDalvikもたとえJITにしてもレジスタの少ないCPUでは速度がでないことはほとんど自明です。
>>195 >誰かがそろそろPrologのVMを再設計してもいい頃。
すでにある。
>>193 >WAMを拡張した抽象マシン
>>196 >SICStus/QUINtus は、Threaded code というのを使っている
WAM に問題があるというよりCPUとのマッチングの問題じゃね?
threaded codeは実装のテクニックであって、VM/AMの命令セット設計の話 とは無関係ですよ。
SICStus/QUINtus はWAMを使っていないから全く異なる命令セット設計のVM/AMになっている。
WAMは滅びたんだ。よかった。
商業ベースでは滅んだ。しかし、我々が使う全てのフリーの実装ではどうしてWAMが使われているのか?
ああよかったよかった、Prologが滅びてw
>>189 トン
それだとyaccで作れる構文木って複合項とかに禿げしく限定されない?
:-とか優先度1200の演算子は任せられるか。後は単なるatom?
それだったら自前でパーザ書いても大差なさそうだな
>>190 壮絶に的外れ。
CやJavaでPrologコンパイラを書く場合に構文解析をどうするかって話。
WAMはその後の話。盛り上がってるからいいけど
>>192 MIT PRESSのWAM本は読んだ。
prologの授業頑張ってたけど もっと頑張っとけばよかった・・・
>壮絶に的外れ。 親切にレスしてくれてるのによくこんな言葉遣いできるよな
Prologerには自意識過剰で人を見下す傾向がありますからw
ぶっちゃけ>190の読解力は目を覆わんばかり
WAM厨w
>>208 たしかにPrologerは電波出してる奴多いんだよw
ぶっちゃけ
>>190 はネタだと思って笑い飛ばしていたんだが、マジだったのだろうか
たまにスレが伸びてると思ったら喧嘩ですか。
こんな過疎スレにも荒らしがきてるのか。必死に自演しても見るのは数人しかいないと思うが…
喧嘩にはなってないだろ。
>>190 がフルボッコなだけw
>>190 の読み違いはプギャーだが顔真っ赤にして反論しないのは大人
荒れる原因作ってスマソ
だが本題のレスが>189だけなのは残念
ここの住人はProlog処理系もPrologで書くような人達なんだろうな
参考になる資料見つけた(PDF)
THE DESIGN AND IMPLEMENTATION OF A PROLOG PARSER USING JAVACC
ttp://digital.library.unt.edu/permalink/meta-dc-3251:1 JavaCCはPCCTS由来のLL(k)パーザジェネレータで>189と同じやり方。
HaskellのパーザコンビネータParsecをJavaにポートしたJParsecでは
動的な文法が扱える。これらを試してみる
>ここの住人はProlog処理系もPrologで書くような人達なんだろうな それが基本だし,今のCPUなら結構使える 他の方法使っても定数倍だろ?
ただし、日本語だけは勘弁な
こんなに人居たんだこのスレ・・・
rterm.cのreduceで順序立ててるみたいだから、結局同じなんじゃないの
>>228 同じって何と?>189と同じなら>205
> それだったら自前でパーザ書いても大差なさそうだな
「演算子っぽいもの」っていうよりも、節を構成する項の列全体(「.」まで)を一旦スタックに積む感じだったよ
「項の列」はちょっとまずいか。言い方わかんねw
>>230-231 >205の
>:-とか優先度1200の演算子は任せられるか
ってことだよね。','は優先度1000で':-'より強いから
>>188 亀レスだが。一番普通に皆がやってるのは、
SWI-Prologのソースを参照する(盗む)ことだと思う。
>>234 質問する前に見たw
188で質問したのは「どうパーズするか?」じゃないんだ。
「パーザジェネレータで」できるかってこと。
動的といってもたかがしれてるんだから構文解析表を
操作すればできるんじゃないかと思ったんだけどね。
>>236 それ>188=235へのレス?
演算子順位法なんてコンパイラの本に普通に出てくるんだが。
そんなことも知らないと見下されてるわけか。バカにされたもんだな。
自前でパーズする方法を聞いてるんじゃないってことがなぜ伝わらないのか。
「○○というパーザジェネレータを使うと動的に演算子を追加できる」という情報が
あるなら教えて欲しい、それだけだ。
ネタってことがなぜ伝わらないのか
239 :
デフォルトの名無しさん :2008/06/14(土) 11:25:57
後出しジャンケンって嫌われる傾向にある
喧嘩腰w
>自前でパーズする方法を聞いてるんじゃないってことがなぜ伝わらないのか。 書き方が悪いってことがなぜ伝わらないのか。
>>241 少なくとも>235で伝わらないのは読み手の問題だろ。
自演までしてネタにマジレスカッコ悪いw 頭悪いんじゃねw
Prologの話しろよクソども
バカ専用 普通 ハッカー ウィザード ┝ - - - - ┿━━━┿━━━┥ ∩___∩ /) | ノ ヽ ( i ))) / ● ● | / / | ( _●_) |ノ / 今はここら辺クマーー!! 彡、 |∪| ,/ / ヽノ /
まったりするスレだってことがなぜ伝わらないのか
2chでスレ荒らし 普通 ハッカー ウィザード ┝ - - - - ┿━━━┿━━━┥ ∩___∩ /)
Ubuntu7.1 で Progol4_4 をmakeするとエラーに なるのですが、なにかご存知の方、 コメントをください。 # sudo sh expand.sh ・・・解凍して展開・・・ gcc -O2 -c -o command.o command.c command.c: In function 'c_interp': command.c:55: error: 代入として無効な左辺値です とメッセージがでます。
command.c:55: error: 代入として無効な左辺値だってことがなぜ伝わらないのか
>>252 それは、判るのですが、どうすればいいのでしょうか?
いや、なんか適当にポインタを取ったりすればいいのかもしれない。適当。
しったかぶってただけでしたw
そんなことも知らないと見下されてるわけか。バカにされたもんだな。 そういうことを聞いてるんじゃないってことがなぜ伝わらないのか。 情報があるなら教えて欲しい、それだけだ。
> By the way, I'm running the latest version of gcc on a Sunblade 100 workstation. だからpkgadd(ed)、かな
command.c > CTYPE(cclause)=pdot0; progol.h > typedef int BOOL, INT; > typedef long int LONG; > typedef double DOUBLE; > typedef char *STRING; > typedef char *POINTER; : > #define I_GET(i) ((i)->obj) : > #define CTYPE(c) ((LONG)I_GET(F_ELEM(2l,(c)))) : > struct item { : > POINTER obj; 世の中間違ってる
> #define CTYPE(c) ((LONG)I_GET(F_ELEM(2l,(c)))) #define CTYPE(c) (*(LONG *)&I_GET(F_ELEM(2l,(c)))) こんなんできたっけ
普通 まったり 超まったり dat落ち寸前 ┝ - - - - ┿━━━━┿━━━━━┥ ∩___∩ /)
>>262 2ちゃんに「普通」なんつー概念はありえねーw
自分以外を「2chでスレ荒らし」と言ってる奴だから、対話は成立しないだろ。ほっとけ。
Prologって何の問題を解くのに向いているのでしょう? 手続き的な処理には不向きな気がします。 私はこのスレを読んでシステムの用件定義時に個別の用件の妥当性 をチェックするなどに使えるかな?と思っています。 ミナサンはどんな問題を解くのに使われていますか? ちなみに、Javaや.Netなどから呼び出せたりするPrologってありませんか?
269 :
251 :2008/06/17(火) 02:59:52
皆さんの示唆によりまして、
めでたく、Progolの起動まで漕ぎ着けました。
ひとまず、ありがとうございます。
ひとまずというのは、
>>261 はその通り直したのですが、同様にエラーのでた
(LONG) を「なんか適当にポインタを取ったり」という感じで
コメントアウトしてしまったらうまく行った、ということです。
それでは、問題があるかもしれないから、今日
(LONG)を生かす方法を試みます。
>>265 Prologの手続的解釈というのもあります。あくまで、Prologをどう読むかということですが。
プログラマが副作用に着目している以上、深さ優先探索を「悪用」して、
あーやって、つぎにこうやって、という具合に読んでいくことは現実味があります。
関数型ではPrologから影響を受けたErlangが似た構文を持っています。
>>261 です
http://piza.2ch.net/tech/kako/968/968727266.html >1 名前: 厨房エログラマ 投稿日: 2000/09/12(火) 11:54
> unsigned long a = 0xcccccccc;
> (unsigned char)a = 0xff;
> このようなコードをみました。
> VC++で試したところ、拡張子CPPではエラーになりましたが、
> 拡張子Cでは問題なく通り、aの値は 0xccccccff になりました。
> この代入はC言語の規則上では正しいのでしょうか?
>10 名前: >8 投稿日: 2000/09/13(水) 08:15
> ANSIでは(unsigned char)aは左辺値じゃないから代入文の左辺に
> は置けない。これはANSIでは「処理系依存」ではない。
>
> この記述ができるコンパイラはANSIに従っていない。このため
> VC6も-ZaでこのMS拡張仕様を無効にする手段を用意している。
>
> gccではコンパイルできるが結果は0xccccccffでなく
> 0x000000ffになる。同様に-ansi -pedanticをつけて厳格に
> ANSIに準拠させるとエラーとなる。
>
> 言語仕様を(暗記せよとはいわないが)調べるぐらいしたら
sizeof(LONG) == sizeof(POINTER)
という仮定がされている、という仮定をしてしまった気がするとです
272 :
デフォルトの名無しさん :2008/06/27(金) 03:45:34
Prologって何か凄そうだな。 とりあえず勉強したいのだが、日本語の良い書籍はないだろうか?
>>272 PrologとAI 「Prologへの入門」 「AIプログラミング」 (2分冊)I.Bratko著 安部憲広訳 近代科学社
解説の丁寧さにやや欠けるきらいがあるが、内容はPrologならではのもので、他の言語の
入門書にこの水準のものはない。
「Prologを学ぶ 文化とその実践」 杉崎昭生著 海文堂
穴場的な本。実はこの本も相当のもの。日本語プログラミングのスタイルで書かれて
いることを嫌う向きもあるが、日本語を使った変数名の選択などを見ると、実に考え抜
かれた本であることがわかる。
もっとも高名な本としては
「Prologの技芸」 L.Sterling・E.Shapiro著 松田利夫訳 構造計画研究所発行 共立出版発売
がある。これは掛け値なしの名著。ただし、出版当時の特殊事情から、現在絶版。
入手がやや難しいと思うが、
「Prologとその応用2」 溝口文雄・武田正之・畝見達夫。溝口理一郎共著 総研出版
「Prologで学ぶ AI手法 推論システムと自然言語処理」 高野真著 啓学出版
「Prologを楽しむ」 Ph.O・松田紀之著 オーム社
など、他の言語の解説書ではちょっと見られないものが多い。
教科書的なものとしては、 「Prologプログラミング入門」 安部憲広著 共立出版 この本はどこかの大学で 教科書として使われているらしく売れているようです。 「情報学概論 Prolog プログラミング」 吉田要著 八千代出版 「Prologプログラミング」 W.F.Clocksin/C.S.Mellish著 マイクロソフトウェア 三番目のものはProlog本の古典。これも入手難だと思います。
少し、理屈っぽいところでは、
「論理による問題の解決 Prolog入門」 K.コワルスキ著 浦昭二監修 山田眞市 菊池光昭 桑野龍夫訳
培風館
「コンピュータによる推論技法」 第14章 L.ウォス/R.オーバーヒーク/E.ラスク/J.ボイル共著
川越恭二/久野茂/前田康行/光本圭子訳 マグロウヒル
特定分野からの視点では
「自然言語解析の基礎」 第4章 田中穂積著 産業図書
「帰納論理プログラミング」 第5章 古川康一 尾崎知伸 植野研 共著 共立出版
「第五世代コンピュータ入門」 第2章 渕一博監修 古川康一 新田克己 中島秀之 相田仁 共著
オーム社
それから
>>273 の最後に
「楽しいプログラミングII 記号の世界」 中島秀之・上田和紀 共著 岩波書店 を追加し、
I.Bratko著の「AIプログラミング (PrologとAI)」の訳者として田中和明氏を追加します。
> 「Prologの技芸」 L.Sterling・E.Shapiro著 松田利夫訳 構造計画研究所発行 共立出版発売 この構造計画研究所って建築関係ですよね。 うちの大学によくアルバイト募集のチラシが貼ってありました。 大学卒業して随分経って、最近Prologに興味を持ち始めたのですが、 ここでバイトしていたら勉強になったのかなぁ…と思うと残念。
>>273 〜275
thx
結構あるな、と一瞬思ったがやっぱ少ないな。
いくつか密林で購入したので楽しみ。
次はPrologを利用して何を解くかだな。。。
>>129 で
2 + X = 5
を解けるかとあるが、この手の方程式を与えると自動でPrologの式を
生成してくれるとか出来ないの?
「とか出来ない」の動作主plz
>>278 plus(X, Y, Z) :-
freeze(X, freeze(Y, Z is X+Y)),
freeze(Y, freeze(Z, X is Z-Y)),
freeze(Z, freeze(X, Y is Z-X)).
で, plus(2,Y,5) を実行すると,Y=3となります.
SICStus Prologで実行したけど,SWI-Prologでも動くはずです.
4 * (2 - 2 * X ) + 2* X = X / 2 + 6. のような場合は?
282 :
281 :2008/06/29(日) 04:47:11
まちがえた 4 * (2 - 2 * X) + 8 * X = X / 2 + 6. です。
283 :
280 :2008/06/29(日) 10:38:54
>>282 それは無理ですね.自分で数式処理するか,CLPを使うかですね.
SICStus Prologでは,以下のようになりました.
?- use_module(library(clpfd)).
?- 4 * (2 - 2 * X) + 8 * X #= X / 2 + 6.
X in 4..5 ?
Xは,4または5だそうです.
良く見ると,いじわるな問題ですね.
>>283 ?- 4 * (2 - 2 * X) + 8 * X #= X // 2 + 6.
だと、どうなりますか?
一元一次方程式は両辺を A / B * X + C に再帰的に導けばいいのでしょうか。 ただし、Xは変数 A,B,C はnumberです。
頻繁に数式処理をして、Prologで無くても良いのであれば 数式処理システム入れちゃうという手もあるけどね 無料の数式処理システムもあるんだし
287 :
283 :2008/06/29(日) 21:48:06
>>284 | ?- 4 * (2 - 2 * X) + 8 * X #= X // 2 + 6.
! Domain error in user: #= /2
! expected constraint, found 4*(2-2*_86)+8*_86#=_86//2+6
! goal: 4*(2-2*_86)+8*_86#=_86//2+6
となります.
| ?- X #= 5/2.
X = 2 ?
yes
なので #= の場合 / で整数除算ではないでしょうか.
?- 一元一次方程式((1 + 5 * X) / (5 + 3 * X) = 1). Prologで = の左右両辺を項変換してから、方程式を解こうとすると、 最終的に上のような例になる場合が少し難しいのかな。ここまで整理できたら、 ひとまず項変換は保留にして、 ?- 一元一次方程式((1 + 5 * X) = 1 * (5 + 3 * X)). として解きにいかなくてはならない。
>>278 ?- 解法の生成(2 + X = 5,U).
U = (X is 5 - 2)
yes
?-
?- 開放の生成(4 * (2 - 2 * X ) + 8 * X = X / 2 + 6,U).
U = ( A is 4 * 2,B is 4 * -2,C is 1/2,D is B+8-C,,X is (6-A) / D)
yes
?-
というような意味かな。
290 :
289 :2008/06/30(月) 17:13:35
U = ( A is 4 * 2,B is 4 * -2,C is 1/2,D is B+8-C,,X is (6-A) / D) は U = ( A is 4 * 2,B is 4 * -2,C is 1/2,D is B+8-C,X is (6-A) / D) です。
291 :
289 :2008/06/30(月) 17:14:28
ごめん。開放-> 解法 ね。
某処理系のバグをいくつか適当に潰してみた 地下1階 いくつかの組込み述語で''や[]を考慮していない件 地下2階 findall/3で生成される変数が同一視される(番号の系列が繰り返される)件 地下3階 _が実際に単一化されない件 結果的に、何かの練習問題みたいだった | ?-findall(X,(true;true;X=A;X=B-C),L). X = _11 A = _13 B = _15 C = _17 L = [_32,_32,_32,_32-_34] ->; no
このスレで質問することでもないのだけれど・・。Mercuryのコンパイルで $ sudo mmake hello_world.depend mmc --generate-dependencies --grade reg.gc hello_world $ sudo mmake hello_world ml --grade reg.gc -- -o hello_world hello_world_init.o \ hello_world.o \ hello_world.o: In function `<predicate 'main'/2 mode 0>': hello_world.c:(.text+0xf): undefined reference to `<predicate 'io.write_string'/3 mode 0>' collect2: ld はステータス 1 で終了しました make: *** [hello_world] エラー 1 Ubuntu7.10です。要するに io モジュールをimportできないらしい。 何か環境変数の設定が必要なんだろうか。ソースは :- module hello_world. :- interface. :- import_module io. :- pred main(io__state, io__state). :- mode main(di, uo) is det. :- implementation. main --> io__write_string("Hello, World!\n").
無駄に手強かった(が今更誰もはまりそうにない)
>>293 の続きの記念カキコ
地下4階 高階述語に渡された目標(G,H)を呼ぶとHの環境が取り違えられる件
do_call(G) :- call(G).
| ?- X=aaa, do_call(( write(X), nl )).
aaa
X = aaa ->;
no
| ?- X=aaa, do_call(( true, write(X), nl )).
true,write(aaa),nl
X = aaa ->;
no
| ?- X=aaa, do_call(( true, true, write(X), nl )).
true,true,write(aaa),nl
X = aaa ->;
no
データベースって動的に追加できるのでしょうか? 例えば、 test( X ) :- test2( X ). test2(a). test2( b). に、test2(c)を追加するような動的な処理って出来るのでしょうか?
っ assert retract dynamic
んじゃ、データベースを外部出力するとか出来ますか? この二つが出来れば、あるていど実用が見えてくるのですが。
>>297 >>298 を補足すると、 基本的には ...assertz(test2(c)), ... をどこにでも使えます。
ただし、
>>102-
>>112 に出てくることを押さえておく必要はあるでしょう。
>>299 listing という述語があります。
>>297 を例とすると、
?- listing(test2/1).
test2(a).
test2(b).
?- assertz(test2(c)),listing(test2/1).
test2(a).
test2(b).
test2(c).
yes
?-
>>299 MobilePCを持った電気計測員が電気メーター読み取って入力するケース。
% *** user: '電気メーター' / 2 ***
電気メーター(User,X) :-
継続的質問(電気メーター/3,(date(Date),assertz(電気メーター(User,Date,X)))).
% *** user: '継続的質問' / 2 ***
継続的質問(Functor/Arity,Query) :-
concat_atom([Functor,#,Arity,'.pl'],File),
(
exists(File,read),
r_consult(File)
;
\+(exists(File,read))
),
call(Query),
fail .
継続的質問(Functor/Arity,_) :-
concat_atom([Functor,#,Arity,'.pl'],File),
tell(File),
listing(Functor/Arity),
told,
! .
exist/2,concat_atom/2,date/1 などは未定義ですがどんな述語かはお解りでしょう。
ユーザコードが'12264'で電気メーターが64362.1を指しているなら、
?- 電気メーター('12264',64362.1).
yes
のように使います。カレントディレクトリの 電気メーター#3.pl というファイルに
更新(追加)された電気メーター/3が保護されます。計測と入力のタイムラグは生じますね。
MobilePCで漢字入力が困難な場合は、
d(A,B) :- 電気メーター(A,B).
というような述語 d/2 を
>>301 に追加します。
?- d('12264',64362.1).
yes
になります。継続的質問/2を呼んでいるのはあくまで電気メーター/2ですから、
これで d#3.pl に保護されてしまうという心配はありません。それから
>>301 でexist/2となっている
ところがありますが、これはexists/2の間違いですね。この述語はreadモードで
ファイル 電気メーター#3.pl がオープン可能かどうかの問い合わせに使われています。
>>301 ( できる, する ; \+ できる )
の形を
( できる -> する ; true )
としなかった理由をよろしければ
>>303 昔はこの形式しかなくて、後の方はほとんど使ったことがないから。
実は本当に上記が理由なのだが、もうひとつ、二節しかない節定義の時は、
第一節を第二節では必ず、否定する習慣がついている。バグをさけるために。
それでどうしても節の定義でなくても
>>301 のような表現になってしまう。
この場合は、OSとインターフェイスをとる組込述語を使うわけだから、
二回連続して検査する可能性のある私の表現はあまり好ましくない。
なるほど。 ただファイルは論理外の対象なので、前後で結果が一致しなかった場合は、、などとつい考えてしまいます。 ->のない;は後戻り前提、という先入観があったりして。
>>305 ファイルについてはその通りですね。協業ってこともある
だろうし、どこかでchmodをしているかも知れませんね。
一般に、Prologのプログラマの方はどうなのでしょうか。
私が
>>301 で書いた ( _ ; _ ) のようなインライン化した
表現は私自身は「好ましくない」と感じてしまいます。
必ず別に述語を立てるべきと。
そこらあたりの感覚っていうのは・・・。
おっとURLがちょっと違った
私怨か?
どんな私怨だそれ
>>301 で思い出した。
皆さんのバージョン管理述語の定義が見たい。
ぜんぜん違うはなしになるが、 ソフトウェアサイエンスの世界でも注目の大学ということになると、 岩手県立大学、公立はこだて未来大学ということになるらしいのだが、 実際のところどうなのだろう。
>>314 学長で注目されるだけでなく、と言う意味。
316 :
デフォルトの名無しさん :2008/07/11(金) 02:22:38
かつて日本の国家プロジェクトでやってた 「第五世代コンピュータ」って計算機科学に 貢献しましたか? 今も KL1 っていう言語が残ってるみたいですが、 今は、どんな位置付けになっているのでしょうか? (後々に繋がった良い成果?それとも、糞の役にも立たない税金の無駄遣いだから担当者は首吊れ?) また、それと北海道大学の方の ET とは、何か繋がりはありますか? (KL1 を引き継いで始まった?それとも、全く別個に始まった?)
317 :
316 :2008/07/11(金) 02:26:36
申し訳ありません。 うっかり上げてしまいました。
>>316 ここはPrologのスレですから。
中島秀之氏は、1978年に情報処理、1982年bitにそれぞれ
Prologの紹介記事を書かれました。ICOTの準備が進んでいたにも
関わらず、一般向けにPrologが紹介されたのはこの二記事が最初です。
ICOTについては、PSI II がないと検証できない研究が多いですね。
そのことが一番問題だと思います。それで、ちょっとひねった見方を
するなら、ICOTが森政権の頃だったら、5000億円とか予算が付いたこと
でしょう。これだと、PSIを何世代も作り替え、PC版も作りという展開に
なって、研究者と一般コンピュータ利用者との乖離がずっと小さくなった
かもしれませんね。
>>316 「計算機科学に貢献」というのは目的ではなかったと思うんだけどw
税金云々と言うならば、国の手に入った特許などがその後どうなったかとか、そっちじゃないの
ここはPrologのスレですから。ICOTが「計算機科学に貢献」できなかったとは言えません。 なぜかというと、ICOTの成果を引き継ぐのは私たちだからです。計算機科学に貢献して いないように見えるとしたら、ロジックプログラミングの世界を発展できず、むしろ縮小さ せてしまっている私たちの力不足だということになります。
「力不足が原因だ」 でした
322 :
316 :2008/07/12(土) 00:03:52
スレ違いの質問をしてしまったようで申し訳ございませんでした。
>>318 色々お教え頂き、ありがとうございました。
>>319 そもそも、学術的な成果を目指した計画ではなかったのですか。
もしそうでしたら、私の見方が間違っておりましたね。
>>320 論理プログラミング自体は発展して、 ET という物があるようなのですが、
その出発点が気になるといいますか、 KL1 とは関係がないのかなと少し思いましたので。
趣味で論理プログラミング言語の事を調べ始めた所で、少し気になった事があり、
Prolog と近いようなので、このスレでいいのかなと思ってしまっておりました。
スレ違いの質問にレスを頂き、ありがとうございました。
第五世代は基礎研究じゃなくて真剣に応用を目指したプロジェクト。 だからメーカーが多数参加したし、国産メインフレームのように 事業化する見込みで始まってる。見込み違いも甚だしかったわけだが。 等価変換はPrologともKL1とも直接の関係はないだろうが、 高水準だが非効率的な言語で記述されたプログラムを、等価で 効率のいい記述に変換することに意義があるのであり、 それにはPrologが格好の材料だったとは言えるだろう。
ICOTの真のテーマは並列論理型言語の実用性の検証。
将来、並列論理型言語の時代がくると直感した人たちが、
知識プログラミングという大風呂敷を広げて、それを実証しようと
した。だから、プログラミング言語的観点から言うと現在主流の
手続き型、関数型とは無縁に近い研究なのであって、この立場
から見ると、「何の貢献もない」と感じられて当然といえる。
>>322 ここで作られ使われた並列論理型言語がKL1。
サラブレットの大種牡馬が傍流の血脈から突然現れる
ように(サンデーサイレンス?)、並列論理型言語も突然
復活するように、現れこの世界を席捲するのだろう。
そう考えると現在KL1(KLIC)がほとんど使われていなく
ても、さほど気にするような問題ではないのかも知れない。
>並列論理型言語 Prologは並列論理型言語なのか? 出来るのならアーランより面白そうだが・・・
それはないw
>>325 > ここで作られ使われた並列論理型言語がKL1。
考えてみればprologほど並列処理が似合う言語はないよな。 しかも自動並列が可能。
KL1なら特に並列実行するのは簡単だが、効率を考えると いかに並列実行しないかが重要でそこが難しい。 効果的なところだけ人間が並列を指示するErlangの方が現実的。
KL1のソースは汚すぎ。 windowsに移植しようとして挫折した。
>>329 マルチコアが十分に進んだ世界(後、2,3年はかかるかな)なら
実用に向くようになるんじゃなかろうか。
Z = X + Y でZが0~9までの値をとるときに、 X,Yの組み合わせを求める項ってどういう風に駆けますか?
>>330 KL1じゃなくてKLICのソースだろ。
335 :
316 :2008/07/12(土) 23:31:53
>>323 >>324 レスありがとうございます。
「応用を目指したプロジェクト」「実用性の検証」だったのですね。
そこの所を勘違いしておりました。
>>323 等価変換プログラミングの事も少し勘違いしていたようです。
お教え頂き、ありがとうごさいました。
>>324 そうですね。
>>331 も書かれてますが、今、マルチコア CPU が
普及してきておりますし、それに、普通に使われる言語についても、
全体的に抽象度が上がって来て、宣言的な部分が増えて来ているようですし、
2, 3年後かは分かりません(もう少しかかるかもしれません)が、
今後、並列論理プログラミング言語に焦点が当たって来るかも知れませんね。
今日、 Cygwin 上に KL1 を入れてみたので、少し勉強したいと思います。
(普通の Prolog も入ってますのでそれでも良いかも知れませんが)
>>329 Erlangサーバを作ってPrologから呼ぶと快適だから、
Prolog-KLIC-Erlangが相互に呼び合う
トライアングル・サーバ/クライアントシステムを構築するのが
良さそうだね。
あと、GUIの処理をどうするか。
>>336 ErlangからPrologを呼ぶケースを考えると、Erlangは関数型だから、
socketでTCP/IP通信をする際、ストリームにappend([1,2],[3])を書きたい場合、
format("~w.",append([1,2],[3])) を実行すると期待する
append(([1,2],[3]). ではなく、 [1,2,3]. が書かれてしまう。この問題は入出力
双方に共通して起こるから、インターフェイス部分はPrologでいうと functor/3 や
=../2で項を再帰的に分解したようなTokensと呼ばれる構造体からスカラ型の
アトムを「拾う」ことになる。使い勝手はPrologに較べると著しく落ちる。
そんな問題はあるね。
間違えた。 format("~w",append([1,2],[3])) ではなく format("~w",[append([1,2],[3])]) でした。
>>328 ESPが使われたとき、ICOT内部の評価は知らないけれど、部外者からは
生成されるインスタンスが並列なら素晴らしいのだがという声が多かった。
逆にそういう旨味でもないと、ローカルメソッド(ほとんどProlog)まで引数で
オブジェクトを引き回すことになってロジックプログラミングの良さが減殺
されてしまっているという否定的評価を含むものだった。
340 :
デフォルトの名無しさん :2008/07/13(日) 13:42:28
>>341 実用的な意味はない。ということは、KLICのコードだ
さっぱり開発されないという事態が予想される。
ただ、KLICの仕様は必ず将来主流になるから、常に
最も使いやすい形でアクセス可能な状態にしておこう
というだけ。
実用的な意味はない。ということは、KLICのコードだ け 行末の"け"が消えてしまった。
Windowsユーザかつ非Cygwinユーザかつシングルコアユーザの俺に 教えて欲しいんだけど、KLICで main :- fib(30). fib(N, F) :- N =< 1 | F = N. fib(N, F) :- N > 1 | N1 is N - 1, N2 is N - 2, fib(N1, F1), fib(N2, F2), F is F1 + F2. をマルチコアのマシンで動かした場合、-p引数の数を増やすとスケールする?
>>344 Ubuntu7.01 + Am2+Phenom でバッケージ版のKLIC だと
-P 2 とか -P 3 を入れても生成される実行ファイルと
そしてもちろん実行速度も変化なし。
346 :
345 :2008/07/14(月) 13:56:41
Ubutu は 7.10 のまちがい。 コンパイル後の実行ファイルはサイズだけでなくまったく同じものが 生成されていました。
348 :
345 :2008/07/14(月) 15:29:31
>>347 そうですね。やってみます。
以前にRedhat 9.0 で並列版を動かしたことがあるのですが、
Fedora5でと思ったら、うまくmakeできませんでした。
Debianだとパッケージで動くとこのスレできいたので、
現在はUbuntuのパッケージで使っています。
>>340 日本語情報があまりに乏しくて、どうにも進みません。
ム板に別スレを立てるのでも、フログでもどんな形でも
いいですから、どなたか、厚みのあるチュートリアルを
開いてください。
さっきからミスパンチばかりしてますね。ブログですねw
Oz Mercury Scala が現在の私には情報不足三兄弟ですね。
>>345 ちなみに実行時間はどれくらいでした?
一瞬だった場合はfib(35)でどれくらいとか。
>>352 fib(40,_) で12秒弱ですね。
>>353 ありがとうございます。
意外に速い。SWI-Prologじゃfib(40)なんて終わる気がしないw
>>354 IF/Prolog V5.2Aのインタプリタですと、fib(40,_) は189秒でした。
>355 インタプリタだしカットも入れてないので遅いのはしょうがないですね。 よく考えたら>344のコードだと全くサスペンドしないな。 普通の手続き型言語と同じ動きになってしまう。 ちょっと意地悪かもだけど、fib/2の2番目の節を fib(N, F) :- N > 1 | F is F1 + F2, fib(N1, F1), fib(N2, F2), N1 is N - 1, N2 is N - 2. に変更するとどうなります?
>>357 fib(40,_) が139秒になってしまいました。-P 2 オプションでコンパイルしても
まったく同じです。
並列的枠組みが「働く」ことによって10倍遅くなった?
この負債を返済するには16コアのCPUを待てばよい!!? 現在のKLICを使っての話だけど。
>>355 SWI-Prolog Version 5.6.14 インタプリタ 334秒。
さて、Prologは今後どんな使われ方に落ち着くのだろうか。 命令型言語が廃れ、宣言型の時代になった時には盟主たり うるか。それともやはり、知識プログラミングのアセンブラか。
あ、あ、 なった暁には ですw
逐次型のコプロセッサ的役割 きっと知識記述か知識推論あたりで使われる
失敗駆動型アーキテキチュワがクルぜ!
非決定的オートマトンが実用化されない限り無理
368 :
デフォルトの名無しさん :2008/07/18(金) 23:43:39
Prologオワタ\(^o^)/
369 :
デフォルトの名無しさん :2008/07/19(土) 02:53:03
過疎ってる
未だにカットをどう使うのか良く解らない
つい最近 Prolog には、エジンバラ版とマルセイユ版があるというのを知りましたが、 今、一般的なのは、エジンバラ版という認識で良いでしょうか?(SWI-Prolog 等) マルセイユ版の Prolog とはどんなものでしょうか? エジンバラ版とどのように異なるのでしょうか?(構文が違う?)
あわわわわっ すみません。上の「Virual Prolog」は「Visual Prolog」の間違いです。
>>374 ありがとうございます!
Prolog 誕生の経緯が纏められた文書ですね。
読み進めると、一行だけではなく、「Part IV. The final Prolog」の
章では、飛行機の乗り継ぎ方(?)をはじき出すプログラムが載っていますね。
どうやら、Turbo Prolog とは、全く関係がないようですね。
面白い書き方だとおもいました。
計算式は含められなくて、計算は全て関数(述語)呼び出しで行うのが LISP に似ていますね。
変数の書き方は ET 言語と同じですね。
うわっ、いま、気がつきました!
>>372 に「かつて Borland から出てた Turbo Pascal が」と
書いてしまいましたが、正しくは、
「かつて Borland から出てた Turbo Prolog が」でした。
すみません。
TruboProlog VisualProlog は 宣言の部分はマルセイユ版を受け継いでいますが、 clauses はエジンバラ版の仕様だと思う。
Visual Prologの日本語の情報がなくて困るのですが、 Turbo Prolog を振り返るには、 「TURBO Prolog プログラミング」 玉井浩著 1989年 サイエンス社 が手軽です。 「TURBO PROLOG入門」 Carl Townsend著 倉谷直臣/酒井高広訳 1988年 オーム社 にはその後Visual Prologに引き継がれる IDE の原型のような 部分の解説が少しだけ含まれています。
>>374 それはマルセイユ流だったのか
C&Mの付録に「ある初期のシステム」での例として載っていて異彩を放っていたよ
ふっ。さすが、マルセイユ。 田舎のエディンバラとは、洗練され方が違う。 見苦しい「:-」(顔のAAか!)を使わず、数式すらも受け入れず、 ただ符号付きの項のみからなるシンプルさ。 実に美しい! 更に変数には必ず記号をつける事により、識別子の先頭を大文字に しなければならないと言う無粋な規則も廃している。 さすが自由の国フランスだ!
「:-」 ←これかわいいのに…(´・ω・`)
♪メ〜ダ〜カ〜の学校は〜
<- か <= にしなかったのは何故だろうね
>>384 それ、最初から疑問だった。 <- が自然だよ。
マルセイユ流の + - はエレガントだね。 関数表記を混在させてしまうと、何が何だか分からなくなるだろうけれど。
=:-] がよかった。モヒカン!!!!
肯定リテラルはモヒカンだったろう論
389 :
デフォルトの名無しさん :2008/07/22(火) 10:16:17
% % database/0 % :- op(500, xfx, ha). :- op(600, xf, desu). :- op(600, xf, dehanai). :- op(700, xf, ka). :- dynamic(data/2). database :- write('konnichiwa'), nl, process_loop. process_loop :- write('|: '), read(Input), process(Input). process(sayounara) :- !. process(Input) :- command(Input), process_loop. command( X ha Y desu) :- update_data(X,Y), write('wakarimasita.'), nl.
update_data(X,Y) :- functor(P,Y,1), arg(1,P,X), assertz(P). かな。
どこにモヒカンがいるの?
すみません、随分昔にClocksin%Mellishの本や技芸本で遊んでたんですが、 再びPrologな気分になってきました。 当時はSWI-Prologとかcu-Prologとかを使ってたんですが、 最近はどんな処理系が良いんでしょうか。 できれば日本語文字列が扱えるものだといいんですが。 日本語処理にも使ってみたいので。
あ、mercuryやKL1も少し遊んだ事があります。 関数型と合体?したようなWild LIFEとか面白そうなものもあった記憶がありますが できればなるべく今現在普及しててドキュメントが揃ってるものが知りたいんです。
SWI-Prologが多数派なんじゃない?
折角なのでもうちょっと希望を書いてみます。 できればデータベースは永続化できるといいな。 RDBMSと連携して。(Datalogか・・・) ネイティブコンパイラもあるといいな。
あ、レスありがとうございます。 SWI-Prologがメジャーなんですか。 ところで、DL(Description Logic)と合体したようなの、 確かLIFEはそんな感じだったと思うんですが、 そういう言語は今使われてるんでしょうか? cu-Prologの制約付きユニフィケーションなんて面白いと思ってたんですが、 それも一般的にはなってないですよね? HPSGなんかの文法理論とかなりマッチしてたような記憶があるんですが。
>>393 SWI-Prologは速くはありませんが、最も使われているようです。
?- sub_atom(この,_変位,_長さ,_残り長さ,_副文字列).
_変位 = 0
_長さ = 0
_残り長さ = 2
_副文字列 = '' ;
_変位 = 0
_長さ = 1
_残り長さ = 1
_副文字列 = 'こ' ;
_変位 = 0
_長さ = 2
_残り長さ = 0
_副文字列 = 'この' ;
_変位 = 1
_長さ = 0
_残り長さ = 1
_副文字列 = '' ;
_変位 = 1
_長さ = 1
_残り長さ = 0
_副文字列 = 'の' ;
_変位 = 2
_長さ = 0
_残り長さ = 0
_副文字列 = '' ;
No (空行を削除しました)
SWI-Prolog Version5.6.14 Ubuntuでのパッケージ版ですが、快適です。
もちろん述語にも漢字が使えます。
399 :
デフォルトの名無しさん :2008/07/27(日) 09:36:48
Prolog は、論理型プログラミング言語などと嘯いているが、 所詮はバックトラック機能が付いた手続き型言語でしかないんじゃなかろうか。
内部実装云々の話をしだしたらprologじゃない件
推論の流れに乗って何かしようと思う心が手続き型。 Prologプログラムの大部分を論理プログラミングで固めることができる、という感じかな。
たしかに手続き型言語の部分は緑切断と赤切断の使い分けなどにも現れてる。 でもそういうよく知られている解決策を使えば論理型の範疇でいろいろやれるし、論理型には他の選択肢がほとんど無いのが実情かな。 実際、Prologでやりにくいときは他の言語を使うから問題ない。
論理型と手続き型の問題対象領域が違うからなぁ 考えてるのにマッチする方法を使うのが妥当 そういう意味では,型とデータ構造のパターンマッチングと手続きを同時にかける関数型は強い気がする
ほんとは、実現方法なんか関知しないで、 純粋に論理を書いたらそれが動くというのが理想なんだろうけど、 現実の Prolog は、文は上から下に、ゴールは左から右に、逐次的に調べるという風に 実現方法が(現実に合わせるために)規格で決まっているんですよね? ゴールを左から右に順番に試すという決まりがないとカットの仕様が決められないでしょうし。 その辺とかカットとかで論理型だと胸を張るには汚い感じがするから、 それを何とかしたくて制約(論理)プログラミングが出てきたんですよね? ところで、制約論理プログラミング言語は、このスレの範囲外ですか?
Marseille Prolog IIIが制約論理の元祖みたいなもんじゃなかったっけ?
>>405 制約論理型言語の話題、大歓迎じゃないかな。
>>405 制約論理プログラミングの誕生の経緯について私は知らない。
単純に変数と変数の関係を記述できるようにしたかったからだと
思っていた。
データベースをオンメモリで処理するのはなんとかならんかな、と思う。 外部DBと連携するとかできんのか? 巨大なデータベースを処理することができんではないか
>>409 外部データベースとインターフェイスをとり、Prologインタプリタを
Prologで書いて、定義節が存在しない時はテーブル名を述語名と
みなして、外部データベースから全解を取り出した上で、
member/2で1tuple(節)づつ取り出す。
こういったことは、長くPrologをやってる人は一度は試みていると
思う。実務で永続して使っている例は少ないだろうけれど。
412 :
411 :2008/08/01(金) 06:08:37
定義節が存在しない時は -> 定義された節がもはや存在しない時は かな。
遅延評価など積み残した課題はたしかにあると思うが、 Prologの今後は、実用に耐える第一級のオンメモリデータベースである ことを目標として欲しい。RDBである必要もないし、SQLをサポートする 必要はまったくない。数百万節以上の検索がオンメモリで、専門の DBMSと同レベルの実行速度が得られれば、Prologの時代は必ず来る。
>>403 自然言語で命令するにしても、長い表現になるわけで、
プログラムというものは決してゼロにはならない。
ポイントはどれだけ「その部分」が早く出てくるかという
ことと、かつ、短く表現できるか、だと思う。
これによってプログラム言語の値打ちは決まる。
415 :
デフォルトの名無しさん :2008/08/04(月) 14:07:08
prologで何か作らなきゃいけないんだけど 面白いネタありませんか レベル的には大学4年生レベルの課題で
>>415 自分だけに分かるルールをこね回すようなものは評価されない。
やはり、世のため人のためになるものが良いと思う。
私が一例をあげると
謡曲 「井筒」 をPrologの節で表現する。考え所は無限にある。
人工無脳 or Eliza
>>416 GUIを前提にしたハイパーテキストはすっかり知の市民権を
得たが、どこまでリンクをたどってもやはり文章が出てきてしまう。
Prologには***は真であると言い切る勁さがある。Prologの述語表現が
「第三のテキスト」に成ることを期待したい。
>>419 「期待したい」じゃなくて、そうなるように考えて、自分から動いたら?
そのためのツールを作るとか、 ML とか Wiki とかを拠点として用意してコミュニティーを作るとか。
それに、素の Prolog のままだと使いにくそうというか、とっつきにくそうだし、フォーマットを考えた方が良くない?
国際化とかマルチメディア対応とかも含めてさ。
XProlog とかどうだろう。 XML で Prolog を書くの。 hogehoge(X, Y) :- X=Y. を <def> <head id="hogehoge"><var id="X"/><var id="Y"/></head> <goal><eq><var id="X"/><var id="Y"/></eq></goal> <def/> みたいにするとか。
プロローギュ歴10年の俺には奇妙に感じるが、何か利点がある?
フォーマットは、もっと練り直した方がいいと思いますが、 Prolog の XML 化の利点としては、 (1)XML は、エンタープライズ分野で結構使われていて、環境が整っているので、その流れに乗れば使われやすい(のでは?) (2)XML を扱うライブラリがそろっているので、他の言語から自動生成するときに色々な工夫がしやすい(かも) (3)永続化、データベース化は、XML データベースにそのまま入れればいいだけ!(だといいなぁ) (4)XML が直に使える。XML 上で定義された色々なデータ形式が扱いやすい(んじゃないかな〜) (5)XML は、勿論、国際化されたデータ形式です(よね) (6)XML で定義されたマルチメディア関係のデータも扱えるのでマルチメディア対応もバッチリ(である事を祈る) が考えられるかなと。 問題は、質問の時ですね。 質問 を URL として記述する方法も考えると 夢(妄想とも言う)がいろいろ広がっていいんじゃないかと、 Prolog 歴数秒の私が考えました。
424 :
デフォルトの名無しさん :2008/08/09(土) 21:21:25
他にも (7)CSS とか XSLT でとかで色んな形に成形したり表示したりできる (8)データとプログラムが同じなので、統一的に扱える (9)データに構造を持たせ、意味づけができる というのもありますかね。 デメリットとしては、 (d1) XML は冗長 (d2) XML の文法に縛られる (d3) Prolog っぽくない (d4) そもそも Prolog の必要があるのか (d5) XML も Prolog も Lightweight Language (P系とも言う) の世界から無視されている(もしくは忌み嫌われている) (d6) XML で Prolog を書かこうなんて考える奴は、人として生きている資格がない と言うのがあるかと思います。
>>424 > (d6) XML で Prolog を書かこうなんて考える奴は、人として生きている資格がない
謝れ!RuleMLの人に謝れ!
427 :
424 :2008/08/09(土) 22:33:19
ごめんなさい。 RuleML なんて言う物があったんですね。 いま、 Wikipedia で確認しました。 それがあれば、私の考えた物なんか要りませんかね。 (d6) は私自身だけの事を言ったつもりでした。 私の無知と愚かさに自ら墓を掘って入りたくなりました。 誠に申し訳ございませんでした。 それでは、逝きたいと思います。
一人じゃ逝かせねぇぜ。そうです、私は422です。
Prologのプログラマにとっては 括弧、カンマ、ピリオド などの基本構文要素も 鬱陶しいだね。これなくて何とかならんものか、と思ってる。 上の方に出てきたマルセイユ風の話もそんな感覚での話題。 言語間のインターフェイスとしてXML や XSLTを考えることは 当然有力なんだけれど、それを書かされるの絶対御免。
>>430 いいかげんスレ違いだし、何か少しでも成果を上げてから来たら
すまん言い過ぎたw 夏だな
暑いぐらいで沸騰する奴は年中沸騰している
Webで知識表現といえばRDF. 主語,述語,目的語の三つ組みだから,Prologと同じ人工知能の系譜. 「セマンティックWeb」でググればたくさん出てくる.
>>435 RDFは10年以上前からINAPでセッションが設けられているくらい
代表的なPrologの応用分野なんだけれど、
"PROLOG Programming for Artificail Intelligence"にも章立てがない。
まとまった日本語のWeb文書も私は知らない。ここらあたりの知識を
まとめたProlog本だれか書いてくれませんか。
ついでに言うとPDF時代なのだから、Prolog本もUniversityである必要はなく、
College本が次々と出てくることを期待。
?- intersect([1,2,3,4],[A,B],[2,3]). A=2, B=3; A=3, B=2; no ?- となるような intersect/3 を定義してください。
集合なのか順列なのか?
第二引数の要素が第三引数と同じ時は解がでるが、 多いときには、不定となるな。 こう言う要求仕様にはどう答えればよいのだろうか。
関係代数の割り算というのがデータベースにあったが、 集合の割り算っていうのはあるのかな。
>>440 {}/{}はある
割り算って言わないけど
>>441 集合なら[2, 3]と[3, 2]が別解なのはおかしくない?
>>443 それもこの質問の大事なポイント。この話、元々、モード宣言でいうと
intersect(+,+,-) であるのを
intersect(@,@,@) にできないものか、という疑問からでている。
ということは集合であっても、
?- intersect([1,2,34],[2,3],X). と ?- intersect([1,2,3,4],[3,2],X). は別に
存在できたわけだ。それで、
>>437 は別解扱いにしてみた。
>>444 この定義だと双方向に行くかなと思って試してみると、noとなることがある。
あれーカットもないし変だなぁー、ということなのだが、この問題のように、
そもそも(数学的に)解が定まらないという場合が多い。変数が次々と生成
されそうなものだがとか考えてみても、最終的に何が起こるのか、起こって
いるのか予想できない。
?- intersect([1,2,3],X,[2,3]). のような場合ね。
>>445 not(P) っていうのはカットなしには定義できないはずだけど、
この副目標が入っている定義は双方向性と言う観点からは
どうなんだい。
>>445 そういわれてみると、ゼロ除算のように見えてくるね。
>>437 論理的に破綻している点についてはどうなの
Prologを初めて使っているのですが、意図する動作を作れなくて困っています。 ある数式がリストに含まれているか否かを調べたいのですが、組み込みのmemberだと単一化が起こってしまします。 リストの中身が変わると困るので、単一化されないほうが望ましいのですが、実装方法がわかりません。 A=[B/c],member(b/c,A). 組み込みmemberだと、 A = [b/c], B = b . となります。望む動作としては A = [B/c]. つまり、「成功しても失敗してもリストの中身は変わらず、リストに含まれていれば成功する」、 このように動作するmemberの作り方をご存じの方がいらっしゃいましたら教えてください。 swi-prolog 5.6.59
member2(X,[H|_]) :- unifyable(X,H,_),!. member2(X,[_|T]) :- member2(X,T). とか。
>>449 とりあえず(==)/2というのはご存知かな
一般には
\+ \+ X = Y
みたいなキモい方法が
あ、なんか勘違いした気が ごめん
S∪T([]、[_]、[_,_]、…)の中から適当にS、Tを取る、という方法なら、 パターンが一応網羅されることを予測できる気が。どのみち止める工夫はいるだろうけど。
>451-453 >450じゃだめなん?
unifyable/3は未定義
unifiable/3はISOでは未定義
(==)/2は的外れだった
>>453 は
>>437 向け
かな
>>449 m(P,[Q|_]) :-
u(P,Q),!.
m(P,[_|R]) :-
m(P,R).
u(P,Q) :-
var(Q),!.
u(P,Q) :-
not(var(Q)),
functor(P,F,A),
functor(Q,F,A),
u(A,P,Q).
u(0,_,_) :- !.
u(N,P,Q) :-
arg(N,P,A1),
arg(N,Q,A2),
u(A1,A2),
M is N-1,
u(M,P,Q).
% u(P,Q) :- var(Q),!. がポイントじゃないかな。
457 :
456 :2008/08/31(日) 04:16:02
全然確かめていない。間違ってたらごめん。
でも、こういうのは、だいたいこの発想で書く。わかりやすいように
u/3にしたけど、u/4の定義にして ... u(1,Arg,P,Q), ... と呼び出すように
定義する方が普通。 u(N,Arg,P,Q) :- N > Arg,!. が第一節にくるのかな。
>>456 だと引数の後の方から評価するから、使い方の問題ではあるが、
(:-)/2 など副作用の発生する順序などが意味を持つ解析では具合の
悪いことが起こるかもしれない。
やれ、キャストだ、クロージャだといったような議論が皆無なのがPrologですが、 functor/2 arg/3 (=..)/2 はいつでも気楽に使えるようになった方がいいと思います。 故意にでもそういうコードを沢山書くことですね。 関数を追加定義できるように is/2 ではなく、 は/2 を定義してみるとか。
459 :
458 :2008/08/31(日) 04:33:07
ごめん。 functor/3 です。
>>449 >>450 を参考にして
member2(X,[H|_]) :- \+ \+ X=H.
member2(X,[_|T]) :- member2(X,T).
とかでいいのでは?
| ?- A=[B/c],member2(b/c,A).
A = [_14/c]
B = _14 ->;
no
ちなみに某処理系では「a == _」がセグメンテーション違反になってフイタw(地下5階)
仮想DOSマシンだとそれらしく動く罠
461 :
460 :2008/08/31(日) 12:35:49
おっと未改造版では無名変数がアトムだから「a == X」じゃないと再現しないかも。蛇足だスマソ
>>455 手元のSWI-Prolog 5.4.7だとunifyable/3は定義されていた。
>>462 SWIのライブラリのソースに
unifyable→unifiableと綴りをなおしたようなコメントを見た。
古いマニュアルには載ってるみたいだね。
\+ \+ G \+ \+ X = Y \+ X \= Y のほかに思いつくのは、 can_succeed(G) :- copy_term(G,H), call(H), !. とか
>>448 集合だと [2,3] と [3,2] は同じものとみなされるから、
A = 2,
B = 3; を返したら、
A = 3,
B = 2; を返すことはないであろう、と言う意味ですか。
466 :
465 :2008/09/01(月) 07:37:09
A = 2, B = 3 の時 集合 [2,3] とりなり、 A = 3, B = 2 の時 集合 [2,3] となる。 これを、論理的に破綻しているといいます?
>>465 それは[A,B]をXかなにかに見間違えただけでしたw
面目ない
カットがよく解りません… 説明してるサイト見に行っても「バックトラックが云々」と出て来て「うっ…」となってしまいます。 …というか、バックトラックがよく解らないのかも知れません。
とりあえず、具体的につまずいた例題があれば紹介してもらうと面白いかも
紹介してもらうと… 紹介してもらえると? 紹介してくれると? 紹介していただけると
北島康介がここで一言 ↓
チョ〜 気持ちい〜
Prologすれなのに・・・ 不覚にも吹いたw
>470 問題を解いていた訳ではないのですが カット使えた方が色々なことが出来るんじゃないかな、という 凄くばくぜんとしたn
>>475 それでは逆に質問。
member(X,[X|_])..
member(X,[_|R]) :- member(X,R).
の定義があるとします。この定義を
member(X,[X|_) :- !.
member(X,[_|R]) :- member(X,R).
に変えました。これで何が変わりますか?
477 :
476 :2008/09/07(日) 11:20:36
memberの第1節のピリオドが2個ついていますが、これはもちろん1個が正しい。
478 :
476 :2008/09/07(日) 12:02:55
もう1ヶ所間違っているので書き直します。 それでは逆に質問。 member(X,[X|_]).. member(X,[_|R]) :- member(X,R). の定義があるとします。この定義を member(X,[X|_]) :- !. member(X,[_|R]) :- member(X,R). に変えました。これで何が変わりますか?
479 :
476 :2008/09/07(日) 12:04:49
まだ直ってない.もう1ヶ所間違っているので書き直します。 それでは逆に質問。 member(X,[X|_]).. member(X,[_|R]) :- member(X,R). の定義があるとします。この定義を member(X,[X|_]) :- !. member(X,[_|R]) :- member(X,R). に変えました。これで何が変わりますか? おちゃーしゃのエディタ。フォント大きくできないかな。まったく読めない。
480 :
476 :2008/09/07(日) 12:05:38
まだ直ってなかった。もうやめた。みなさん、ごめんなさい。
めげるなw member1(X,[X|_]). member1(X,[_|R]) :- member1(X,R). member2(X,[X|_]) :- !. member2(X,[_|R]) :- member2(X,R). a1 :- member1(1,[1,1]), print('o'), fail. a1. a2 :- member2(1,[1,1]), print('o'), fail. a2. ?- a1. oo Yes ?- a2. o Yes
>もうやめた。みなさん、ごめんなさい。 ワロスwww てか、途中でやめんな。
>>469 トレースを取って読むとかそのへんの段階を飛ばしてないかな
>>481 member3(X,[X|_]).
member3(X,[_|R]) :- member3(X,R),!.
だとどうなる?
多分、
>>481 がテストして不適切だったことがわかる。
好ましくないとされるカットの例です。 ?- findall(X, ( member(X,[a,b,c,d,e]),(X=c,!,fail;true)), L). X = _1234, L = [a,b]; no % trueだとおもしろくありませんが findall(Y,(member(X,[a,b,c,d]),(X=c,!,fail;to_upper(X,Y))),L). % のように使いますね。 ?- see(foo),findall(X,(repeat,read(X),(X=end_of_file,!,fail;true)),L),seen. 質問を一行で済ましたい時にこのように使うことはあります。
>>484 不適切という言葉は不適切。
>>481 は
要素が2個でも一応完全にバックトラックしているからね。
この部分が解ればカットの半分は解ったことになるね。
>>486 レッドとグリーンがあって、こちらはレッドカット。節の末尾に来て、
非決定性-決定性を制御する。処理系に最適化を促すために
使うこともある。
ここらあたりは、「Prologの技芸」に詳しい説明が載っている。
著作権の問題さえなければ、ここに書き写してしまうのだが・・・。
>>487 著作権法第32条に、「公表された著作物は,引用して利用することができる。この場合において,その引用は,公正な慣行に合致するものであり,
かつ,報道,批評,研究その他の引用の目的上正当な範囲で行なわれるものでなければならない。」と定められています。
つまり、著作権法は引用の範囲(一定の条件)内であれば他人の著作物を著作権者の承諾なしで使用することを認めています。
一般には、
1)引用することが、オリジナルな文章(本文)を表現するために必要であること
2)自分のオリジナルな文章が主(量的にも質的にも)であり、引用部分が従であること・・・オリジナル全体の半分を越えた引用も著作権侵害に該当します。
3)引用部分とその他の部分が明確に区別できること、そして、引用文は改変しないこと
4)引用された著作物の出典が明示されていること(著作権法第48条)
と考えます。
引用の際にはこれらに注意すれば承諾なしで使用できます。ここで引用する場合もオリジナルな文章となるように解説すれば問題ないと思います。
>>488 ありがとうございます。適切な要約を試みてみます。
p(1) :- !,q1. p(2) :- !,q2. p(3) :- !,q3. はグリーンカット。このカットを入れることで本体側のユニフィケーションで 節が選択されるとそれより下の節は存在しないのと同じことになる。 ただし、q1,q2,q3は非決定性である可能性はある。 q1,q2,q3を決定性として扱うためには、 p(1) :- !,q1,!. p(2) :- !,q2,!. p(3) :- !,q3,!. と節の最後にカットをさらに入れる。
>>491 のq1には変数がないのに何で非決定性になるのだろう、
と疑問に思われる方もいるだろう。この疑問はq1が
q1 :- write(abc),nl.
q1 :- write(def),nl.
のような定義になっていると、
?- p(1),X = 5.
abc
X = 5;
def
X = 5;
no となることで解けるにちがいない。述語定義のなかに変数がなくても
非決定性に成りうる。
repeat.
repeat :- repeat.
などが典型である。
非決定性=外部から情報を与えて真偽値を最終的に決定すること
この外部から介入する機会は ?- p(1),X = 5. のように、質問の適切な
位置に変数を持ちさえすれば得られるのだ。
fail させればいいじゃないか、と考える人もいるだろう。そうです。 ただし、このfailは外部からの情報を擬似的に内部的に発生させている ショートカットのようなものです。一旦止まって、再実行の情報を もらったのと同じことを表現したものだと考えればよいでしょう。
p(X) :- X > 3,q1. p(X) :- q2. このようなコード見て、Prologプログラマは危ないなと思います。どうすれば危なくないか。 p(X) :- X > 3,q1. p(X) :- X =< 3,q2. こうすればよい。上のコードだと ?- p(5), X = 5. のような質問から呼び出されて、 この質問からバックトラックを要求されると結局q2が実行されてしまいます。 それを抑制するには、論理的に排除すればよい。さて、代案として、 p(X) :- X > 3,!,q1. p(X) :- q2. これもグリーンカットです。 カットを p(X) :- !,X > 3,q1. のところに入れてはいけません。 このカットによってそれまで上に定義されてきた節の条件をいちいち否定する必要がなく (X =< 3のこと)なり、プログラマの負担を軽減します。 しかし、私は上のコードの方が好きです。
495 :
494 :2008/09/10(水) 13:54:31
上のコードではわかりませんでしたね。 真ん中のコード、 p(X) :- X > 3,q1. p(X) :- X =< 3,q2. がもっとも好ましいコードに思えます。
>>494 p(A,B,C,X) :- integer(A),integer(B),integer(C),q1(A,B,C,X).
p(A,B,C,X) :- integer(A),integer(B),not(integer(C)),q2(A,B,C,X).
p(A,B,C,X) :- integer(A),not(integer(B)),integer(C),q3(A,B,C,X).
p(A,B,C,X) :- integer(A),not(integer(B)),not(integer(C)),q4(A,B,C,X).
p(A,B,C,X) :- not(integer(A)),integer(B),integer(C),q5(A,B,C,X).
p(A,B,C,X) :- not(integer(A)),integer(B),not(integer(C)),q6(A,B,C,X).
p(A,B,C,X) :- not(integer(A)),not(integer(B)),integer(C),q7(A,B,C,X).
p(A,B,C,X) :- not(integer(A)),not(integer(B)),not(integer(C)),q8(A,B,C,X).
4引数の述語q1,q2,q3,q4,q5,q6,q7,q8が決定性の述語だとすると
述語p/4は完全に決定性の述語です。しかしこのコード書くのちょっと大変ですね。
実際にはmember/2を3個使って自動生成するにしてもそれ自体相当な手間です。
しかし、グリーンカットを使うと以下のようにnot(_)を見事に排除できます。
p(A,B,C,X) :- integer(A),integer(B),integer(C),!,q1(A,B,C,X).
p(A,B,C,X) :- integer(A),integer(B),!,q2(A,B,C,X).
p(A,B,C,X) :- integer(A),integer(C),!,q3(A,B,C,X).
p(A,B,C,X) :- integer(A),!,,q4(A,B,C,X).
p(A,B,C,X) :- integer(B),integer(C),!,q5(A,B,C,X).
p(A,B,C,X) :- integer(B),!,,q6(A,B,C,X).
p(A,B,C,X) :- integer(C),!,q7(A,B,C,X).
p(A,B,C,X) :- q8(A,B,C,X).
>>491 > p(1) :- !,q1.
> p(2) :- !,q2.
> p(3) :- !,q3.
> はグリーンカット。
目標p(1)、p(4)などに対しては意味が変わりませんが、
p(X)でXを生成しようとすると意味が変わります。
>>494 > p(X) :- X > 3,!,q1.
> p(X) :- q2.
> これもグリーンカットです。
これは全く意味が変わります。
>>497 なるほど。
私はGHCのガードに当たるものは、グリーンだと思い込んでいましたが、
全くの誤りでした。
p(1) :- !,q1.
p(2) :- !,q2.
も確かにカットを外せば ?- p(X). に対して X=1; X=2; となっていくはずですね。
>>491 -
>>496 のグリーンカットと書いた部分を外さねばなりません。
もう一度、書き込むわけにもいかないので、その部分を無視して読んでください。
>>498 久々の力作なんだから、書き直した方がよくね?
皆さんありがとうございます… 何かもう少しでピコーン来そうな予感です。 確かにトレースはサボっていたかも… 今まで手続き指向の言語しかやったことがなく 「これがプログラミング言語なのか?制御が書けない。ある種のツールなのでは?」 とも思いかけてたんですが 何か自分の中で「いや、これは間違いなくプログラミング言語だ」という気がして来ました。 制御を直接書くのではなく、既に制御されてるものを上手くコントロールする感じでしょうか。 そしてカットはその手段のひとつなのかな、と。 正直failとかも自分で練習に書くコードでは書いて来なかったんですよね。 これもカットと同じく制御のコントロール手段かな…? >494 p(X) :- ! X > 3 q1. としてはいけない理由は何なのでしょうか?
501 :
469 :2008/09/10(水) 19:29:42
ごめんなさい…カンマが改行に変換されてしまいましたorz
>>500 3より大きければq1が実行され、
3以下であればq2が実行されるようにしたいわけです。
p(X) :- !,X > 3,q1.
だと、Xが3以下の時もカットを通過してしまいます。例えば
?- p(2). でも !を通過し、2 > 3 が実行されて偽となり、しかも、
カットをすでに通過していますから、次節の
p(X) :- q2. へは進むことができません。
ちゃんと動くプログラムで動作を比較した方が早いのでは
>502-503 すみません、そうですね。自分で書いて試して確認しました。(gprolog) q1 :- write('q1 '). q2 :- write('q2 '). p1(X) :- X > 3, !, q1. p1(_) :- q2. p2(X) :- !, X > 3, q1. p2(_) :- q2. t(I,X,_) :- I >= X. t(I,X,P) :- I < X, call(P,I), t(I+1,X,P). t(X,P) :- t(0,X,P). | ?- t(10,p1). q2 q2 q2 q2 q1 q1 q1 q1 q1 q1 true ? yes | ?- t(10,p2). no まだオロオロしながらで、なかなか定まりませんが 書く場面とその効果がだいぶ見えて来たので色々試してみます。 ありがとうございました。
1日は何秒か?100000秒は何日か?などの問いに答えるプログラムを書いてみました。 もっとうまい書き方があったら教えてください。 p(X, '日', Y, '時間') :- nonvar(X), !, Y is X * 24. p(X, '日', Y, '時間') :- nonvar(Y), !, X is Y / 24. p(X, '時間', Y, '分') :- nonvar(X), !, Y is X * 60. p(X, '時間', Y, '分') :- nonvar(Y), !, X is Y / 60. p(X, '分', Y, '秒') :- nonvar(X), !, Y is X * 60. p(X, '分', Y, '秒') :- nonvar(Y), !, X is Y / 60. p(X, M, Y, N) :- nonvar(X), !, p(X, M, Z, K), p(Z, K, Y, N). p(X, M, Y, N) :- nonvar(Y), !, p(Z, K, Y, N), p(X, M, Z, K).
p(1, '秒', X, '秒').でスタックオーバーになったりする やっぱ安直すぎる実装だったかな…
>>506 よいテストデータを見つけましたね。拍手。
こういうバグの意味がくっきり浮き出てくるのが、Prologのいい所だな。
書き出しは、 p(1, '日', 24, '時間'). p(1, '時間', 60, '分') . ..... が素直なのではないか。
510 :
505 :2008/09/14(日) 12:09:19
>>509 そうですね。さらに、第一引数の「1」も要らないような気がしてきました。
そこで、経路検索のイメージで考え直してみることにしてみました。
?- convert(1, '日', X, '秒'). のように使います。
p('日', '時間', 24). % 1日 = 24時間
p('時間', '分', 60). % 1時間 = 60分
p('分', '秒', 60). % 1分 = 60秒
pp(M, N, K) :- p(M, N, K).
pp(M, N, K) :- p(N, M, K2), K is 1/K2.
q(S, S, _, 1) :- !.
q(S, E, L, K) :- \+ member(S, L), pp(S, N, K2), q(N, E, [S|L], K3), K is K2 * K3.
% convert(+X, +M, -Y, +N)
convert(X, M, Y, N) :- q(M, N, [], K), Y is X * K.
>>510 この際、
?- convert(3,日,X,Y).
X = 3, Y = '日';
X = 72, Y = 時間;
X = 4320, Y = 分;
X = 259200, Y = 秒;
no
も可能にしましょうよ。
双方向性というよりも。バランスプログラミングかな。
SWI-Prologみたいな巨大なのじゃなくて、schemeでのgaucheみたいな実装無いかなあ。
gprologくらいで良いんじゃないの? あれ、必須なのは数個のファイルだけだし
grolog
なんかグロそうな名前だな
当たり前のバグ話。 member(A,[A|R],R). member(A,[_|R1],R) :- member(A,R1,R). が定義されている時に リストLの末尾N要素からなるリストXを取り出すには、 last_nth(L,N,X) :- member(_,L,X),length(X,N). でよいかという話。 last_nth(L,N,X) :- append(_,X,L),length(X,N). が正しいのだが。
518 :
517 :2008/09/17(水) 08:22:51
last_nth/3ではなくlast_n/3だね。
>>517 last_n/3の自然な仕様は、 第一引数と第二引数が逆になるだろう。 append/3とlength/2による定義は初めて見たが、 last_n(N,L,X) :- length(X,N),append(_,X,L). なるほどね。
length/2 や append/3 のような述語だけで構成されていたら Prologって最高におもしろいけどね。
海文堂刊の「Prologユーティリティライブラリ」ボグダン・フィリピッチ著
には
>>517 的な述語定義がけっこう載っていた。
Prolog-KABAの時代だったからこんなの実用にならないよと
非難囂々だったのだが、最近試してみると全然問題ない。
アセンブラで記述されたProlog-KABAと比較しても100倍以上
速く動いているんだね。
上の本もそうだが、Prologの古い本には読み返してみると これはなかなかというものが多い。 「Prologとその応用2」溝口文雄監修 総研出版刊 もそのひとつ。 正規表現のDCG記述だとかボトムアップパーザの丁寧な説明とか、 そのレベルの記事が満載で、この本が今日顧みられないことが 残念な気がする。 ところでこの本。「その応用1」はついに出なかった。
初心者です。Ubuntuにswi-prologをインストールしてみました。 で、普通にプログラミングできることはできるのですがテキスト等のyes/noと 違って、成功するとtrue失敗するとfailと表示されます。 意味的にはこっちが正しいとは思うのですが、これでいいのでしょうか。
っていうか、fail?上に挙げたMLの投稿ではfalseだけど
>>523 ちょっと読んだ限りでは、8月の時点で
・仕様変更されていた
・Yes/Noとは動作が違うし、理には適っている
・でもまあ取説には反映してないんだけどね
という状況だった、という感じ?
初心者です。頭がいい人よかったら教えてください 階乗のプログラムを制約論理プログラムで定義せよ。 なお、データ領域有限領域(0から100000まで)と実数領域の場合に分けること。 と言う問題です。SWI-Prolog使ってます
Prologの技芸を探してたら著者名が構造計画研究所になっていたんだけど 構造計画研究所ではProlog使ってるんでしょうか。
>>528 著者でもなければ翻訳者でもなく出版社だけどな。
中で使ってるかどうかは知らない。
>>528 私の勝手な解釈ですが、
使おうと思ったから「出版」して、
使うのを止めたから「絶版」にしたのでは。
Prolog単独ではちょっと弱いという場合、数種類のプログラム言語の 組み合わせが考えられる。たとえば、 Prolog + Tcl/Tk + R どこかのスレでこれからトレーダーになると人が推薦言語を求めて いたから私はPrologと書きました。この組み合わせはそれに対して 付いたレスです。さて、皆さんの三つ揃えはどんなものになりますか?
>>530 流行(第五世代プロジェクト)にのって出版しただけじゃね?
>>532 まあ、そうだろうね。ただあそこの出版物はやや趣味的なものを
感じるけど。
>>529 そうでしたか失礼しました。
大学在学中に学科(建築科)の掲示板にアルバイト募集のびらが張ってあり、
アルバイトに行った当時の友人の話だと「時間も本も沢山あるお!w
プログラミングの勉強しほうだいで、今ではJAVA覚えて何でもできるおwww」
という事でした。それだけでも羨ましいのですが
もしそんな調子でPrologやLispが覚えられるならば、やっておけばよかったかな、
なんて思いましたもので。
>>534 構造計画研究所についてはよく分かりませんが、Prologの処理系を
販売している人たちに聞くと、Prologユーザー数は15年くらい前と
現在では変わりがないそうです。処理系だけを保持していて使って
いない幽霊ユーザーではなく、実際に使っているユーザー数がです。
1990年代前半にPrologでやろうとしていたことをC++に置き換えた
所は結構あった記憶もありますが。
この15年ユーザ数は増えてない、と。
>>536 企業ユーザーは増えていないようです。もちろん国立大学を中心に
授業でPrologの講座はありますから、使ったことのある人数は
増加し続けていることになりますが、使い続けている人や団体となると
横ばいではないかと。
Erlangユーザーをカウントするとどうなっかな あとKL1使ってる人って死滅したの?
>>538 オープンソースのSWI-Prologの分は増加ということになる。
Erlangは15年前はほとんどゼロだから、激増! といっても3桁の単位かな。
Prologは日本は横這い、外国は少しずつ増え続けているというところでしょう。
KL1はKLICで2桁でしょう。
全然いないと思っても日本中探すと結構いるのではないか。
絶滅危惧種は ESP(CESP) だね。
駅スパートシステムってまだ存在するの?
>>541 こじんまりとしたものを使ってるところはあるよ。
プログラムコードは沢山公開されたし、技術のノウハウ集的なものなら、
それの上にただ知識を乗せるだけで気の利いたものがすぐ動く。
医師の処方を代行しようとか、そういう壮大なものは挫折したのではないかな。
>>541 Prologの使い道を分類すると
・定理証明 これは別にすると、
・経路探索系
・言語解析系
・資源ブン捕り系
・エキスパートシステム系
に分類できる。上三つがそれぞれ深さ優先探索を軸に強い関連を
持つのに対して、エキスパートシステム系はアプリケーション的な
色合いが強く異彩を放っていると思う。使い勝手もよい。
言語解析系は自然言語解析が対象ではなく、文脈自由文法的な記述を
敢えてして、LL言語が正規表現などで探索するのに対して差別化を
試みる時に使われることが多いようだ。
まあ、ある時代有効でその後効力がなくなる技術なんて普通はないよ。
世の中が飽きるだけ。
>>542 > 医師の処方を代行しようとか、そういう壮大なものは挫折したのではないかな。
Mycin は成功例だろ
答えられる人が居ないだけさ
>>527 マジレスすると、有限領域の場合はマニュアルにまんま載ってるYO
>>543 もっと単純に
・データベース系
というのがあると思う。
>>547 マニュアルってProlog内のでしょうか?見つからないです
すいません、本当ド素人なんです
site:gollem.science.uva.nl inurl:manual/clpfd fac 今サーバーに繋がらないからGoogleで
質問です。 「正確な値は決まってないけど、この2つは同じ値を取る」という状態は、その2つに同じ論理変数 を割り当てれば表現できますよね。 その反対の「正確な値は決まってないけど、この2つは異なる値を取る」という状態を表す方法は ないでしょうか? \=は値が決まらないと使えませんし、\==は別の論理変数であることしか規定できません。
>>553 ありがとうございます。
attributeというのは知りませんでした。
なかなか便利そうです。ただ、十分注意して使わないとプログラムの挙動が予測困難になりそうですね。
>>555 ありがとうございます。
まさに欲しかったものでした。
attribute変数を使って一応自作しましたが、やはり標準のものが
いいですね。
KLICの話題はここでいいでしょうか?
>>557 今までもちょくちょく話題になってるからいいんじゃない
X⊆Yであるとき、yesを返す(ここでXとYはリスト) imp(X,Y)はどのように定義すればいいのでしょうか? prologは初めてで手続き型言語しかならったことがないので リストの扱い方がよくわかりません
>>560 % 普通は。
imp([],_).
imp([A|R],Y) :- member(A,Y),imp(R,Y).
member(A,[A|_]).
member(A,[_|R]) :- member(A,R).
% member/2は組込述語になっていて、定義する必要はないかも。
% こういうのもあり得る。
imp(X,Y) :- sort(X,X2),sort(Y,Y2),imp_2(X2,Y2).
imp_2([],_) :- !.
imp_2([A|R1],[A|R2]) :- imp_2(R1,R2).
imp_2([A|R1],[B|R2]) :- A @> B,imp_2([A|R1],R2).
imp_2([],_) :- !. のカットは要りません。 imp_2([],_). imp_2([A|R1],[A|R2]) :- imp_2(R1,R2). imp_2([A|R1],[B|R2]) :- A @> B,imp_2([A|R1],R2). ですね。
空気を読まずにClocksin & Mellishのプログラムを改造
http://okwave.jp/qa831807.html > 本に載っていたのを試したのですが
> 順番が逆になってしまいます。↓
>
> remdup(L, M) :- dupacc(L, [], M).
> dupacc([], A, A).
> dupacc([H|T], A, L) :- member(H, A), dupacc(T, A, L).
> dupacc([H|T], A, L) :- dupacc(T, [H|A], L).
remdup2(L,M) :- dupacc2(L, [], M).
dupacc2([], _, []).
dupacc2([H|T], A, L) :- member(H,A), !, dupacc2(T, A, L).
dupacc2([H|T], A, [H|L]) :- dupacc2(T, [H|A], L).
http://pc11.2ch.net/test/read.cgi/tech/1186292994/606# % *** replicate/2 ***
replicate(N,X) :-
N > 0,
replicate(1,N,1,X).
% *** replicate/3 ***
replicate(N1,N,M1,[]) :-
N1 > N.
replicate(N1,N,M1,X) :-
N1 =< N,
M1 > N1,
N2 is N1 + 1,
replicate(N2,N,1,X).
replicate(N1,N,M1,[N1|R]) :-
N1 =< N,
M1 =< M,
M2 is M1 + 1,
replicate(N1,N,M2,R).
int f(int x) { ... } のような関数のコメントに /* ** 引数: 整数値 ** 戻り値: 整数値 */ と書く後輩を思い出した。 whatを記述するのは難しいらしい。
566 :
564 :2008/11/10(月) 21:23:05
ごめん。よくよくみれば replicate/4 でしたw
>>564 自分の発想ではこんな感じに
(1) dup(a,3,[a,a,a|X],X) のような述語を組み合わせて2重ループを組む。
(2) ループの状態遷移を分離する。
replicate2__next(1,N0,N1,N1) :- 1 =< N0, N1 is N0-1.
replicate2__next(M0,N,M1,N) :- 2 =< M0, M1 is M0-1.
(4/4, [1,2,2,3,3,3,4,4,4,4])
:
(1/4, [1,2,2,3,3,3,4])
(3/3, [1,2,2,3,3,3])
:
(1/2, [1,2])
(1/1, [1])
(0/0, [])
>>564 第一引数が都合よく二重に情報として利用できる特殊なケースだな。
>>564 他スレでの質問に対して、このスレで答えていくというのはいいアイディアかも知れない。
ここでは最適化とか、単一化を速くする戦略とか、そういう観点からの 言及のように思うけれど。 それより私の気にかかるのは、RubyとかLispの中に巧みにPrologが 組み込まれたとしても、RubyやLispの専門家が論理学のそれであることは まれだろう。そうだとすると、日常的にPrologを書いてない人がこの 推論部分はProlog向きだからってすらすらとPrologが書けるかという問題。 「ふつう」のPrologプログラマは長く使っているから多少は論理的に 物事を考えられる様になったという人たちなのであって、逆にそれだからこそ、 Prologプログラムが書けるのだ。
私はLispとPrologはセットで習った世代ですね。 商用のLisp処理系も大抵Prologがついてくるし、両方使うって人は多いのかと思っていた。 皆さんProlog一本なんですか?
>>576 私はLISPからPrologへ移った世代。LISPでPrologを書いた世代と
いってもいい。Prologを始めたらLISPをやってる必要はなくなった。
性能的に全部Prologってわけにはいかなかったなぁ。 メモリに乗らないデータの扱いに困ってた。最近だとどうなのかな。
俺は、Prologだけだった Prolog最高!!!
最新の理論に追従できてないみたいですが、今から学ぶ価値ありますか? HaskellやRubyより優れている点は?
そもそも論理型言語なので、HaskellやRubyとは根本的に別物なのですが...
assertion とかどうやってるの?
プログラム全体がassertionというかassertionしかないというか
>>583 普通のプログラムの正当な論理のコードと、デバッグ用のコードと区別できないような…
そこでAlgorithmic Debuggingです
assertion(P) :- not(P), halt.
>>586 例えば
f(X), g(Y),assertion(X>=Y)
って、f(X) か g(Y) が偽だと assertion は実行されないんだけど大丈夫でしょうか?
実行とは? prologではf(X)は関数の適用なんかじゃ無いよ。
これが関数脳か・・・
>>580 「最新の理論に・・」
>>581 に同意。頭の働かせ方が違うとしかいいようがない。
「学ぶ価値」 学門としての研究課題が見つかるかどうかは知らない。一般論としては
初・中等教育では、論理学的な学習は全く不十分なのでPrologコード書くことは意義がある。
「優れている点」 生産性。
生産性で言うとLispの内蔵言語として実装するのが一番だろうなー Prologのみだと手続き的な処理でどうしても記述が冗長になる
Ruby上(?)にDSLとして実装できるかな
>>591 z(X) がビルトイン関数で、評価するときにXが0未満だとマシンがハングするとする。
P(X) :- a(X), b(X), c(X), ・・・, assertion(X>=0), z(X).
a(X), b(X), ・・・のどれかが失敗し続ける限り、assertion(X>=0)の失敗を検出できない。
>>595 そのプログラムの虫をとるほうが先なのでは、
というような状況しか想像できないw
あれ?なんか変なことを書いてしまったw いいんじゃん虫取りで
結論 : Prolog では、多人数で仕様書やコードを使い回すような規模のプログラム開発は無理
>>595 assertion って知らないんで、興味深いね。
a(X),b(X),c(X) , ・・・,assertion(X>=0),z(X).
もし、これが並列に実行される系だとするとassertionはどんな
特権的な地位を持つの? そのままだとハングしてしまう。
予備知識 assert は、プログラムのフローとはまったく関係ないユーザ側の異常入力等を検出します プログラムのフローとは関係ないので、C言語とかだと、デバッグのとき以外はNULL文になるようなマクロで実装されています デバッグ時には、仕様上では考えられないような入力が入ってた場合等、assertがFALSEになったときに警告を出力します assertは、バグを探すためだけに存在すると言っても過言では有りません
>>595 void p(int X) {
if (a(X)) {
if (b(X)) {
assert(X>=0);
z(X);
}
}
}
Cでもa(X)やb(X)が偽を戻すとassert(X>=0)の失敗を検出できませんが何か?
仕様書に、「P(X) は、Xが0未満の整数になってはならない」 と書いてあるのに、ソースファイルにP(-1)とミスタイプするバカを検出する方法が assertion
>>602 void p(int X) {
int isA, isB, isZ;
isA = a(X);
isB = b(X);
assert(X>=0);
izZ = z(X);
return isA && isB && isZ;
}
仕様書の通りに p(X) :- ・・・,X が 0 未満 の 整数 に なってはならない,・・・. とするのがProlog流だな。条件のどこにこれを置くかが微妙で、それがPrologの弱点。 ともかく、仕様の通り書くのがProlog。この立場からいうと、上のassertに ついての話は何をいってるのかわからない。
>>604 念のため聞いておきたいんだけど、それは本気で書いてるの
>>605 それだと、プログラムのアルゴリズム上の項の羅列と、仕様外の異常値のチェックが同じライン上に乗ってて区別できないけど、それがProlog
流?
>>604 voidなのに値を返すとはさすがC脳w
>>607 「仕様外の異常値」なんて曖昧に考えてるからおかしいんじゃね?
定義域かどうか、それだけでいいだろ
>>604 javaでも
if(func1(x) && func2(x) && .... && funcZ(x)){System.out.println("test");}
ってあって、func1(x) が偽だと、 func2(x) 〜 funcZ(x) がまったく評価されない。
結局、デバッグの際に論理式が確実に評価されるように分解して書き直すハメになる。
>>608 int p(int X) {
int isA, isB, isZ;
isA = a(X);
isB = b(X);
assert(X>=0);
izZ = z(X);
return isA && isB && isZ;
}
トリップつけろw
>>607 fail と error の区別がつかないという指摘はPrologが広まった
当初からあった。私は仕様以外の事はプログラムにしないという
原理主義者だから、全部不便でもfail。だから
>>607 は諾。
ちょっとぐぐった限りでは、 !!p & !!q & !!r みたいな変態コードは見つからなかったよw
今の流れはたいへんビミョーだと思うけど、テストやデバッグの話題は面白いと思う
自分はよくても他人はどう使うか分からないしな なんとか上手に警告出せるようなトリックはないだろうか
>>613 Cのビット演算子とjavaの論理演算子が一緒にあると拒否反応が出る…末期症状だ orz
やはり単一化の時点でassertionが働かないと。制約論理型だと何とかなるか。
中島秀之氏の「項記述」などを復活させてみたらどうか。
>>618 Javaにもビット演算はある
ビット演算ではないがbooleanにも&,|,^を適用できる
JLS3e 15.22 Bitwise and Logical Operators
>>619 when/2でnonvar/1を条件にすればできるのでは
だんだんワケが分からなくなってきた ・プログラムで上手に処理しなければならないエラー (例:入力したファイル名がおかしい) ・値が入った瞬間にマシンがハングアップするような処理系が処理することすらできないエラー 前者は、エラー処理のアルゴリズムが担当 前者のエラーは、コードにバグがなくても、プログラム実行中に確実に起こりうるエラー 後者の値のチェックを、assertion が担当 理想的には、assertionの警告を良く読んでデバッグしていくと、後者のエラーは最後には無くなる (だからassertionはデバッグのときだけ必要)
「assertまで到達しない」とか「assertの置き場所が違う」とかの超越的な問題は、 そもそも単純なassert的検査だけではどうしようもないんじゃないかな。 おまけ:assertについての妙な表現の例 ・assertが出る/発生する/起きる (「発動する」はアリか?) ・assertがかかる/引っかかる (「に」引っかかる、ならそのまま受け取れる) ・assertが検出される 「エラーが出る」は「エラーメッセージが出る」の略とも解釈できるけど… assertの場合は逆の意味になってしまいそう
>>623 そもそもassertionを誤解してるんじゃないか
ホーア論理でも調べてみてはどうか
特定の項が呼び出される直前と直後に、あらかじめ登録しておいた特定のプログラムを呼び出すような仕組みがあればいいと思います。 emacs lisp の hook みたいな感じで。
「assertは祈りではない」(パウ口)
>>595 P(X)の定義域がX>=0であるなら最初に表明してしまえばいい。
P(X) :- X < 0, !, fail.
P(X) :- a(X), b(X), c(X), ..., z(X).
>>628 チェックをしないバージョンを作るときには、コードを何ヵ所も削除しないといけないくなる気が…
プログラミング中は、assertで警告を出すと同時にデバッガを起動したりスタックをだらだら出力したいんだけど、 製品版では何もして欲しくないから。 一個の整数の比較だけならいいけど、リストを末尾までチェックしたりする場合には遅くなるし。
>>628 Prologの場合、副目標が呼ばれる前にassertionが入るというのは普通ではない。
だから、
>>595 に対する答えは、
:- op(900,fx,assertion).
p(X) :- a(X),b(X),c(X) , ... ,zx(X).
assertiion (zx(X) :- X < 0, !, 警告( ... ),fail).
zx(X) :- z(X).
実行モードでconsult,reconsult,compileされる時はassertion節は無視される。
とするのが一番自然に思える。
>>634 それだとassertion/1を追加する表現になっているのでもうひと工夫!
#assert zx(X) :- X < 0,!,警告( ... ),fail. zx(X) :- z(X). とかやるか。
すみません、教えてください。次のようにして簡単な微分の処理を書き始めています。 合成関数の微分の処理で、sin(x^3)のように引数にxが入っているのかどうかを判定するにはどうしたらいいでしょうか? d(C,X,0) :- integer(C). d(C,X,0) :- atom(C). d(X^N,X,X^N1) :- integer(N),N1 is N-1. d(sin(X),X,cos(X)). d(cos(X),X,-sin(X)). d(log(X),X,1/X). d(exp(X),X,exp(X)). d(F+G,X,DF+DG) :- d(F,X,DF),d(G,X,DG). d(F-G,X,DF-DG) :- d(F,X,DF),d(G,X,DG). d(F*G,X,DF*G+F*DG) :- d(F,X,DF),d(G,X,DG). d(F/G,X,DF*G-F*DG/G^2) :- d(F,X,DF),d(G,X,DG). d(sin(X),Y,0) :- integer(X). d(sin(X),Y,cos(X)*DXS) :- d(X,Y,DX),simp(DX,Y,DXS). simp(X^0,X,1). simp(X^1,X,X). simp(C,X,C).
すみません、お騒がせしました。なんとかなりました。 among(X,Y) :- term_to_atom(X,X1),atom_chars(X1,X2),member(Y,X2). すみませんでした。
再帰的に項の引数にアトムがあるかどうか検査する(_項) :- functor(_項,_関数,_引数の個数), 再帰的に項の引数にアトムがあるかどうか検査する(1,_引数の個数,_項). 再帰的に項の引数にアトムがあるかどうか検査する(_,0,_項) :- atom(_項),!. 再帰的に項の引数にアトムがあるかどうか検査する(N,_引数の個数,_項) :- N =< _引数の個数, arg(N,_項,_引数項), 再帰的に項の引数にアトムがあるかどうか検査する(_引数項),!. 再帰的に項の引数にアトムがあるかどうか検査する(N,_引数の個数,_項) :- N =< _引数の個数, N_1 is N + 1, 再帰的に項の引数にアトムがあるかどうか検査する(N_1,_引数の個数,_項). % 具体的なアトムが存在するかどうか知りたいなら1引数増やして % atom(_項),!. を % _atom(_項),項=_検索アトム,!. に置き換える。
640 :
639 :2008/11/24(月) 20:30:01
% _atom(_項), ... は間違い atom(_項), ...
ありがとうございます。 よく調べて考えてみます。
% 注意 ?- var(X),functor(X,A,B). no ?- functor(3.14,A,B), A = 3.14, B = 0 yes ?- % 引数が0であるだけではatomとは判定できない。
%
>>639 % が間違っていることに気づいたんだがどう直せばよいのかな。
?- 再帰的に項の引数にアトムがあるかどうか検査する(万葉集).
yes
% 引数がないのに真になってしまう。
帰ってきたPrologトリビア探検隊
このスレの
>>1 にもある『Prologの冒険』(原題“Adventure in Prolog”)の「まえがき」より。
> そして生まれて初めて(しかもたぶん最良の)アドベンチャーゲームを書いた Will Crowther と Don Woods に感謝します。
…誰?と思ったが、とりあえずスルー。
<10年以上経過>
去年ごろ読み返したとき、またこの名前が気になったのでグーグル先生に聞いてみた。
この2人は、アドベンチャーゲームというジャンルの元祖となった伝説的作品の作者たちだった。
(例えばジャーゴンファイルに「ADVENT」という見出しで記載がある)
しかし「生まれて初めて」の意味はやはりわからない。
わからないけど、まあ、なんかあるんだろう。と再びスルー。
<1年ほど経過>
何気なく、ウェブで公開されている原文の「Preface」(「まえがき」にあたる)を開いてみて、はっとする。
> a copy of the original Adventure game
(意味:元祖「Adventure」ゲーム/アドベンチャーゲームの元祖である「Adventure」という作品)
これが訳書では…
> 自作のアドベンチャーゲーム
じゃ、じゃあ…
> 生まれて初めて(しかもたぶん最良の)アドベンチャーゲームを書いた
は…!
> writing the first (and in my opinion still the best) adventure game
(意味:世界初の〜/世界で初めて〜)
もしこの訳書に、アドベンチャーゲームの歴史についての訳注がちょろっと書いてあれば、
Prologももうちょっと広まったかもしれないなあ、なんて思った。そんな日本Prolog裏面史w
あと、誤訳の可能性を想像できなかった自分のデバッグ力不足を思い知った
>>643 再帰的に項の引数に変数があるかどうか検査する(_項) :-
functor(_項,_関数,_引数の個数),
再帰的に項の引数に変数があるかどうか検査する(1,_引数の個数,_項).
再帰的に項の引数に変数があるかどうか検査する(N,_引数の個数,_項) :-
N =< _引数の個数,
arg(N,_項,_引数項),
atom(_引数項),!.
再帰的に項の引数に変数があるかどうか検査する(N,_引数の個数,_項) :-
N =< _引数の個数,
arg(N,_項,_引数項),
not(atom(_引数項)),
再帰的に項の引数に変数があるかどうか検査する(_引数項),!.
再帰的に項の引数に変数があるかどうか検査する(N,_引数の個数,_項) :-
N =< _引数の個数,
N_1 is N + 1,
再帰的に項の引数に変数があるかどうか検査する(N_1,_引数の個数,_項).
>>643 確かに長々しい述語名にしないと発見しにくいバグかもしれないw
>>647 googleで引っ掛かるようにする工夫でもある。
>>646 これ「変数」ではなくて、「アトム」ですね。タイプミスかな。
Prologで3次元ベクトルを扱うことを考えています。 Prologに大域変数はないので次のようにやってみました。 Prologでベクトル、行列を扱う場合の定石がありましたら教えてください。 v(a,[2,3,1]). v(b,[3,5,2]). vec_eq(X,Y) :- v(X,V),v(Y,V). inner_product(X,Y,Z) :- v(X,[X1,X2,X3]),v(Y,[Y1,Y2,Y3]),Z is X1*Y1+X2*Y2+X3*Y3. outer_product(X,Y,[Z1,Z2,Z3]) :- v(X,[X1,X2,X3]),v(Y,[Y1,Y2,Y3]), Z1 is X2*Y3-X3*Y2, Z2 is -(X1*Y3-X3*Y1), Z3 is X1*Y2-X2*Y1.
>>650 ベクトル演算部分だけの述語を最初に定義する。次に、
データベースから取り出して、そのベクトル演算述語に計算させる。
そういう述語をいろいろ定義する。結果をデータベースに保存する場合もあるでしょう。
順序、作りは、そうするのが普通だと思います。
「Prologで作る数学の世界 Prologそして集合-位相-群」 飯高茂著 朝倉書店 1990/6 ISDN10-:4254110545
なども参考になさったらよいでしょう。
>>649 タイプミスかな、とは武士の情けか。ほろっ。
変数検索版を作ってる最中にバグを発見したので、それをベースに
改訂版を作ってしまった・・・
>>650 どういう感覚でそのv/2を使おうと思ったのでしょうか
>>651 その本を以前、書店で探してみたのですが残念ながら絶版でした。
県立図書館にもないので大学の図書館で探してみます。
>>653 数学で a=(1,2,3)とするのようなことをしようとしたものです。
黒川利明先生のPrologの本にあったことが記憶にあったのかもしれません。
>>654 (a×b)×aとかa×(a×b)のような連続的な計算に不便と思うのですが、
目的にないのでしょうか。A=[1,2,3]ではいけませんか。
>>655 たしかにその通りでした。
大域変数で保持しようとするとエラーになりました。
triple_vector_product(X,Y,Z,A) :-
outer_product(Y,Z,V),
assert(v(t,V)),
outer_product(X,t,A).
これを次のように書き換えるときれいにまとまりました。
outer_product([X1,X2,X3],[Y1,Y2,Y3],[Z1,Z2,Z3]) :-
Z1 is X2*Y3-X3*Y2,
Z2 is -(X1*Y3-X3*Y1),
Z3 is X1*Y2-X2*Y1.
triple_vector_product(X,Y,Z,A) :-
outer_product(Y,Z,V),
outer_product(X,V,A).
A=[2,3,1],B=[3,5,2],C=[2,5,4],triple_vector_product(A,B,C,Z).
A = [2, 3, 1],
B = [3, 5, 2],
C = [2, 5, 4],
Z = [23, 0, -46].
% 質問された方は実はよくお解りのようですが、初心者向けに掲げておきます。 行列演算((+),[],[],[]). 行列演算((+),_行列1,_行列2,X) :- 行列の和(_行列1,_行列2,X). 行列演算((*),_行列1,_行列2,X) :- 行列の積(_行列1,_行列2,X). 行列の和([],[],[]). 行列の和([A|R1],[B|R2],[C|R]) :- 加算(A,B,C),行列の和(R1,R2,R). 行列の積(L1,L2,X) :- 行列の転置(L2,L4),行列の積_1(L1,L4,X). 行列の積_1([],_,[]) :- !. 行列の積_1([A|R1],L,[S1|R3]) :- 行列の積_2(A,L,S1),行列の積_1(R1,L,R3). 行列の積_2(_,[],[]) :- !. 行列の積_2(A,[B|R2],[C|R3]) :- 行列の積_3(A,B,C),行列の積_2(A,R2,R3). 行列の積_3([],[],0) :- ! . 行列の積_3([A|R1],[B|R2],S) :- S1 <- A * B,行列の積_3(R1,R2,S2),S <- S1 + S2. 行列の転置([],[],[]) :- !. 行列の転置([[A|R]|R1],[A|R2],[R|R3]) :- 行列の転置(R1,R2,R3). 行列の転置([[]|_],[]) :- ! . 行列の転置(L,[B|R1]) :- 行列の転置(L,B,R2),行列の転置(R2,R1),!. '行列?'([[_|_]|_]). 加算([],[],[]) :- !. 加算([A|R1],[B|R2],[C|R]) :- C <- A + B,加算(R1,R2,R).
% 利用者関数定義述語 :- op(900,fx,(<<-)). :- op(700,xfx,(<-)). :- op(400,fx,(`)). (<<- _式) :- X <- _式, member(A,X), format('~q\n',[A]), fail; true. X <- _式 :- functor(_式,_関数,Args), functor(_式2,_関数,Args), 引数を関数評価(1,Args,_式,_式2), 関数定義(_式2,X).
引数を関数評価(Args,0,_式,_式) :- !. 引数を関数評価(Args,Args,_式,_式2) :- arg(Args,_式,_引数), arg(Args,_式2,Y), Y <- _引数,!. 引数を関数評価(N,Args,_式,_式2) :- arg(N,_式,_引数), arg(N,_式2,Y), Y <- _引数, M is N + 1, 引数を関数評価(M,Args,_式,_式2). 関数定義(` _項,_項) :- !. 関数定義(_式,X) :- 利用者関数定義(_式,X). 関数定義(_式,X) :- X is _式,!. 関数定義(_式,X) :- _式 =.. [F|R], list_length([F|R],Length), current_predicate(F/Length), append([F|R],[X],L), Q =.. L, call(Q). 関数定義(X,X) :- !.
用者関数定義(_式,X) :- functor(_式,_関数,2), arg(1,_式,_引数1), arg(2,_式,_引数2), '行列?'(_引数1), '行列?'(_引数2), 行列演算(_関数,_引数1,_引数2,X).
>>660 の最初の一文字がCopyされていませんでした "利用者関数定義"ですね。
:- op( ... ). の部分を最初に実行しないと行列述語の途中でsyntax error となります。
順序が逆になってしまいました。これで、
?- 行列の積([[3,-2,7],[-5,1,4],[2,-3,-1]],[[-4,2,5],[3,-2,1],[6,-3,-1]],X).
X = [[24,-11,6],[47,-24,-28],[-23,13,8]].
yes.
となりますし、
?- X <- [[3,-2,7],[-5,1,4],[2,-3,-1]] * [[-4,2,5],[3,-2,1],[6,-3,-1]].
X = [[24,-11,6],[47,-24,-28],[-23,13,8]].
yes
?- <<- [[3,-2,7],[-5,1,4],[2,-3,-1]] * [[-4,2,5],[3,-2,1],[6,-3,-1]].
[24,-11,6]
[47,-24,-28]
[-23,13,8]
yes
となります。
?- X <- [append([3],[-2,7]),[-5,1,2+2],[2,-3,-1]] * [[-4,2,5],[3,-2,1],[max([2,6,5),-3,-1]]. X = [[24,-11,6],[47,-24,-28],[-23,13,8]]. yes Prolog述語を関数とみなして評価しています。
max([2,6,5) は max([2,6,5]) の誤り。
とても参考になりました。ありがとうございました。 微積分、線形代数の復習のために数式処理システム、行列計算、行列式の計算、 ベクトルの計算などをPrologで書いて知識を明確にしようと思っています。 とても参考になりました。
>>657 一行目 行列演算((+),[],[],[]). これ要りません。行列の和に移動したのですが、
削り忘れました。実は、元々私のライブラリでは、
行列演算((+),[],[],[]).
行列演算((+),[A|R1],[B|R2],[C|R]) :- 加算(A,B,C),行列演算((+),R1,R2,R).
・・・
行列の和(_行列1,_行列2,X) :- 行列演算((+),_行列1,_行列2,X).
となっていました。
述語を定義していく順序として、
1) 行列の和/3 を定義した。
2) 関数評価可能にするため(
>>660 )
3) 行列演算/4 を 逆カリー化するように定義した。
そういう物語りを暗示したかった。
この程度のことでさえ、メタ述語の嵐になる… やはり一階言語には限界がありますな
>>667 利用者定義関数の部分ですか。そういうことになりますね。
こういう形で利用すればですね。
私は現在は関数定義はErlangを呼び出していて、利用者定義関数は
ほとんど追加していません。Prologでfunctor/3や=../2を使う所は
他にほとんどないですね。
>>667 というより、利用者関数定義(_項1 * _項2,X) :- '行列?'(_項1),'行列?'(_項2),行列の積(_項1,_項2,X).利用者関数定義(_項1 + _項2,X) :- '行列?'(_項1),'行列?'(_項2),行列の和(_項1,_項2,X).と列記するのがProlog流じゃないのか。
並列論理型言語のGHCを、今現在使っている人ってどのぐらいいるもの?
PSI2が何システム現役で動いているか。まず知りたい。
現時点ではKLICが実用になるとは思えない。システム記述ならともかく、 それ以外ではPrologと使い勝手に差がありすぎる。
DCGで簡易翻訳を行いたいんのですが、参考になるHPとかありますか?
どう書く?org というサイトのお題に「アラビア数字を使わずに漢字の 九九表を作れ」というのがあり書き込みました。下は私の書き込みの改良版。 漢数字(〇,[]). 漢数字(一,[_]). 漢数字(二,[_,_]). 漢数字(三,[_,_,_]). 漢数字(四,[_,_,_,_]). 漢数字(五,[_,_,_,_,_]). 漢数字(六,[_,_,_,_,_,_]). 漢数字(七,[_,_,_,_,_,_,_]). 漢数字(八,[_,_,_,_,_,_,_,_]). 漢数字(九,[_,_,_,_,_,_,_,_,_]). 九九表示 :- 漢数字(U,A), 漢数字(W,B), not(U=〇), not(W=〇), 九九(A,B,[],[],X,Y), 九九解表示(B,X,Y), U=九, W=九. % つづく
九九([],_,[],A,' ',Y) :- 漢数字(Y,A),!. 九九([],_,U,W,X,Y) :- 漢数字(X,U), 漢数字(Y,W),!. 九九(A,B,C,[_,_,_,_,_,_,_,_,_,_|R],X,Y) :- 九九(A,B,[_|C],R,X,Y),!. 九九([_|R],B,C,D,X,Y) :- append(B,D,E), 九九(R,B,C,E,X,Y). 九九解表示([_,_,_,_,_,_,_,_,_],X,Y) :- format('~q~q\n',[X,Y]),!. 九九解表示(_,X,Y) :- format('~q~q ',[X,Y]). :- 九九表示.
しまったインデントを忘れた。書き込み直すね。 九九表示 :- 漢数字(U,A), 漢数字(W,B), not(U=〇), not(W=〇), 九九(A,B,[],[],X,Y), 九九解表示(B,X,Y), U=九, W=九. 九九([],_,[],A,' ',Y) :- 漢数字(Y,A),!. 九九([],_,U,W,X,Y) :- 漢数字(X,U), 漢数字(Y,W),!. 九九(A,B,C,[_,_,_,_,_,_,_,_,_,_|R],X,Y) :- 九九(A,B,[_|C],R,X,Y),!. 九九([_|R],B,C,D,X,Y) :- append(B,D,E), 九九(R,B,C,E,X,Y). 九九解表示([_,_,_,_,_,_,_,_,_],X,Y) :- format('~q~q\n',[X,Y]),!. 九九解表示(_,X,Y) :- format('~q~q ',[X,Y]). 問題はここで九九/6と云う述語ですが、双方向性を持たせられないかな、 と思ったのです。appendしか使ってないし。どんなもんでしょう。
どう書く?orgの書き込みでは、九九表示/0 は 九九/0 でしかも、 九九 :- ..., fail. 九九. となっています。典型的なPrologのコードを示すとすると こちらの方がいいかなと。それと意外に感じる方が多いかと 思いますが、私の好みはこちらです。全部組み合わせますよ という宣言になってるでしょ。
純Lispが数をもたず数を表現するのにリストを利用したといいますが、 それを連想しました。 どう書くのお題に行列式の計算がありました。余因子展開をPrologを使って 書くということを考えてはみたのですがギブアップでした。Prologはそういったことには 向いていないように思います。 DCGのことはRun/Prologのマニュアルに説明があったよなぁと探してみたのですが 見つかりません。処分してしまったのかなぁ。
行列式の定義のsgn()について考えていました。互換の積の個数が 偶数か奇数かによって行列式の計算の際の符号が決まります。 転倒数というものがありその偶奇が互換の積の個数の偶奇と一致しているようです。 転倒数を列挙するものを考えてみました。 t([X],_,[]). t(Xs,W,[X,Y]) :- select(X,Xs,Ys), select(Y,Ys,_), X < Y, nth1(X,W,Wx), nth1(Y,W,Wy), Wx > Wy. t([1,2,3,4],[4,2,1,3],Z),write(Z),nl,fail. [1, 2] [1, 3] [1, 4] [2, 3] false. さて、その個数をカウントして偶奇により符号を返す述語を考えてみたのですが わかりません。
>>673 >>678 Webサイトについては疎いのですが、書籍なら、
「Prologとその応用2」 溝口文雄監修 溝口文雄,武田正之,畝見達夫,溝口理一郎著 総研出版
187pから後(畝見達夫担当)がお勧めです。洋書では
"An Introduction to Language Processing with Perl and Prolog" Pierre M. Nugues 著
Springer刊 の第8章。
>>679 行列式とは全然関係ないので恐縮ですが、append/3を使った例。
ガウス行列(_行列) :-
ガウス行列([],_行列).
ガウス行列(_,[]) :- !.
ガウス行列(L,[_行|R]) :-
append(L,_,_行),
要素がゼロ以外に出会うまで(_行,Zezos,_),
ガウス行列([0|Zeros],R).
要素がゼロ以外に出会うまで([0|R],[0|R1],R2) :-
要素がゼロ以外に出会うまで(R,R1,R2).
要素がゼロ以外に出会うまで(L,[],L).
Zezos -> Zeros に直してください。
append/3 と 要素がゼロ以外に出会うまで/3 を纏めると。 ガウス行列(_行列) :- ガウス行列([],_行列). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- zeros_append(L,_行,Zeros), ガウス行列([0|Zeros],R). zeros_append(Zeros1,L,Zeros2) :- append(Zeros1,L1,L), zeros_append_copy(L1,Zeros1,Zeros2). zeros_append_copy([0|R1],L,[0|R2]) :- zeros_append_copy(R1,L,R2). zeros_append_copy([_|_],L,L).
最終的には、 ガウス行列(_行列) :- ガウス行列([],_行列). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- zeros_append(L,_行,Zeros), ガウス行列([0|Zeros],R). zeros_append([],[0|R1],[0|R2]) :- zeros_append([],R1,R2). zeros_append([],[A|_],[]) :- not(A=0). zeros_append([0|R1],[0|R2],[0|R3]) :- zeros_append_copy(R1,R2,R3).
また副目標を一ヶ所間違えた。 ガウス行列(_行列) :- ガウス行列([],_行列). ガウス行列(_,[]) :- !. ガウス行列(L,[_行|R]) :- zeros_append(L,_行,Zeros), ガウス行列([0|Zeros],R). zeros_append([],[0|R1],[0|R2]) :- zeros_append([],R1,R2). zeros_append([],[A|_],[]) :- not(A=0). zeros_append([0|R1],[0|R2],[0|R3]) :- zeros_append(R1,R2,R3).
686 :
678 :2008/12/05(金) 21:23:16
>>680 「Prologとその応用2」書棚を探したらありました、持っていました。
当時は「Lispで学ぶ認知心理学3 言語理解」とかウィノグラードの
「言語理解の構造」渕先生訳 を素人なのに買い込んできて読んでいました。
今は数学への応用に関心があります。
LR parser generatorはないのかなあ。 左再帰の制限はつらい。
DCGの情報を確認しようと古い書籍を少し読む。Webではとかく 「技芸」の話題が多いが、「論理による問題の解法 Prolog入門」。 やはりコワルスキは凄い。1979年にこんな本が出版されてるんだから 驚き。もう研究することはあまり残っていない。
手続き的な操作はRubyでいいじゃん。 並行処理やバックトラックならHaskellでいいじゃん。 Prologの使いどころがわからない。
あっちからこっちへも こっちからあっちへも 双方向のユニフィケーションが欲しかったらPrologで ではいかんのか? のか?
>>689 全然わかってないね、 Prologとは単位節プログラミングのことだよ。条件節は補強でしかない。 何十万という単位節を蓄積していくのが、Prologプログラミング。
Prologってどんな用途に使うのか? (他の言語と同じ仕事をする時、他に比べて)どう便利なのか? ってことじゃない?
単位節って 「何々は何々である」 みたいなもの?
AとBはC関係にある、というような定義。
用途は企業実務一般。位置付けとしては表計算に近いと思う。 記述しやすいから、生産性が高い。 一昔前だと、情報は手でタイプしなくてはならなかったから、 収集したものをプログラム化するのはどんな言語でも大変だったが、 今日は情報を入手する時には既にデジタル化されている。 これを変形してプログラムとする場合、できるだけシンプルな 形式のものが有利。論理式に基礎を持つPrologは好ましいもののひとつ。 Webサイトを情報源とするケースだと、形態素解析が必要だが万単位の 単位節なんて、少量の規則で生成できてしまう。
静的型がないような言語を本当に企業で使えるの? 検証とか、デバッグとかで無駄にコストがかかりそう。 ライブラリとかも少なそうだし。
そんな大きなプログラムには決してならないからね。
大学でしか見たこと無い。
COBOLの代替とかそんな感じか
COBOLとは対極の位置にあるような気がするのは僕だけか…?
大学でやったがこれこれからどう使えば良いんだろ
DCGをいじっています。とりあえずこんなことやっています。 e --> s,v,o,c. e --> s,v. e --> s,v,c. s --> n. n --> [dog]. n --> [dogfood]. n --> [man]. n --> [cat]. n --> [mouse]. n --> [human]. n --> [error]. v --> [runs]. v --> [run]. v --> [eats]. v --> [is]. o --> n. c --> adjective. c --> n. adjective --> [beauiful]. e([human,is,error],[]). true
>>699-
>>700 Prologの対抗馬を挙げるとすればXMLだね。
>>696 企業実務の速度に追い付いていくには、
型とかコンパイルといってる時点でアウト。
COBOLがアウトになった件
>>705 さすがにそこまで言うとネタだ。問題が発生した場所で即プログラミングされる必要があることは確かだが。プログラム観の違いなのかな。
>705 それが本当だったらLispが天下取ってるわい。
我々、いや、少なくとも私が目指すのは、自然言語による極く短い プログラミング。すべての人が質問者であると同時に、プログラマで あって、その質問がその後再利用できるようになる、そういう言語。 論理プログラミングが支持されるのは、この目標に現時点では、 最も近いプログラミングスタイルを持っているからだ。
>>709 負節のログから節を選択して、Headを付加してassertしてる?
>>710 不十分ながら。?- 年齢(山崎,X),メールアドレス(山崎,Y).
が実行されると、
't00237#2'(X,Y) :- 年齢(山崎,X),メールアドレス(山崎,Y).
が生成されて候補節ファイルに付け加えられる。
?- haz('t00237#2','山崎さん').
を実行して、 assertz((山崎さん(X,Y) :- 年齢(山崎,X),メールアドレス(山崎,Y))).
を導くのだが、
1.. 述語名を推論して自動化などはできていない。
2.. 多くの場合有用なのは 't00238#4'(U,W,X,Y) :- 年齢(U,X),メールアドレス(W,Y).
も選択できることだろうけれど、これもできていない。
>>711 の2..は簡単にできそうなことなのですが、ちょっと考えどころが
あって、やっていません。このことについては、また後で。
?- メールアドレス(山崎,Y)年齢(山崎,X),メールアドレス(山崎,Y).
から自動で、
:- assertz((山崎さん(年齢(山崎,X),メールアドレス(山崎,Y))).
が導出できるなら、これは「質問者であると同時に、プログラマである」と
いえる。そうではなくて、質問者が質問と同時にこれは'山崎さん'で登録して
ください、などと言わなくてはならないとすると、
>>705 と同じような意味で
その時点でアウトです。
:- assertz((山崎さん(X,Y) :- 年齢(山崎,X),メールアドレス(山崎,Y))). でした。
>>689 Haskellについて言うと、20年を経て現在の普及度。
もう完全に死んでいます。
>>703 英語活用大辞典っていうのがありますね。研究社の。あれは、デジタル情報として
利用できないんですか。私は日本語しか興味がないのでちょっと対象外ですが、
国語辞典でああいうものがデジタルで利用できたらな、と思います。有料でも。
>>705 それなら訊くがあなたの言う企業実務の許容時間とは何秒ほどか。
暫し。 道の辺に清水ながるる柳蔭しばしとてこそ立ちとまりつれ --西行--
>>711 いわゆる自己レスだが、
?- 年齢(山崎,X),メールアドレス(山崎,Y). の
述語定義の中でヒットする節は
年齢(山崎,59).
メールアドレス(山崎,'
[email protected] ').
であろう。しかしもしかすると、それぞれインターフェイスの述語で
年齢(_氏名,_年齢) :- 年齢_2(_氏名,_年齢).
メールアドレス(_氏名,_メールアドレス) :- メールアドレス_2(_氏名,_メールアドレス).
と定義されているかもしれない。
この場合は 't00237#2'(山崎,_年齢,_メールアドレス) :- 年齢(山崎,_年齢),メールアドレス(山崎,_メールアドレス).
と候補節を作成する方が好ましいだろうか。さらに、't00238#4'は
't00238#4'(_氏名,_年齢,_メールアドレス) :- <略> .
であるべきだろうか。しかし、それでは年齢/2が
年齢(_変数,_アトム) :- var(_変数),atom(_アトム),年齢_2(_変数,_アトム).
だったらどうするのか。Prologの述語は型がなく双方向性という性質を持つため
このようなコードに遭遇する可能性は高い。メールアドレスの引数との重複の可能性も
でてきた。直後に検査副目標を持たない限りこのような記述は無意味であろう。
ほんの一例だが、ある述語の引数の論理変数に最適なラベルを貼ることは易しい
ことではないことが分かるだろうか。
>>712 の冒頭、口ごもったような書き方をしたのはこのためだ。
なんでprologってこんなにおもしろいんだろ 今はもう全然書いてないけどさ、 学生時代は教授からの課題を解き終わった瞬間がめちゃくちゃうれしくてさ、 何度も何度も自分のコードを見直して、ほれぼれしちゃうんだよな なんかコードが綺麗 まぁ実際はクソコードだっとは思うんだけどそれでもうれしかった
それはPrologというより先生の教育がよかったということだと思う そこそこ難しいものができたのをちゃんと評価してくれるとなんでも楽しいよね
>>16 > "PROLOG Programming for Artificail Intelligence" Ivan Bratko著の
これを買ってみたけど、
iterative deepeningの例(練習問題の解答)が解なしの場合に止まらない。
codeは余りdebugしてないのかな。
題名にPrologの入ってる本が先月かそこらに出たんだね
>>722 >>723 号外を出さなくてはいけなかった。ここ一週間Amazonの
Prolog本検索していたんだが、考えてみれば洋書ばかりだった。
和書、まさかっていう感じ。
>>693 山と山が連なっていてどこまでも山ばかりである、というのが関数型。徹して構造的。
一方、単位節プログラミングというのは平らで微視的。Binary Data Modelに近い。
この点があまり強調されていないのが不思議。
PrologをDBMSのクエリ言語として使うことってできない?
>>726 卒業研究でRDBの論文を読んだら、クエリがprologみたいな文法で記述してあって、
「これ、どのDBMSなんですか?」と聞いたら、論文での表記だけがprolog風なだけで実装はSQLだったのを思い出した。
あと、JavaCCで簡単なパーサを作って、prologの問い合わせをSQLに変換してた人もいた。
とりあえず、こんな感じでいいと思う。リストはメンバ関数を駆使する必要があると思う。
P(x, _) :- Q(x), R(x, y), y>=100.
↓
select x from P,Q,R where x.P = x.Q and x.Q = x.R and y.R >= 100;
というか、そもそもprolog自体もデータベースなんですけどね。
>>726 もちろんできる。
ただ、SQLに変換しなくてはならないとすると、あまり旨味がない。
この方面の課題とか考えでところについては、このスレでも何度もでてきた。
SQLに変換せずにということになると、現在のDBMSの能力の半分位は捨ててと
いうことになるが、MySQLやPostgreSQLのSQL解析の部分をそっくりPrologの
解析に取り替えてしまうという方法がある。やるならそこだが、Prologの表現に
できるだけ制約を加えたくないし、そうすると遅延評価の問題とか、探索木が
大きくなった場合とか、データベースの高速の探索アルゴリズムに変換することは
易しくはないと思う。
それより、今なすべきことは、Prologをオンメモリデータベースとして実用に耐える
水準に引き上げることだと思う。これができて使い込まれればPrologインターフェイスの
展望が開けてくる。
つーか、prologって外延データベースじゃないの?
>>729 少し前にでてきた、単位節プログラミングがそれに当たると思う。
ただこれは、メソッド・作法であって、Prologを生かすなら、
外延的に物事を集合として記述するのが効果的で面白いということだ。
仕様から必然的にこうならざるを得ないという訳ではない。
内包的な演繹データベースとしてもSQLと同等以上に強力である。
datalogの話でもしますか。 というより、現行のprolog処理系はまず日本語処理をなんとか しないと駄目だろう。
732 :
デフォルトの名無しさん :2008/12/21(日) 00:39:01
学校の課題なのですが、 [a,f,s,a,5]のなかにaはいくつ含まれているかカウントするprologを作成せよという問題がさっぱりわかりません。 counta(L,C):- L=a, k+1, C is k. これであっているのでしょうか。 もしよかったら参考になりそうなサイトとかあったら教えてください。
…何ていうか、根本的に勉強し直したほうがいいと思うよ。 教科書最初から読み直すとか。
>>733 counta([],[]).
counta([a|R],[a|R1]) :- counta(R,R1).
counta([_|R],X) :- counta(R,X).
または、
counta([],0).
counta([a|R],s(S)) :- counta(R,S).
counta([_|R],S) :- counta(R,S).
何が起こるのかやってみてください。
これらを提出してこれが答えだと強弁したら、
先生、君に一目置くかも。
まあ、無視される答えに作り換えてください。
>>732 ・変数は アルファベットの大文字から始まるか _ から始まる文字のならびでなくてはなりません。
・それからリストですが [a|R]の意味は先頭要素がaで残り(R)要素があります。
ただし残り要素は場合によると空([])かも知れません。そんな意味です。
[A|R] は先頭要素が変数(今のところ何が来るのか分からない)で残り(R)要素のあるリスト。
残り要素が空の可能性があることは同じです。
・Prologではリストの残りはという時は | の後にRのような変数を書きます。
変数であればRとは限りません。
・[_|R] の _ も一応変数です。これは無名変数といって、この要素は他の部分では使わないよ、
と宣言していると考えましょう。
今回はここまで。
みなさま、ご指導ありがとうございます。 悪戦苦闘しましたが、いちおうこんな感じでできました counta(L,N) :- findall(a,member(a,L),La), length(La,N).
>>736 それは書きなおして提出した方が良いと思いますよ。
組み込み述語に頼らないで再帰を使ってというのが
宿題の趣旨だと思いますよ。
そうそう。 is/2等の組み込み述語を使わずにいかに加算を実現するかがポイント。 peano数表現で求めた後、10進表現に直すところが難関だ。
>>731 ,739
何を指して問題と言うのかな?批判したいだけなんだろ。
大半の処理系で文字列として日本語は扱えるし、
日本で開発された K-Prolog あたりなら文字単位(全角/半角)の処理もできていたはず。
文節単位の処理は形態要素分析の世界だから Prolog 処理系の課題からは外れるし。
それとも日本語でプログラミングしたいのかな?こんな感じで(w
人(ソクラテス).
死ぬ(X) :- 人(X).
?- 死ぬ(ソクラテス).
> 日本で開発された K-Prolog あたりなら文字単位(全角/半角)の処理もできていたはず。 裏返せば、大半の処理系は出来てないわけですね。 swi-prologはどうだっけ?
>>741 SWI-Prologは、
全然問題ない。まてよ、Windows版は問題があったかな。
全角文字だけで、プログラミングしたいと思う人は少ないようだ。 死ぬ(X):− 人(X). ?− 死ぬ(ソクラテス). K-Prologはこれができていたはず。こういう意味での漢字処理の完全性から Kを冠した。
エディタの便利機能が全然効かなくなるからなあ
先に書いたフラットな単位節を基本とするなら、Python風にインデントして、 死ぬ(X) :- 人(X). 人(ソクラテス). 人(アリストテレス). は 死ぬ X 人 X 人 ソクラテス 人 アリストテレス というsyntaxから上記のProlog表現を起こすプリプロセッサを 被せるのが有力。複合項の表現が多くなると効果が薄れるから、 フラットであることが特に重要。
swi-prolog 5.4.7 (win)で日本語を試してみた。 p.pl a('日本語'). というfileを用意(SJIS)。 24 ?- [p]. % p compiled 0.00 sec, 0 bytes Yes 25 ?- a(X). X = '\223\\226\{\214\・ Yes UTF-8にしてみたが同様。 これは駄目ですね。
日本語処理に関しては、IF/Prologの国内販売が中止になったのが痛い。 30万円台の、今日的には高価な製品だったが、企業で実務に利用するには 十分のものだった。ドイツ版は入手できるが、日本語の部分は削ってあるようだ。 SWI-Prologも5.6.14というバージョンのUbuntu(Gnu?)パッケージだと、 変数名まで完全に日本語が使える。もちろんアトムをシングルクォーツで 囲む必要もない。
Prologについて日本語情報としてその全容が示されたのは、 中島秀之氏の1978年の情報処理の論文や1982年4-6月のbit誌での解説では ないかと思っていたのですが、本棚の底から久しぶりに顔をだした、 『人工知能』 岩波講座情報科学-22 の奥附を見てびっくり。私は1984年の 第二刷を購読したのだが、第一刷は、1982年4月9日とある。 この本のPrologの解説はなかなかのもので、雑誌を除くとこの本が最初の 言及なのかも知れない。以前間違った事を書いたと思うので訂正。
>>749 中島先生のLispで書かれたProlog処理系を動かそうと苦心していたことを
思い出しました。1982年に連載されたものはバックナンバーが入手できず
残念だったのですが、何年か前に知人のご厚意によりコピーをいただくことが
できました。
あー。 あのシリーズを個人で購読した人いるんだ凄いなー。 (神保町の古本屋でセットで買った)。 ハードカバーがカーキ色と青色があるのは、第一刷と第二刷だったのか。
>>746 X 人
X 死ぬ
ソクラテス 人
アリストテレス 人
の方がよくないか?
まちがえた X 人 X 死ぬ ソクラテス 人 アリストテレス 人 だった。ホーン節が生きないか。
COBOLのようだw
それと引数が20以上にもなると辛いこととなる。 好ましくないとはいっても、ビジネスでは時々ある。
[] X X append X Y Z append [U|X] Y [U|Z] append やはりこれが究極のProlog仕様か。
>>759 ウラジオストックから日本海を眺めてるようだ。
>>759 Schemeで簡単にできた。究極のProlog仕様?
(appende `(い ろ) `(は に) r)
=> (((い ろ) (は に) (い ろ は に)))
(appende a b `(い ろ は に))
=> ((() (い ろ は に) (い ろ は に)) ((い) (ろ は に) (い ろ は に)) ((い ろ) (は に) (い ろ は に)) ((い ろ は) (に) (い ろ は に)) ((い ろ は に) () (い ろ は に)))
http://codepad.org/1lbqvsBH
762 :
デフォルトの名無しさん :2008/12/27(土) 19:04:11
デフォルトで並列処理を行うProlog処理系ある?
>>759 このくらいシンプルだとちょっと構文規則を変えれば、
|| _ _ .
__ ___ ____ .
_____|__ ___ _____|____ .
Esotericな言語 Loran のできあがり。
第一節まちがえた。これだと無名変数になってしまう。 || __ __ . __ ___ ____ . _____|__ ___ _____|____ .
Epilogなんてのもあったな 啓学出版から訳本が出てた
>>767 Epilogはバックトラックする仕様だった記憶がある。実際に動いているのを
見たことはないけれど。
Concurrent PrologやGHC/KL1はしない。上田和紀氏はずっとGHC上での
全解探索を研究テーマにしていた。
私は全然知らないのですが、Parlogはどうなんですか?
そんな昔からGlasgow Haskell Compilerがあったのか・・・・ GHCはICFPの人気言語第一位!
>>768 の GHC は Guarded Horn Clauses だろJK
>>770 エジンバラ大だったらにICOTに敬意を表してGHCなどという名前、付けないよね。
そうか、EHCにしかならないかw
グラスゴー大とエジンバラ大はやはりライバル関係にあるの?
>>771 1987年頃にはPC98で動く逐次型GHCが商品になっていた。
プロログほど今のマルチコアを使いこなせる言語もないだろうに・・・
erlang
>>774 GHCをErlangで書いたらとからおもしろいことが沢山ありそうですが、
なぜ関数型に化けなくてはならないのかな。
KL1ってWindowsで使えるの?
使えない。
Javaの実装系使えば並列しほうだいだぜ!!
>>778 CafeなどJava系Prologは見込みがあるということかい。
KLICについて。 私のところではRedhat9(5~6年前)では心地よく動いていたのだが、 その後OSも変わり、カーネルバージョンも上がったところ、 makeが通らなくなった。私の知識ではどうしようもなく、 KLICを使うためにわざわざUbuntuに代えて、Gnuパッケージで 動かしている。しかし、ソースがいじれないと実用にはならない ので、なんとかしたい。どなたか、makeがうまくいっている方、 環境と方法を教えてください。
Ubuntu 版のパッケージが動いてるなら、 Ubuntu 版のソース落とせばいいじゃない。 Ubuntu は Debian 系だから、各パッケージのビルドに必要な環境も簡単に整備できるようになってるはずだけど。
とりあえず2.002をubuntu 8.04でコンパイルしてみた Configure ! ( locate_file libsocket.a f $LIBPATH || locate_file libsocket.so f $LIBPATH ) \ include/klic/options.h l.21 ! //extern Const struct opttable *opttable; vi runtime/trace.c ! //extern char *calloc(); vi runtime/debug-d.c ! // extern char *sys_errlist[]; こんな感じでコンパイルできた。 cd test; make すると parsetest が double free or corruption で落ちますなあ。 後は問題なし。
JanによるJavascriptで書かれたPrologインタプリタが本格化してきた。
http://ioctl.org/logic/prolog1 私も少し前の版からbuiltinを拡張したり、ユーザ定義述語を増やしたりして、
最近は実務にも使っている。<div>タグとPrologインタプリタのjsファイルだけを
持ったスケルトンのHTMLを受け取ったクライアントブラウザがスタイルシートに
あたるそのWeb画面固有のstart_prolog.jsをサーバ側から呼び出して、動的に
ブラウザを再表示する。サーバ側でPrologがHTMLを生成して参照させるのと
どちらが有利かは微妙だが、Prolog埋め込みHTMLを作成するのは案外と
面倒。必要な箇所だけPrologの副目標として指示できるこの方法は評価に価する。
3.003(本家)もやってみた。同様の修正に加えて、 runtime/rmon_server.c > exit() < exit(1) したら問題なし。testも通る。ただしどちらも共有メモリなし。 config.sh DEF_SHMSYSTEM='yes' にすると、include/klic/shm_machine.h の n_lock マクロで、 asm文関係のエラー、lvalue でないものに代入している、になる。 DEF_PARALLEL='yes' DEF_DISTSYSTEM='yes' DEF_PVMLIB='pvm3' とした以外は default 。これは2.002も同じ。
785 :
783 :2009/01/04(日) 11:52:51
少々言葉足らずのところが。 >Prolog埋め込みHTMLを作成するのは案外と面倒。 とは、eRubyなどでやっているように、予めHTMLを 作っておいてその中に埋め込まれたPrologQueryを 基に表示を追加していく。*.phtml を *.htmlに 変換するこの処理をPrologが担うケースの事。 普通は、write('<html>\n'), ... ,write('</head>\n'), の間の ... の部分に表示副目標がくる。つまりPrologが HTMLファイルを一気に書き上げる。
>>783 IEユーザがPrologを使わせられている図を考えると痛快だね。
788 :
デフォルトの名無しさん :2009/01/05(月) 13:33:23
progolの質問って、ここでいいんでしょうか? 以下のプログラムでgeneraliseに失敗するんですが、何故だかわかりません。 モード宣言が無いからでしょうか? どなたか詳しい方、教えてください。 環境は、CProgol Version 5.0です。 grandfather(paul,john). grandfather(paul,tod). grandfather(brian,john). grandfather(brian,tod). :-grandfather(john,paul). :-grandfather(tom,john). :-grandfather(sarah,john). father(paul,tom). mother(sarah,tom). father(tom,john). father(tom,tod). father(brian,amy). mother(amy,john). mother(amy,tod). parent(A,B) :- father(A,B). parent(A,B) :- mother(A,B). generalise(grandfather/2)? 結果 |- no [:- generalise(grandfather/2)? - Time taken 0.00s]
789 :
デフォルトの名無しさん :2009/01/05(月) 13:47:56
×progol ○prolog
790 :
788 :2009/01/05(月) 23:44:52
prologのスレというのは承知の上なんですが、 さすがにprogolのスレは無いみたいで…。 ココが一番ちかいかな、と。 すいません、お願いします。
791 :
デフォルトの名無しさん :2009/01/05(月) 23:51:32
>progol 帰納論理プログラミングですね。
Progol大歓迎。久しぶり使ってみた。 grandfather(A,B) :- parent(A,C),parent(C,B). を導きたいと思ったのだけど、 [Generalising grandfather(paul,john).] [No mode declaration for example grandfather(paul,john).] ....... grandfather(paul,john). grandfather(paul,tod). grandfather(brian,john). grandfather(brian,tod). しか出てこないな。
モード宣言をごっそり入れたら、以下のようなものも生成してくれた。 なにしろ出力が多すぎて訳が分からない・・・ grandfather(A,B) :- father(A,C), father(D,E), father(E,F), father(G, H), mother(H,F), mother(I,E), parent(A,C), parent(C,B), parent(D,E), parent(E,F), parent(G,H), parent(H,F), parent(I,E). [0 explored search nodes] f=-10100,p=3,n=3,h=10000 [No compression] grandfather(A,B) :- father(A,C), parent(C,B).
モード宣言は以下の通り。 modeh(*,grandfather(+atomid,-atomid))? modeh(*,grandfather(-atomid,+atomid))? modeb(1,father(+atomid,-atomid))? modeb(1,father(-atomid,+atomid))? modeb(1,father(+atomid,+atomid))? modeb(1,father(-atomid,-atomid))? modeb(1,mother(+atomid,-atomid))? modeb(1,mother(-atomid,+atomid))? modeb(1,mother(+atomid,+atomid))? modeb(1,mother(-atomid,-atomid))? modeb(2,parent(+atomid,-atomid))? modeb(2,parent(-atomid,+atomid))? modeb(2,parent(+atomid,+atomid))? modeb(2,parent(-atomid,-atomid))?
これで大分絞られて来た。
grandfather(A,B) :- father(A,C), mother(D,C), parent(A,C), parent(C,B). こういうのを抑制するにはどうすればいいのか。
>>796 一応、prototype.js系は使っている。組み込み述語の中のかなり多くが、
これに依存している。好ましいことではないかも知れない。
Javascriptを全く意識せずそれ以上の事をするためには何が必要か、
という研究なのだが、Ajaxの一翼を担うとなると、もう少し本格的な
Prologが必要だろう。300要素くらいのリストの再帰でスクリプトエラー
になるのでは困る。
別に困らねーしw
Prologで書かれたソースからJavascriptのコードを吐くコンパイラを作ればおk
Prologで書かれたPrologコンパイラね。 P#はC#を吐き出すね。PrologCafe上でコンパイル処理を行う。
>>801 AZ-PrologもCのソースを生成している。変換プログラムは
元々はPrologだと思う。
例えば、 scalaでprplogを組んだら、最終的にはJavaコードが生成されるのか? それはそれで、よさげだな
それはどういうコードを書くかによる。
805 :
788 :2009/01/08(木) 00:03:51
>794 ありがとうございます。 794のモード宣言を加えたら、なんとか求めたい答えが出ました。 でもなんか793の出力とちがいますね。 モード宣言無しだと全く動かないのはなぜなんでしょうか? これだけの量の宣言を入れないといけないのは使いづらいですね… [48 explored search nodes] f=2,p=5,n=0,h=0 [Result of search is] grandfather(A,B) :- father(A,C), parent(C,B). [Result of search is] grandfather(A,B) :- father(A,C), parent(C,B). [4 redundant clauses retracted from grandfather/2] grandfather(A,B) :- father(A,C), parent(C,B). [Total number of clauses = 1] yes [:- generalise(grandfather/2)? - Time taken 0.04s]
ごめん。私のも
>>805 に同じだ。
>>793 は最初にmodebの
第一引数を*にしてみた時のもの。
このスレで単位節プログラミングが強調されているけれど、
現場で問題を
>>788 のように最小単位にフォーカスする。
それで、それを読んだ人間が帰納推論=学習・理解する。
単位節プログラムはこのような学習・理解を促す材料と
して相応しい形式だということです。
Prolog上でsolveとかreduceという述語を定義して、 Prologインタプリタを動かしている人が多いと思うの だけれど、副目標に対応する定義述語がなかった場合 どうしている? failにする、エラーとしてexceptionの 対象とする、ただwriteする、あるいはgoogleを参照に 行くっていうのもあるだろう。論理プログラミングを 逸脱するから、標準を定めるとかいう問題ではないの だろうけれど、皆さんのアイデアを訊きたい。
私の場合は、定義述語prolog_mode/1が prolog_mode(script) の場合はそのまま標準出力に書く。 prolog_mode(prolog) の場合はfail。 prolog_mode/1が未定義の場合はexceptionが発生します。 インタプリタのトップレベルでは無条件にgoogle参照。 ですね。
>>807 それに関連していうと、
?- X = 'abc
def
ghi'.
がエラーになるの何とかならないかな。
あれ、SWI-Prologだと X = 'abc\ndef\nghi' となるよ。
gprolog IF/Prolog PrologCafe などではエラーとなる。
SICStus とか Bin といった大物は何故か動かなくなってしまった。 ライセンスが切れたのかな。
>>809 がOKならスクリプト言語として相当に強力だね。
>>814 そうではない。
foo1(A),
foo2(B),
...,
'$1 とか $2 といった大物は何故か動かなくなってしまった。
ライセンスが切れたのかな。'([A,B]),
...,
が通らないと使い物にならないだろう。
prolog, や start_program, program, はprologの述語としてありうるから、危険かも知れない。 スクリプト表記は二行以上にまたがった場合とすれば、 いいのかも知れない。二行以上にまたがった関数名を 持つ述語を定義してる人はさすがにいないだろう。
それと、ここのところの流れだけど、 PrologでPrologインタプリタ書いておいて、parserだけは 処理系にお任せというのは横着と言われても仕方ないか。
>>818 Prologの最得意分野だからね。Cに較べて速くないということは
あるけれど。
parser generatorの入力言語(BNF + 属性計算)と比べると、 prologは文法記述が手続き的になる(実行順序を意識して書く必要がある) という問題があり、余り得意という気がしない。
>>820 ライブラリに依存せず、細部までアセンブラ的にPrologで
記述する現在のPrologのプログラミングスタイルだと、
語彙の切り出し部分は手続的に見える処理を含むだろう。
とはいえ、基本的には一体に非決定性のappendのパターンで書ける。
その「基本的」に左再帰は入ってるの?
項(A,R) :- 項(A,R1), ・・・(R1,R). は「含ませない」ですね。
>>823 最適分野の意味は、左再帰を使わずかつ小規模な言語解析の
クラスという意味かな?
825 :
823 :2009/01/10(土) 09:37:21
>>783 遅レスで恐縮だが、要するにこれで、何をやりたいの?
知識処理したいんじゃね?
>>826 >>827 末尾再帰の最適化もなしでは知識処理は荷が重いなw
Prolog-KABAクラスのものなら大変おもしろいことになるのですが・・。
一言でいうなら、AjaxをPrologで制御したいということになります。
サーバー側からの情報のPushとか、ブラウザ実行中にFormやタグの
内容をサーバー側から書き換えるとか、これまでサーバーで処理して
いたXMLファイルの情報解析をクライアントのブラウザで行うなどが、
すべてPrologのみで実行できるようになります。
「集合知プログラミング」っていう本があります。Toby Segaran著當山仁健、鴫澤眞夫共訳 オライリー・ジャパンが発行しています。この本、アルゴリズムの部分がPythonで書かれて いて、ループばかりで読み難くて仕方ない。誰か、Prologで書き直してくださいませんか。
>>828 XMLの扱いについて詳しくないので質問です。
<xsl:template > </xsl:template>の中に埋め込まれた
<html> </html> のなかに更にJavascriptを埋め込む
ことはできるのだろうと思いますが、ここから、xmlの
データ構造を直接アクセスする方法があるのですか。
私の知る限り、<html> </html>の範囲内のタグに限る
ように思うのですが。
>>831 XSLファイルにPrologインタプリタを持つ使い方はまだしていなかったので
よくわかりません。この方法だとhtmlのformにXMLデータをコピーできないか
ということになる。
<input name="data" type="text" value=<xsl:apply-templates select="人事" /> />
などと書きたいところだけどvalue=の右項は"..." でないとエラーになるでしょうね。
いい方法があるのかな?
>>831 xslの要素にはアクセスできると思います。html範囲外でも。
つまり、<html>...</html>があろうがなかろうが、XSLファイルの中の どこにでもJavascriptを書くことができるということか。
>>829 経路問題を扱った少女小説! あれも、ついでに頼む。
836 :
834 :2009/01/16(金) 19:24:29
サーバー側で使っているXML-PrologTermの変換述語はこのTiny-Prologでは 重すぎてうまく動きませんでした。それで次善の策として、JKLというAjax ライブラリを使って組み込み述語を作ることにします。 parseXML( )メソッドを使って、連想配列にXML構造を取り込み、それを htmlの要素にコピーすれば簡単にアクセスできます。XMLの構造を予め知って いる場合、つまりPathが通っている場合ですね、にはそれでデータを取得でき ますが、Prologのfunctor/3のようにこの連想配列を解析して、XMLの構造を Prologの項として再構成して引数にunifyする事はできていません。 オブジェクトのプロパティに関して知識がない場合ですね。
このスレってプログラムソースが沢山載ってるところが魅力なんですが、 このところお話ばかりで書き込まれませんね。
( ゚д゚)ポカーン
「含意 (implication) A ⊃ B (A → B, A ⇒ B). …意味…A ならば B. 」 という記述を見かけたのですが、A ⊂ B (A → B, A ⇒ B) の間違い ではないでしょうか? A ⊂ B だと意味が分かるのですが、 A ⊃ B が A ⇒ B に対応するのだとすると意味が分かりません。 今のところの自分の解釈は次のような物です: ベン図で書くと、A ⊃ B は、大きな円Aの中に小さな円Bが含まれている 状態です。すると、Bに入っている元は、必ずAに入っている、と言うことが 言えるので、B ⇒ A は言えますが、A ⇒ B は言えません。
>>839 > Bに入っている元は、必ずAに入っている、
これがAならばB。
A(x)を、x∈Aな時trueな述語とすると、
A(x)→B(x)
>> Bに入っている元は、必ずAに入っている、 >これがAならばB。 ええ!? BならばAでしょ!?
843 :
デフォルトの名無しさん :2009/01/24(土) 09:59:32
age
>>839 非常に紛らわしいが論理学でそういう書き方をすることがある
阿呆じゃのうと思うけど仕方ないね
集合なのか論理なのか紛れることはないだろうから問題ないと言えばない まあ初めて見る人は戸惑うよね
>>841 1, 2, 3, 4, 5 を全て同時に満たす集合を A
1, 2, 3 を全て同時に満たす集合を B
とすると
A ならば B
A ⊃ B
ということじゃない?
B ⊃ A に見えるが・・・
x>2 ⊃ x>1 {x| x>2} ⊂ {x| x>1}
外苑でなく内包で考えればいい。 内包的記述の量で。
>>839 その記号法はペアノに由来します。ペアノは現代的な論理式の表記法を
最初に発明した人なんだけど、そのペアノが書いた1889年のラテン語の論文
"Arithmetices principia, nova methodo exposita"
では、
B is a consequence of the proposition A
BはAの帰結である
という関係を、
B C A
と表記してました。Cはconsequence(を表わすラテン語の単語)の頭文字です。
そこから自然に、その反対の関係、すなわち、
A deduces the proposition B
AはBを導出する(つまり、AならばB)
を表わす記号として、Cをひっくり返した記号が導入されました。で、そのペアノ
の影響を強く受けたのがラッセルです。ラッセルはペアノの表記法を参考に、
ひっくり返ったCを平べったくつぶした記号、すなわち「⊃」を含意記号として
採用したわけです。この記号法はPrincipia Mathematicaで使われたため、
論理学者のあいだで一気に広まり、たとえばチャーチなんかも教科書では
この表記法を採用してます。
このペアノに由来する表記法は、現代的な集合論の記号法が定着するより
前に出来たもので、集合論での記号法とは区別して考える必要があります。
論理学でこの記号がでてきたときには、とりあえずは集合論的な意味は切り離して
考えるようにしてください。
へー、勉強になった。 どっかで一度こういう点整理した方がいいと思うけど 慣れちゃってる人達は必要性感じないのかな。
>>851 まあ、文脈的に混乱することもあまりないでしょうから、知ってる人は整理する必要性
を感じないのかもしれませんね。でも、ネット上では
>>839 氏のような混乱をたまに
みかけますね。
ちなみに、19世紀末から20世紀初頭にかけてはもっと紛らわしい状況があったようで、
ペアノやラッセルなんかは、
MはNの部分集合である
という関係を表わすのに、現在とは逆向きの記号、すなわち
M ⊃ N
を使ってたらしいんですね。そしてこれは、いったん含意に「⊃」を使うと決めてしまえば、あとは
∀x(x∈M ⊃ x∈N)
という関係から自然に導かれる記号法でもあります。現在ではもちろんこれは
M ⊂ N
と書くわけですが、このペアノとは逆向きに開いた記号は、ペアノと同時代のシュレーダーに
由来するものらしいです。
(正確には「⊂」じゃなくて、「⊂」の上に「=」を重ねたような、現在では使われない記号です。)
そして、このシュレーダーの記号法はツェルメロによって採用され、その後、集合論の世界では
ツェルメロの学派が主流になったので、現在ではペアノ流の記号法は(集合論の世界では)
廃れてしまっているというわけです。
表示されるものと意味内容を区別するのは、全ての 表示されるものに意味内容があるわけではないからかな。
>>850 知らなかった。素晴らしい解説をありがとう
2chもたまにはいいことあるネ
昔はこういうレベルの人が2chにたくさんいたんだよ
>>842 この手の議論にウィキペディアを根拠として持ち出すのは、まずいよ
(みんなスルーしてるけど)
wikipedia持ち出すのに,なぜ,まずいのか 説明できる? オープンソースだから? だれかの思想が混じっている可能性があるから? それとも過去の個人的な経験から? その辺書かないとただのバカ
説明できないことにしておいて
「ならば」に「⊃」を使う記法を初めて見たのは通俗書で 元はサイエンティフィック・アメリカンの記事だったようだが 特に説明もなかった記憶があるな
漏れは「情報科学における論理」
一般教養の論理学で見たが 「含意ってことかい」って感じで誰も気にしなかった スマリヤンも⊃使ってるな 信用ないってのは悲しいねw 真と偽のどちらを1にするかも本によって違うから そちらで混乱する人もいそうだな
WikipediaのPrologの項を読んでみると、 誰のために書いてあるのかが疑問になる。 論理学に精通している人にはPrologとは 何なのかが判る説明になっているのかも しれないが。少なくとも、 「括弧でグループ分けをするLISP」のような 難解な表現は避けるべきだと思う。
>>863 Schemeのそれなどに較べればマシな方かも。
ハッスルしちゃってる人が書くのがwikipediaなんで。
>>863 英語版に較べてお粗末過ぎる。書き潰してしまうか。
なんで Prolog の人ってソクラテスが好きなの?死ぬの?
>>868 実は出典知らない。
>死ぬの? ヨーロッパ人にとって死とは絶対の証であって、忌み嫌う対象では
ないと犬養道子が書いていた。十代に読んだ随筆がトラウマのような状態に
なっていて、すぐこのことを思い出してしまう。
http://mtlab.ecn.fpu.ac.jp/turing_ihon.html > もっとも、ソクラテスの名前があるといかにもアリストテレスが言いそうだなと
> 思ったりするんですが、アリストテレス本人はソクラテスといった固有名は三段論法には
> 含めないことにしてたみたいです。つまり、このソクラテス云々って例は、後の世の人が、
> 三段論法に固有名詞も含めちゃうことにしちゃって、それから作られて広まったもんみたいです。
へえ
>>869 犬養道子の「お嬢様放浪記」や北杜夫の「どくとるマンボウ航海記」を
愛読していた少女達は今何才くらいなんだろう?
>>872 65才くらいw
実は
>>869 の十代のトラウマ云々は嘘で、私が犬養道子を読んだのは
22-3才になってから。「お嬢さん・・・」もその頃まとめて読んだ。
875 :
デフォルトの名無しさん :2009/02/06(金) 10:30:07
デカルト言語っていうのも、このスレで扱いますか?
876 :
デフォルトの名無しさん :2009/02/06(金) 10:52:45
デカッ!
カルテシアンな言語か。 Befungeとか。
なるほど ありがとうございました
>>875 現在のPrologは1995年のISO規格によって簡素な言語仕様の
方向付けがされていますが、この言語のようなものに近くなる
可能性だってあったわけですよ。少なくとも日本はmoduleの
仕様としてICOTのESPを推した。そう考えるとPrologのスレで
Prologを越えたもの(優れているかどうかは別として)を話題と
することは当然でしょう。
Prologだけだと過疎スレなのが現状…… でも論理型言語を全部扱っても 過疎スレ間違いなし!
tracebackとtrackbackを金堂していた
>>863 >1972年ごろにフランスのカルメラウアーとコワルスキーによって考案された。
この一行からして不正確は歴然。
>>883 http://en.wikipedia.org/w/index.php?title=Prolog&oldid=266492716 これか?
> The name Prolog was chosen by Philippe Roussel as an abbreviation for programmation en logique (French for programming in logic).
> It was created around 1972 by Alain Colmerauer with Philippe Roussel, based on Robert Kowalski's procedural interpretation of Horn clauses.
> It was motivated in part by the desire to reconcile the use of logic as a declarative knowledge representation language
> with the procedural representation of knowledge that was popular in North America in the late 1960s and early 1970s.
コルメライワがProlog成立当時の事情を書いた論文の紹介が 前スレにあった。1980年代中頃のものだったと思う。 その内容はその数年前に来日してICOTのメンバーに話した 内容と微妙に食い違っているという話を聞いたことがある。
時系列的にも古い口頭の対話を重視するわけにいかんわな。
これまでの「常識」ではカルメラウアーのアイデアに対してコワルスキーが 示唆を与えたということになっている。この常識を覆すなら、文献リストを 示すか両者の関係を暗示する表現が必要だろう。 それと書き手は誰もがコワルスキーのことは知っているが、カルメラウアーに ついては知らないという思い込みがあるようだ。そうでないとコワルスキーが フランス人になってしまうw
論理型言語で今でも実用レベルで使われている言語ってありますか?
Colmerauerの PROLOG AND INFINITE TREES にはこう書かれている。 Prolog is a programming language that has been developed in Marseille, mainly by Roussel and Colmerauer in (Battani,1973; Colmerauer et al. 1973; Roussel, 1975). The name "Prolog" was given by Roussel for "Pro(gramming) in log(ic)". Originally, it was a theorem prover based on the resolution principle of Robinson(1965), with strong restrictions to reduce the search space: linear proof, unification applying only on the first literal of each clause, etc... Credit is given to van Emden and Kowalski (1976) for having proposed a very simple theoretical model, the Horn clauses, which explains our restrictions and specifies exactly what Prolog tries to compute (minimal Herbrand interpretation).
第一回(1983)の"The Logic Programming Conference"のproceedingsを 譲ってくださる方いないでしょうか。
>>890 Creditっていうのは"謝辞"のことですか?
功名のこと 翻訳するのなら「(略)大変簡潔な理論モデルであるホーン節には、 van EmdenとKowalski(1976)の功績がある」 ちょっと斉藤秀三郎の熟語本位英和辞典を見てみたら、「天晴れ」とあってワロタ
>>891 国会図書館の検索で出てきましたが。。。
蔵書検索で和雑誌新聞にチェックを入れて
タイトルにThe Logic Programming Conference
でそれらしいのがありますが。。。これでしょうか?
>>894 ありがとうございます。
多分それです。私は第一回は参加していないので、どんな冊子かは知りません。
Prologでぐったり
うめ
早すぎだっつーのw
Prologでぽっくり
900 :
863 :2009/02/11(水) 06:12:28
Wikipediaを持ち出したのは、実は
>>858 のレスとするためです(
>>857 >>859 は私ではありませんが)。
この項を読んだ人のうち、少なくとも数千人が、延べ人数的に言うなら
数万人の人が何だか変だなと感じたはずです。しかし、放置された。
私も含めて放置してきた。このことをどう考えればよいのか?
残りの延べ人数にして数十億人が同意してると考えればいいんじゃないかな
>>900 必殺技をわざわざ晒す理由がないからだろう。
あと、うまく言葉にできないというのも大きい。
もしかしたら、若いころならいざ知らず、年取ってしまった今頃に、
そういう観点が存在することを認めちゃうと、発狂しちゃいそうだからかも。
必殺技というのは、全然関係ないことがらの話に自分の思想を 混ぜて、自分の思想にいつの間にか同意させるように仕向ける 技という意味合いね。補足。
何でお前らそんなに日本語不自由なの?
・地道でマメな活動を行う ・情報をまとめることに長け、コミュニティによっては神になれる ・自身のこだわりとコミュニティの方向性が一致しないと荒らしと化す ・いわゆる「自治厨」になりやすい ・粘着行為を行う場合、異常なほど長期間となる ・本人は荒らしていると自覚していない もしくは自分のこだわりこそがコミュニティの為と確信しての犯行 ・時に多くの住人によって叩かれるが、その理由が理解できない ・極端な被害妄想や陰謀論に走りやすい ・他人のレスが上手く読めない、ミスリードが多い ・書き込みも少しおかしいことが多く 日本語が下手だと認識され在日扱いされる ・特徴的なためコテハンをつけなくても住人にバレる ・住人によってあだ名をつけられる
自分の弱点を晒してどうなる。自分はこういうことをされると 傷つく人間なのですよって言ってるだけじゃん。
x【01】こだわりが強い o【02】規則や理屈を重んじる x【03】頑固 o【04】変化を嫌う�� o【05】冗談、比喩、ほのめかし、皮肉などの理解が弱い(マジで受け取るなど)�� o【06】暗黙のルールがわからない�� o【07】自分の好きな話題(いつも同じ話題)に戻っていく�� o【08】雑念にとらわれやすく嫌なことや今、不要な思考を排除できない�� o【09】記憶力の異常 o【10】音に過敏 o【11】感情表現がへた�� x【12】ストレスを受けやすく怒りっぽい x【13】狭い範囲での優れた知識�� o【14】とても論理的で理数系に強いことが多い�� o【15】科目で得意不得意の差が激しい�� o全部【16】宇宙人、変人、ボケのどれか言われたことがある�� ----子供(3歳以上)の頃に現われやすい特徴----�� o【17】分解、組み立てを好む。機械いじりが好き。�� o【18】板、ダンボール、布などで囲いを作り隠れる(遊びでなく)�� o【19】回るモノに強くひかれる(洗濯機、扇風機、モーターなど)�� o【20】自分の空想世界に深く没頭する�� o【21】とても些細なことでもめる(本に折れや指紋をつけると怒るなど)�� x【22】絵など芸術的な才能を持つ者が多い�� o【23】人に触れられるのが苦手 o【24】物を規則的に並べる�� o【25】視線をそらす x【26】オウム返し x【27】物集めが好き�� x【28】形式ばって大人っぽく難しい言葉をよく使う��
いかにも2ch的なのが沸いてきましたw
857=859ですが話が読めませんw
910 :
863 :2009/02/12(木) 08:29:15
もっとも身近な Prolog --wikipedia を引いてみても、 いくつもの疑問点があり、どういう遠慮からか訂正される こともなく、放置されている。そしてこのような「知」が 引用されて蔓延する。文献を自ら渉猟せず、Wikipediaに 頼ることの危険を一例としてあげたつもり。
そういう一般的な警句は他の板でやってくれないか? ここでは電波レスに等しい。
prologとETIってどっちが簡単かな?
>>910 間違っているなら編集すればいいじゃん
それとも集合知はお嫌いなのかしらん?
もしくは確信無く、ただ喚いてるだけなんじゃないの?
[1] 授業単元:Prolog [2] 問題文(含コード&リンク): 1から9までの数字を縦横方向に同じものが並ばないように下記の例のように並べる 並べ方が全部で何通りあるかとその並びをすべて列挙する [3] 環境:特になし [4] 期限: 明日まで [5] その他の制限: 例 534681297 685293714 948367125 153472869 426538971 261759483 817945632 379126548 792814356
>>913 基本的なデザインをしている方はソフトウェアサイエンスの研究者ですね。
多分Plannerを書かれている方でしょう。そういう風に読めます。
私は研究者ではありませんからこの場合は、ちょっと手出しができません。
それにしても、ここ20レスくらいはちゃんと読んでからレスしてよ。
917 :
915 :2009/02/12(木) 17:26:53
失礼しました。
ここ20レスではなく、
>>863 まで遡る必要があるようです。
Wikipediaみたいな粘着がまかり通る世界に書き込もうって人間が 2ちゃんねるのスレに居着くかよ。
まだちょっとよくわからないけど、 「君もPrologのことならわかるでしょう、そのPrologの項目がこの程度でしかなく、 しかもこのスレで晒しても直そうとする人は現れない、そんな情報源なんだよ」 ということ?
?- wikipediaを書く(ソクラテス).
「君も男なら聞き分けたまえ」
>>919 最後の「そんな情報源なんだよ」っていうところは、違うけど。Prologを持ち出したのは
そんなところかな。参考文献や考証の不十分をずっと感じていたから。
もともと珍しく論理学的な話題で、そのなかで
>>857 が一般に文献の考証などが
あまり問われないWikipediaを持ち出すのはマズイといったので、論理学的話題の
事例として Prolog --Wikipedia は格好かなと思った。
結局Prologの例でもそうだと思うのだけど、Wikipediaは善意の書き手が全く知識のない
読者に相当配慮していて、そのため敢えて文献をカットしたり、表現を曖昧にしている
ことも多い。Prologの項もその為だとは思うが、結果としてPrologを知らない人にとっては
逸らかされたような内容になっている。私はそう感じる。
一度Wikipedia批判を始めると表現が少々攻撃的になるのは2chだから仕方ないと 思ってください。
「敢えて」という解釈は新しい
Wikipedia Prologの問題点は、 ・ Prologはなぜ普及しなかったの? というような読み手が一番知りたい情報に対する ヒントが全くないことじゃないかな。
とにかく
>>922 がwikipedia大好き人間であることはわかりました。
>>925 >>884 にリンクがある英語版のWikipediaはよくまとまっていますが、
ご指摘の情報は得られないように思います。
バックトラック時の論理変数の再束縛について触れればよいのでしょうか。
それともスタックの利用法の説明が要りますか?
>>926 結構利用しますよ。
「バンブーアトラスの翌年のダービー馬はなんだっけ?」的な時の
参照が多いですがw
>>925 Prologを全く知らない人はWikipedia折り返しになることが
多いだろうから気になるよね。そういえば以前どこかのスレ
でWikipediaが先頭に出てきたらその言語は死語とみなすと
いう提唱があったのを思い出す。
930 :
929 :2009/02/13(金) 11:37:30
自分にリンクを付けてしまった。
>>928 へのレスでした。
>>927 遅いことがメジャーになり得なかった原因という見解ですね。
>>931 そうです。
でもこの件に関しては私などより、
>>190->200 辺りに書き込まれていた方々の
見解をお聞きしたいですね。
prologの処理系は速いものが結構多かった。以上
以上(笑)
>>929 確かにWikiより上に良いサイトやブログが並べば全然問題ない。
なにしろ興味を持ってくれる人が少ないと最終的には良い人材を
確保できなくなるから。
>>935 でもそれって、Prologはやさしい。何才からでも習得できると言ってることと
矛盾しませんか?
まったりスレに下界の論争を持ち込むなよ。
設問が馬鹿馬鹿しすぎて…
>>936 Prologは、習得そのものは30分くらいで終わる。やさしい。何歳からでもできる。
習得したのを使いこなすのが難しい。
物事の難易度はその最も難しい側面を基準とされるからな。
難しいと言われるLispだって文法は簡単だしね。
群の公理は簡単だが、公理を覚えることを習得とは言わないな
文化人類学者の方が、群を習得してそう。
generatorを生成元じゃなくて母数ってのも珍しいね。 ただこれprolog関係ある?
>>945 でも、何千もある定理は公理から決定的に導出されるモノだから、理屈では公理さえ覚えれば習得完了なんだけどな
お前はガウスか、ニュートンか?
プログラミングする為にも、いびつなモデルを構成するよりも、 あらかじめ存在している構造を抽出したほうが楽だろ。
>>951 それは、「prologプログラミング」であり、「prolog」ではないと思う。
>>951 は
ホーン節 のことを
いおうと
したのでは ないの かな
わしはそう思う
prolog周辺から、prologプログラミングを抜いちゃったら何を話すんだよ。 言語仕様のみ?とにかく、テンプレに追加だな。 このスレにおいてはprologプログラミングについては話さない。
敵の多い人ですねわかります
「The Book に書かれている証明はもっとエレガントなハズだ」 Paul Erdoes
959 :
デフォルトの名無しさん :2009/02/19(木) 22:12:24
Prologに興味あるんですけど、これって何に使えるんですかね? 日常生活とか、仕事とかで役立ちますか? まあプログラミング言語だから、やろうと思えば他の言語と似たようなことができるんだろうけど、 perlとかrubyとか他のでやったほうが速いような仕事は抜きとして、 Prologだからこそ、こういうのに役立つっての。
>>961 つまりPrologっていうのはオンメモリデータベースでもある。未完の。
963 :
959 :2009/02/19(木) 23:42:06
>>959 手元にあるアーカイブという雑誌の9号(1988年9月)がProlog特集なんだけど
その冒頭の記事から引用。詳細は分からないけど、よさげに思えてくる
--------------
筆者の勤務する(株)アイザックでも一昨年の秋に住宅の設計、生産に関する
実用システムをK-Prologを用いて開発しました。現在も継続的に積水化学工業の
セキスイハイムの工場で実務に利用されており、住宅の新製品に対応して
システムも成長を続け、現在延べ8万行ほどのシステムとなっています。
(中略)
こうなるとPrologの持つ論理型言語としての特質はしだいに薄くなり、
むしろプログラムの生産性が高いとか、記号操作が容易であるとか、
自然と構造化プログラミング風に書けるとか、高階プログラミングに
よってプログラムをデータ化してプログラムの保守性を上げるというような、
本来Prologに期待していたこととは別の側面がクローズアップされてきます。
>>963 典型的なデータベースとそれを利用する述語の例。
メールアドレス(2,'渡辺','
[email protected] ').
メールアドレス(2,'坂田','
[email protected] ').
メールアドレス(2,'坂田','
[email protected] ').
メールアドレス(1,'村山','
[email protected] ').
メールアドレス(1,'佐藤','
[email protected] ').
連絡(_クラス,_部員名,_サブジェクト,_文) :-
メールアドレス(_クラス,_部員名,_メールアドレス),
smtp('
[email protected] ',_メールアドレス,_サブジェクト,_文).
連絡網(_クラス,_文) :-
連絡(_クラス,_,連絡網です,_文),
fail.
連絡網(_,_).
連絡網(_文) :-
連絡(_,_,連絡網です,_文),
fail.
連絡網(_).
% 坂田くんには携帯とパソコンの双方にメールします。
問題 >965のプログラムを、1人に複数メールすることがないように書き換えなさい
つい1週間ほど前からprologに興味をもち、勉強しています。
今のところサザエさんの先祖を問い合わせができる程度なんですけど、
>>960 さんの例題のようなことをどうやって記述したらいいのかまだ思いつきません。
ご指導お願いできませんでしょうか。
>>967 書けるところから行こう! 細かな修正はしなくてはならなくなるが・・
プログラム名(勤務表).
開始時刻(9).
終了時刻(17).
要員('Aya').
要員('Koh').
要員('Sho').
時間単位(1).
最少連続勤務時間(2).
勤務に就くことができない(_要員,_現在の時間) :-
用事(_要員,_現在の時間).
勤務に就くことができない(_要員,_現在の時間) :-
前の時間(_現在の時間,_前の時間),
一人で勤務した(_要員,_前の時間).
用事('Aya',14).
用事('Koh',11).
用事('Koh',14).
用事('Sho',9).
用事('Sho',11).
制限事項となるデータベースはほぼ書けた。 この後は少し数学的なアイデアが必要になるだろう。 組合せ? どうすれば前の時間の勤務状態を調べることができるか? 選んできた勤務状態の候補では矛盾が生じる場合はどうすればよいのか? などなど。
まず、勤務表の枠作りをしなくてはならない。
いちばん一般的な勤務表の生成形式は
勤務表(_勤務表) :- ・・・ . のようなトップレベルの定義がきて、
?- 勤務表(_勤務表).
_勤務表 = [[9,['Aya','Koh']],[10,['Aya','Koh']],[11,['Aya']],[12,['Koh','Sho']]|...]
のようなリストを解として取るものだ。
ここではシンプルな問題なのですべて数え上げて見せるが、時間枠Tには
[T,['Aya']] [T,['Koh']] [T,['Sho']] [T,['Aya','Koh']] [T,['Aya','Sho']] [T,['Koh','Sho']] [T,['Aya','Koh','Sho']]
の組合せを生成する述語を作り、9時台から16時台まで順にこの述語を適用して、
時間枠としての候補を作り
>>968 のデータベースに矛盾する場合はバックトラックしながら、
最終的に無矛盾なリストを再帰的に生成する。
algebraic data typeを使いたい
・ 9時台から16時台までの時間枠の生成
・ 前の時間を参照するから、新たに時間枠を生成する時に
それまで生成してきた勤務表を参照できなくてはならない。
この勤務表を第三引数に生成するとする。
以上を組み込みトップレベルは、
勤務表(X) :-
開始時刻(_開始時刻),
終了時刻(_終了時刻),
_最終時間 is _終了時刻 - 1,
勤務表(_開始時刻,_最終時間,[],X).
となるであろう。第三引数は[]からリストを成長させていくことにする。
最後に四引数の述語、勤務表を定義すればよい。時刻と時間の概念が
錯綜した
>>968 の仕様は最終的に(かつ全面的に)手を入れることとしよう。
あとは
>>971 の
[T,['Aya']] [T,['Koh']] [T,['Sho']] [T,['Aya','Koh']] [T,['Aya','Sho']] [T,['Koh','Sho']] [T,['Aya','Koh','Sho']]
を順に生成する述語を定義すれば、難しいところはほとんど終わりのはずだ。
要員の組合せ生成(_要員ならび,_要員の組) :- length(_要員ならび,_要員数), for(1,N,_要員数), memberr(_要員の組,_要員ならび,N). memberr([A],X,1) :- member(A,X). memberr([A|LA],[A|Y],R) :- R > 1,R1 is R-1,memberr(LA,Y,R1). memberr(A,[_|Y],R) :- R > 1,memberr(A,Y,R). 少しむずかしいですね・・・
for/3が組み込みでない場合は、 memberr(S,E,A,X) :- S =< E,memberr(A,X,S). memberr(S,E,A,X) :- S =< E,S1 is S+1,memberr(S1,E,A,X). memberr([A],X,1) :- member(A,X). memberr([A|LA],[A|Y],R) :- R > 1,R1 is R-1,memberr(LA,Y,R1). memberr(A,[_|Y],R) :- R > 1,memberr(A,Y,R). を定義した上で、 要員の組合せ生成(_要員ならび,_要員の組) :- length(_要員ならび,_要員数), memberr(1,_要員数,_要員の組,_要員ならび).
>>973 に話を戻しますが、このように或る時間枠を生成中に
それより以前の情報と関連が或る場合は、
append(L1,[A|L2],L3) を使えないか?
L1は前の勤務表、Aが今候補生成中の時間枠、L2が後の勤務表、
L3はもちろん勤務表です。L1とL2は再帰的に部分的な勤務表を生成します。
最初にどの時間帯としてAを選択するかにもよりますが、単純に2分点
つまり12時または13時を取ったとしてもこの方が速いかな。
>960 > これはPrologで書くのが一番楽。 Prologで書くとどうしても操作的な側面(SLD導出)を意識せざるを得ないのが煩わしい。 ためしにLPで書いてみた。 set SLOT; set WORKER; param not_on{WORKER,SLOT} default 0; var on{WORKER,SLOT} binary; var on_num{SLOT} ,>=0, integer; s.t. OnNum{t in SLOT}: on_num[t] = sum{p in WORKER} on[p,t]; s.t. R0{t in SLOT}: on_num[t] >= 1; s.t. R1{p in WORKER, t in SLOT}: on[p,t] <= (if(t = 9) then 0 else on[p,t-1]) + (if(t = 16) then 0 else on[p,t+1]); s.t. R2{p in WORKER, t in SLOT}: on[p,t] + (if(t = 16) then 0 else on[p,t+1]) <= on_num[t]; s.t. R3{p in WORKER, t in SLOT}: on[p,t] + not_on[p,t] <= 1; # set SLOT := 9 10 11 12 13 14 15 16; set WORKER := Aya Koh Sho; param not_on := Aya 14 1 Koh 11 1 Koh 14 1 Sho 9 1 Sho 11 1;
>>978 ありがとうございます。私はこの記法知らないのだけれど、結構読めます。
ちょっと全然違う話を書きます。
member/2が実はappend/3だという話。「Prologの技芸」の訳本だとp63、
「Prologへの入門」では、p72、こちらは述語名がappendではなく
concとして出てきます。ここでは、技芸の表現を使います。
member(X,Ys) :- append(As,[X|Xs],Ys).
これを見て、repeat/0だって、
repeat :- append(_,_,_).
でいいじゃないか、とやってみると、大抵の場合スタックオーバーフローに
なるから注意! member/2を使っているとmember/3も使いたくなる。
member(X,[X|R],R).
member(X,[_|Ys],R) :- member(X,Ys,R).
ですね。この有難味は、memberであることを確認した時に、残りのリストを参照できる
ことです。
<<つづきです>> これを使い始めるとメンバーでなかった(ここら辺の意味が曖昧)リストも欲しいと 思うようになる。ただし、メンバーであることを確認した時点では、残りのリストの なかにも、メンバーでない要素はあるかもしれないからmemberという述語名は そろそろ下ろした方がいいかも知れません。ここはmemberで続けると、 member(Us,X,[X|R],R). member(Us,X,[U|Ys],R) :- append(Us,[U],Us2),member(Us2,X,Ys,R). 最近、Prolog学徒と話をしていて、「Prologってmemberですね」ということになった。 そこで「つまり、appendだよ」と言ってみたらキョトンとしていた。それで紙にこんな ことを書きました。
>>979 repeat/0はさすがにだめだけど、forには使えるんだよね。
?- ... ,append(_,_,[_,_,_]), ...
とかやって。
append(X,Y,L), is_ok(L) という感じで、is_okを満たすlistを全生成したくなるときがあるのですが、 is_okを満たすlistは長さN以下であるという類の条件を使って、 それ以上の長さのlistを生成するしかなくなった時点でfailさせる方法は ないでしょうか? append(X,Y,L), length(L,N), N < 100, is_ok(L) などとやってもappendは後ろのことを知らないのでbacktrackしつづけてしまいます。
工学社のProlog本届いた。Prolog知らない俺だけどこれから読みます。 工学社っつーとなんかAPIの説明本ばっかりというイメージで敬遠してたが、 目次みる限り硬派そうだね!
>>982 Nより長いLを作らないappendを書いてください。
>>983 >>984 のいうようにappendに手を入れるか、
以下のような、述語を定義するか。
ap(X,Y,L) :- append(X,Y,L),length(L,N),(N<100,is_ok(L);N>=100,!,fail).
986 :
979 :2009/02/22(日) 12:41:50
なんで突然appendの話を持ち出したかというと、
>>973 でわかりやすくと思って、
9時台から順に勤務表を積み上げていくアプローチを取ったけれど、直感的には
「あ、これはappendだな」と、思ってる訳です。それで、Prologのプログラムは
実はappendだらけという話をした。そしてこれが、
>>978 の
>Prologで書くとどうしても操作的な側面(SLD導出)を意識せざるを得ないのが煩わしい。
へのレスということになるのだと思う。
>>980 member(Us,X,[X|R],R).
member(Us,X,[U|Ys],R) :- append(Us,[U],Us2),member(Us2,X,Ys,R).
は
member(Us,Us,X,[X|R],R).
member(Us1,Us,X,[U|Ys],R) :- append(Us1,[U],Us2),member(Us2,Us,X,Ys,R).
でないといけないのではないかな。
それから左側(第二引数)はmemberでないものではなく、
Xの左側全部だ。したがって、
>>980 の上半分の説明はナンセンス。
988 :
979 :2009/02/22(日) 22:47:17
>>987 あー、そうだ間違えた。これは単に、
member([],X,[X|R],R).
member([U|Us],X,[U|Ys],R) :- member(Us,X,Ys,R).
でいいんじゃないか。訂正します。
>>983 同じ著者に、
「人工知能の基礎理論」2000年 電気書院
「自然言語・意味論・論理」1998年 共立出版があり、
出版社は違うが、これらで三部作を構成していると
考えた方が良さそう。
「AIプログラミング」は突破口。
この本だけ読むといかにも教科書的というか、
参考書的な印象が強いが、三部作だと思って読むと、
それぞれが光彩を放って、そのことが気にならない。
>>988 member(Us,Us,X,[X|R],R).
member(Us1,Us,X,[U|Ys],R) :- append(Us1,[U],Us2),member(Us2,Us,X,Ys,R).
が優れているのは、
member(Us,Us,X,[X|R],R) :- Q.
member(Us1,Us,X,[U|Ys],R) :- append(Us1,[U],Us2),member(Us2,Us,X,Ys,R).
USの参照検査を Q の位置でもできること。もちろん、
>>988 同様に、
?- ... ,member([],Us,X,L,R), ... , Q ,
の位置での検査もできる。
>>978 非決定性というのは必然的に手続的(操作的)なのかな。
member/memberrの話題、それから
>>965 のfailにしても、
外部からの介入を「待っている」感じがあって、やはり、
前と後がある感覚が残る。failは介入を代行しているの
だけれど。
>>965 問題です。
坂田くん、父親が2年生担当のコーチでパソコンを使っています。
一般の連絡網(当人か母親が見る)は携帯に流して欲しい。
1) 普通(1,2年共通)の連絡網ではパソコンと携帯に流れる。
2) 1年生の連絡網の時は全く流れない。
3) 2年生の連絡網の時は携帯とパソコンに流れる。
4) コーチの連絡網の時はパソコンにだけ流れる。
が可能になるように、定義を変更しなさい。
>>993 こういう例題が沢山詰まっているスレ、サイトが欲しいな。
>>994 日本Prolog協会はメーリングリストで運営されてるけど、
ほとんど動いていない。
もう一度、初心者用のサイトやライブラリ蒐集用のサイトを
作り直しますか。
数年前に古本で買ったPrologの冒険でもまた読んでみようかな
>>993 メールアドレス(2,'坂田','
[email protected] ').
メールアドレス(コーチ,'坂田','
[email protected] ').
だと、第一引数を変数で参照された場合(全軍連絡網)はうまくいくけれど、
2年だけの連絡網をながそうとするとコーチには流れない。
メールアドレス(2,'坂田','
[email protected] ').
メールアドレス(コーチ,'坂田','
[email protected] ').
メールアドレス(2,'坂田','
[email protected] ').
だと変数で参照した場合(全軍連絡網)コーチに二回流れてしまう。
メールアドレス(2,'坂田','
[email protected] ').
メールアドレス(_コーチ,'坂田','
[email protected] ') :- _コーチ == コーチ.
メールアドレス(2,'坂田','
[email protected] ').
でよいのであろうか?
>>998 変数で参照することが間違っている。
<略>
メールアドレス('全軍','坂田','
[email protected] ').
メールアドレス('コーチ','坂田','
[email protected] ').
メールアドレス(2,'坂田','
[email protected] ').
<略>
連絡網(_文) :-
連絡('全軍',_,'連絡網です',_文),
fail.
連絡網(_).
でなきゃ。
1000 :
デフォルトの名無しさん :2009/02/25(水) 07:08:40
>>995 とりあえず、Prolog述語 1000 Tipsを目指しましょう。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。