Prolog初心者のスレ
これは良い言語だ…
探検
【論理】Prolog【初心者】
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2010/11/06(土) 13:00:56689デフォルトの名無しさん
2013/09/01(日) 21:56:08.08 >>688
emacsもmeadowもcygwin無しでOKのwindows版あるよ
emacsもmeadowもcygwin無しでOKのwindows版あるよ
690デフォルトの名無しさん
2013/09/01(日) 22:23:09.77 ありがとうございます。試しにMeadow入れてみました。
M-x shellでシェルモードにして、その中でswipl.exeを実行してみましたが、
プロンプトが表示されないなど、満足に動作しませんでした。
M-x shellでシェルモードにして、その中でswipl.exeを実行してみましたが、
プロンプトが表示されないなど、満足に動作しませんでした。
691デフォルトの名無しさん
2013/09/07(土) 16:18:13.90 日本語対応が十分にできるている処理系はありますか?
692デフォルトの名無しさん
2013/09/12(木) 18:45:07.45 Prologで仕様記述できますか?
693デフォルトの名無しさん
2013/09/12(木) 19:42:43.95 >>692
ルールを決めればできるでしょう。
ルールを決めればできるでしょう。
694デフォルトの名無しさん
2013/09/28(土) 12:48:49.81 Prologで2つの値が等しいと(ポインター)アドレスが等しいは区別されていますか?
Lispのeq? equal?の違いみたいなものです
Lispのeq? equal?の違いみたいなものです
695デフォルトの名無しさん
2013/09/28(土) 16:58:44.30696デフォルトの名無しさん
2013/09/30(月) 16:49:29.65 X =:= Y.
697デフォルトの名無しさん
2013/10/02(水) 13:46:42.08 >>692
そこで言ってる仕様記述ってどういう意味のですか?
そこで言ってる仕様記述ってどういう意味のですか?
698デフォルトの名無しさん
2013/10/20(日) 04:46:24.01 PrologにはstalinやMLtonみたいな
超高速コンパイラってありますか?
超高速コンパイラってありますか?
699デフォルトの名無しさん
2013/10/20(日) 17:54:10.52 ICOTでいろいろ量産されてた気がする
700デフォルトの名無しさん
2013/10/21(月) 09:21:25.23 いつのまにかEclipseでPrologが書けるようになってた
便利だ・・・
便利だ・・・
701デフォルトの名無しさん
2013/10/23(水) 10:06:56.32 Prologで常識的には
ある文章の中の名詞なり動詞なりなにを関数にするもんなでしょう?
ある文章の中の名詞なり動詞なりなにを関数にするもんなでしょう?
702デフォルトの名無しさん
2013/10/23(水) 11:23:06.63 >>701
対象となっている、物、事、性質、動作、行為、状態、これらの複合したもの、
文章。何がきてもよいのではないですか。述語論理だから、述語、すなわち、
動詞句や形容詞等が来なくてはならないということはありません。
対象となっている、物、事、性質、動作、行為、状態、これらの複合したもの、
文章。何がきてもよいのではないですか。述語論理だから、述語、すなわち、
動詞句や形容詞等が来なくてはならないということはありません。
703デフォルトの名無しさん
2013/10/23(水) 19:36:57.16704デフォルトの名無しさん
2013/10/24(木) 11:33:03.43705デフォルトの名無しさん
2013/10/27(日) 06:57:07.73 東京キャビネットみたいな
高速で検索できるデータベースの中を
Prologの命題で検索できないのでしょうか
MySQLは,それっぽいのみつけたので
既にあるのかもしれないですが
高速で検索できるデータベースの中を
Prologの命題で検索できないのでしょうか
MySQLは,それっぽいのみつけたので
既にあるのかもしれないですが
706デフォルトの名無しさん
2013/10/27(日) 09:25:23.92 Prologで文法のサイトはよく見るんだが
VSのプロジェクトのような作り方ってPrologできるのん?
VSのプロジェクトのような作り方ってPrologできるのん?
707デフォルトの名無しさん
2013/12/17(火) 10:57:32.78 swi-prologが標準みたいだけど
swi-prologが一番使われてる理由って何故ですか?
swi-prologじゃなくて2番手みたいな処理系ってないのですか?
swi-prologが一番使われてる理由って何故ですか?
swi-prologじゃなくて2番手みたいな処理系ってないのですか?
708デフォルトの名無しさん
2013/12/17(火) 11:59:17.93709デフォルトの名無しさん
2013/12/18(水) 12:46:39.18710デフォルトの名無しさん
2013/12/19(木) 08:47:57.77 PrologをSQLに変換するコンパイラなんてのをみつけた
Prologの構文って全部SQLに変換できるのだろうか
Prologの構文って全部SQLに変換できるのだろうか
711デフォルトの名無しさん
2013/12/20(金) 17:55:44.14 prologは演繹データベースだから、prolog -> SQL は難しい
SQL -> prolog なら大学の演習レベルでもなんとかなると思う
SQL -> prolog なら大学の演習レベルでもなんとかなると思う
712デフォルトの名無しさん
2013/12/20(金) 18:58:22.89 >>711
そうですね。単位節データベースの参照の後に延々とルールが来て、
それでデータベースのフィールド参照のキーが漸く来るなんてことも
有りえます。そういう場合は、selectを参照する条件としてそれらを
型推論的な先読みをしたとしても、拾ってくるのはかなり難しいです。
そうですね。単位節データベースの参照の後に延々とルールが来て、
それでデータベースのフィールド参照のキーが漸く来るなんてことも
有りえます。そういう場合は、selectを参照する条件としてそれらを
型推論的な先読みをしたとしても、拾ってくるのはかなり難しいです。
713デフォルトの名無しさん
2014/02/24(月) 00:48:00.61 RDFのデータベースを検索するSQLの親戚あるけど
あれならPrologと一対一で変換できそう
あれならPrologと一対一で変換できそう
714デフォルトの名無しさん
2014/03/09(日) 15:32:00.41 SWI-Prologを使っているんだけどユニファイ可能な節が1つ以上存在するかを判定する組み込み述語ってある?
今はfindallした結果のリストの長さが0以上かで判定してる…
今はfindallした結果のリストの長さが0以上かで判定してる…
715デフォルトの名無しさん
2014/03/09(日) 16:10:50.90716デフォルトの名無しさん
2014/03/09(日) 18:25:03.73 いい女ぴー?
やらしてくれるぴー?
やらしてくれるぴー?
717デフォルトの名無しさん
2014/03/16(日) 21:00:44.77ID:8VpQ5LoV >>714
ユーザ定義述語であることが条件だが、findall/3とclause/2を使うのが普通だと思う。
ユニファイ可能な節が1つ以上存在するかを判定する(Head) :- findall(_,clause(Head,Body),[_|_]).
ユーザ定義述語であることが条件だが、findall/3とclause/2を使うのが普通だと思う。
ユニファイ可能な節が1つ以上存在するかを判定する(Head) :- findall(_,clause(Head,Body),[_|_]).
718デフォルトの名無しさん
2014/04/09(水) 21:24:27.23ID:i/ZHdrIw >>717
findall/3を使わないと少なくとも幾つあるかはわからない。
findall/3を使わないと少なくとも幾つあるかはわからない。
719デフォルトの名無しさん
2014/06/05(木) 12:16:15.58ID:JLFuk7Df generate(C) :-
random_between(65, 90, I),
atom_char(C, I).
experiment('STAP', Count) :- !,
writef('%w回目で陽性かくにん!¥nよかった☆¥n', [Count]).
experiment(_, Count) :-
generate(S),
generate(T),
generate(A),
generate(P),
atomic_list_concat([S, T, A, P], CELL),
writef('%w細胞', [CELL]),
NextCount is Count + 1,
experiment(CELL, NextCount).
main :-
experiment([], 0).
もっと面白い書き方ないかな?
random_between(65, 90, I),
atom_char(C, I).
experiment('STAP', Count) :- !,
writef('%w回目で陽性かくにん!¥nよかった☆¥n', [Count]).
experiment(_, Count) :-
generate(S),
generate(T),
generate(A),
generate(P),
atomic_list_concat([S, T, A, P], CELL),
writef('%w細胞', [CELL]),
NextCount is Count + 1,
experiment(CELL, NextCount).
main :-
experiment([], 0).
もっと面白い書き方ないかな?
720デフォルトの名無しさん
2014/06/05(木) 19:08:53.35ID:h2Dia7Mk % 特に改善されたという訳ではない。
generate(CELL) :-
findall(A,(
between(1,4,_),
N is random(26),
sub_atom('ABCDEFGHIJKLMNOPQRSTUVWXYZ',N,1,_,A)),
L),
atomic_list_concat(L,CELL).
main :-
nth1(Count,_,_),
generate(CELL),
writef('%w細胞', [CELL]),
CELL = 'STAP',
writef('%w回目で陽性かくにん!\nよかった☆\n', [Count]).
generate(CELL) :-
findall(A,(
between(1,4,_),
N is random(26),
sub_atom('ABCDEFGHIJKLMNOPQRSTUVWXYZ',N,1,_,A)),
L),
atomic_list_concat(L,CELL).
main :-
nth1(Count,_,_),
generate(CELL),
writef('%w細胞', [CELL]),
CELL = 'STAP',
writef('%w回目で陽性かくにん!\nよかった☆\n', [Count]).
721デフォルトの名無しさん
2014/06/05(木) 19:35:36.06ID:h2Dia7Mk722デフォルトの名無しさん
2014/06/05(木) 23:17:35.42ID:awAmNJBx STAP細胞でコードゴルフでもするかね
723デフォルトの名無しさん
2014/06/06(金) 00:01:25.80ID:Ynv3Q/53 g(C):- findall(I,(between(0,3,_),random_between(65,90,I)),C).
e([83,84,65,80],N):-!, format('~w回目で陽性かくにん!¥nよかった☆¥n',[N]).
e(_, N):- g(C), format('~c~c~c~c細胞', C), N1 is N+1, e(C, N1).
main:-e([], 0).
$ wc stap.pl
3 16 233 stap.pl
$ swipl -q -t main -f stap.prolog
ドヤ!
e([83,84,65,80],N):-!, format('~w回目で陽性かくにん!¥nよかった☆¥n',[N]).
e(_, N):- g(C), format('~c~c~c~c細胞', C), N1 is N+1, e(C, N1).
main:-e([], 0).
$ wc stap.pl
3 16 233 stap.pl
$ swipl -q -t main -f stap.prolog
ドヤ!
724デフォルトの名無しさん
2014/06/06(金) 00:03:45.32ID:Ynv3Q/53 g(C):-findall(I,(between(0,3,_),random_between(65,90,I)),C).
e([83,84,65,80],N):-!,format('~w回目で陽性かくにん!¥nよかった☆¥n',[N]).
e(_,N):-g(C),format('~c~c~c~c細胞',C),N1 is N+1,e(C,N1).
main:-e([],0).
$ wc -c stap.pl
223 stap.pl
$ swipl -q -t main -f stap.pl
スペースつめるの忘れてた
e([83,84,65,80],N):-!,format('~w回目で陽性かくにん!¥nよかった☆¥n',[N]).
e(_,N):-g(C),format('~c~c~c~c細胞',C),N1 is N+1,e(C,N1).
main:-e([],0).
$ wc -c stap.pl
223 stap.pl
$ swipl -q -t main -f stap.pl
スペースつめるの忘れてた
725デフォルトの名無しさん
2014/06/06(金) 00:52:39.27ID:Ynv3Q/53 g(C):-findall(I,(between(0,3,_),random(65,91,I)),C).
e([83,84,65,80],N):-!,format('~w回目で陽性かくにん!¥nよかった☆¥n',N).
e(_,N):-g(C),format('~c~c~c~c細胞',C),O is N+1,e(C,O).
m:-e(0,0).
$ wc -c stap.pl
207 stap.pl
swipl -q -t m -f stap.pl
もうだめだ寝る
e([83,84,65,80],N):-!,format('~w回目で陽性かくにん!¥nよかった☆¥n',N).
e(_,N):-g(C),format('~c~c~c~c細胞',C),O is N+1,e(C,O).
m:-e(0,0).
$ wc -c stap.pl
207 stap.pl
swipl -q -t m -f stap.pl
もうだめだ寝る
726片山博文MZ悪魔崇拝 ◆T6xkBnTXz7B0
2014/06/30(月) 22:35:30.71ID:CGk8SAom 古典的な人工知能の研究をしています片山博文MZです。
最近Prologの重要性がわかるようになってきました。
PrologからC言語の関数を呼ぶ方法と、C言語からPrologを扱う方法を教えて下さい。
最近Prologの重要性がわかるようになってきました。
PrologからC言語の関数を呼ぶ方法と、C言語からPrologを扱う方法を教えて下さい。
727デフォルトの名無しさん
2014/07/01(火) 00:10:07.68ID:8cxNwtXU728片山博文MZ悪魔崇拝 ◆T6xkBnTXz7B0
2014/07/01(火) 00:12:40.61ID:/dpi9Kd/ ありがとうございます。
729デフォルトの名無しさん
2014/07/12(土) 22:10:17.18ID:x0cGe7WX swi-prologを使ってるんだけどassertした節を自動的にファイルに保存するようにはできないのかな
assertする度にlistingで書き出してバックアップとるのめんどくさそうだし効率わるそう
assertする度にlistingで書き出してバックアップとるのめんどくさそうだし効率わるそう
730デフォルトの名無しさん
2014/07/12(土) 22:56:26.14ID:ktHPdOby731デフォルトの名無しさん
2014/07/23(水) 04:59:03.99ID:W7WkvjfP prologでGAを実装するのには他の言語(Java)で実装するより何が優れている?
732デフォルトの名無しさん
2014/07/23(水) 18:41:02.31ID:Ricx3ybR カットを使った多様性の表現のし易さ
733デフォルトの名無しさん
2014/07/24(木) 01:48:04.69ID:Zh2B/axR GAにおいてとくにPrologが優れてる点は思いつかないけど、
Javaは冗長でほんと疲れる
Prologなら
member(1,L).
で済むところが、Java だと
List<Integer> list = new LinkedList<Integer>();
list.add(1);
になるからな。
GAだって銀行の勘定系だって、Prologなら半ページで書ける
Javaは冗長でほんと疲れる
Prologなら
member(1,L).
で済むところが、Java だと
List<Integer> list = new LinkedList<Integer>();
list.add(1);
になるからな。
GAだって銀行の勘定系だって、Prologなら半ページで書ける
734デフォルトの名無しさん
2014/07/24(木) 03:43:43.10ID:1HIq9M5v Prologこそ冗長の極みでそw
735デフォルトの名無しさん
2014/07/24(木) 09:11:30.92ID:URujTxoj736デフォルトの名無しさん
2014/08/17(日) 15:56:42.59ID:8ylmIV1H prolog覚えたいんですけど、何かいい方法はありますか?
Cやvba、php、あとcssなど触ってきましたが、やや特殊な感じがしてなかなか覚えることが出来ません…
習うより慣れろ、でしょうか
Cやvba、php、あとcssなど触ってきましたが、やや特殊な感じがしてなかなか覚えることが出来ません…
習うより慣れろ、でしょうか
737デフォルトの名無しさん
2014/08/17(日) 16:35:59.06ID:XkL8f3FM まずは手続き型プログラミングの延長で考えよう
たとえば値 x とy の最大値を求める関数 max(x, y) を疑似コードで書くと:
max(x, y) = if x > y then z := x else z := y; return z
これを Prolog では:
max(X, Y, Z) ;- X > Y, !, Z = X.
max(_, Y, Z) ;- Z = Y.
と書けるけど、一般にはより簡潔に以下のように書く:
max(X, Y, X) ;- X > Y, !.
max(_, Y, Y).
ここで、カット "!" は条件式と以降の文との間に置く "then" と見る
ここまでは(手続き型における)「分岐」のパターンになるけど、
手続き型の「反復」を Prolog では「再帰」で書くから、
「再帰の書き方(=再帰的定義)」に慣れることが最初の壁になる
たとえば数のリストについて、各値を +1 する述語 list_succ は:
list_succ([X|XS], [Y|YS]) ;- Y is X + 1, !, list_succ(XS, YS).
list_succ([], []).
と書き、同様に偶数だけを抽出する述語は:
list_even([X|XS], [X|YS]) ;- is_even(X), !, list_even(XS, YS).
list_even([_|XS], YS) ;- list_even(XS, YS).
list_even([], []).
こういった手続き型プログラミングと共通する概念とその書き方に慣れてから、
Ptolog 固有の「単一化」や「バックトラッキング」といった概念を学ぶといい
たとえば値 x とy の最大値を求める関数 max(x, y) を疑似コードで書くと:
max(x, y) = if x > y then z := x else z := y; return z
これを Prolog では:
max(X, Y, Z) ;- X > Y, !, Z = X.
max(_, Y, Z) ;- Z = Y.
と書けるけど、一般にはより簡潔に以下のように書く:
max(X, Y, X) ;- X > Y, !.
max(_, Y, Y).
ここで、カット "!" は条件式と以降の文との間に置く "then" と見る
ここまでは(手続き型における)「分岐」のパターンになるけど、
手続き型の「反復」を Prolog では「再帰」で書くから、
「再帰の書き方(=再帰的定義)」に慣れることが最初の壁になる
たとえば数のリストについて、各値を +1 する述語 list_succ は:
list_succ([X|XS], [Y|YS]) ;- Y is X + 1, !, list_succ(XS, YS).
list_succ([], []).
と書き、同様に偶数だけを抽出する述語は:
list_even([X|XS], [X|YS]) ;- is_even(X), !, list_even(XS, YS).
list_even([_|XS], YS) ;- list_even(XS, YS).
list_even([], []).
こういった手続き型プログラミングと共通する概念とその書き方に慣れてから、
Ptolog 固有の「単一化」や「バックトラッキング」といった概念を学ぶといい
738デフォルトの名無しさん
2014/08/17(日) 17:01:36.81ID:XkL8f3FM >>737 のコード中にある ;- は :- のタイプミスなので訂正
739デフォルトの名無しさん
2014/08/17(日) 20:16:33.99ID:3mYBlI6x 8/22(金)10:30〜
放送大学集中放送授業期間
『記号論理学('14)』
というのがある。
オススメというよりも自分が楽しみにしているのだけど。
放送大学集中放送授業期間
『記号論理学('14)』
というのがある。
オススメというよりも自分が楽しみにしているのだけど。
740デフォルトの名無しさん
2014/08/18(月) 20:04:08.48ID:5sINgTuF741デフォルトの名無しさん
2014/08/19(火) 00:32:49.89ID:hp9R9Csq 論理的な側面を忘れて、prologを手続型の言語として捉えるのはいい勉強になるね
少し趣旨は違うけど
main :- between(1, 9, X), between(1, 9, Y), Z is X * Y, write(X*Y=Z), nl, fail.
失敗駆動ループを覚えると、バックトラックが少し楽に理解できるかも
少し趣旨は違うけど
main :- between(1, 9, X), between(1, 9, Y), Z is X * Y, write(X*Y=Z), nl, fail.
失敗駆動ループを覚えると、バックトラックが少し楽に理解できるかも
742デフォルトの名無しさん
2014/08/19(火) 07:39:00.21ID:a3YaW1zc 冗長の極みを露悪的に表現したPrologコード。
今度は一万円に達するか、さらに買い物をしなくてはならないか、
レジと売り場を行ったり来たり、駆けずり回っている。
http://nojiriko.asia/prolog/p_odai4_776.html
今度は一万円に達するか、さらに買い物をしなくてはならないか、
レジと売り場を行ったり来たり、駆けずり回っている。
http://nojiriko.asia/prolog/p_odai4_776.html
743デフォルトの名無しさん
2014/08/19(火) 08:21:36.82ID:a3YaW1zc 少し違うのですが、これも手続き的なシミュレーション。
http://nojiriko.asia/prolog/fukakusa_no_shoushou_1_1_1.html
深草の少将は小野小町のもとに雨の日も風の日も
百夜通うのですが、百夜目に力尽き、はかなくなります。
一夜、通う度に、榻(牛車に乗り降りする為の渡し板)に
刻みを入れます。そして数えます。ひとつ、ふたつ、・・・
http://nojiriko.asia/prolog/fukakusa_no_shoushou_1_1_1.html
深草の少将は小野小町のもとに雨の日も風の日も
百夜通うのですが、百夜目に力尽き、はかなくなります。
一夜、通う度に、榻(牛車に乗り降りする為の渡し板)に
刻みを入れます。そして数えます。ひとつ、ふたつ、・・・
744デフォルトの名無しさん
2014/08/19(火) 23:25:35.45ID:AYs1stK5 >>741
九九の表を印刷するお題は、自分なら以下のように書く
main :- findall(X, multiply_of_product(X), Xs), print_list(Xs).
multiply_of_product(Z) :- between(1, 3, X), between(1, 3, Y), Z is X * Y.
print_list([X|Xs]) :- write(X), nl, print_list(Xs).
print_list([]).
失敗駆動ループ技法は、いわゆるバッド・ノウハウの類いだと思う
九九の表を印刷するお題は、自分なら以下のように書く
main :- findall(X, multiply_of_product(X), Xs), print_list(Xs).
multiply_of_product(Z) :- between(1, 3, X), between(1, 3, Y), Z is X * Y.
print_list([X|Xs]) :- write(X), nl, print_list(Xs).
print_list([]).
失敗駆動ループ技法は、いわゆるバッド・ノウハウの類いだと思う
745デフォルトの名無しさん
2014/08/20(水) 17:10:44.30ID:4GbBt7a2 >>744
失敗駆動をfindall/3で隠蔽していますね。同様に、
main :- forall(multiply_of_product(X),writef('%t\n',[X])).
というのもあります。
失敗駆動をfindall/3で隠蔽していますね。同様に、
main :- forall(multiply_of_product(X),writef('%t\n',[X])).
というのもあります。
746デフォルトの名無しさん
2014/08/20(水) 21:59:59.69ID:QfOrIRE5747デフォルトの名無しさん
2014/08/20(水) 23:19:48.10ID:32E1i6+B >>746
>これはあくまでバックトラックを理解するための例として
初心者に対してバックトラックの理解を助ける最初の例として、
失敗駆動ループは不適切という話だ
もっと単純で分かりやすい例を持ち出すべきだった
>ただし、どうしても失敗駆動が必要になることもあるからね
そのとおりだね
どうしても使わなければ解決できない問題に対してだけ使うべき
たとえば>>744 のコードだと、全解探索結果リスト Xs が
メモリに乗り切れないほど巨大という極限のケースでは
失敗駆動ループ技法も(>>745と合わせて)検討候補になるだろう
逆に言えば、一般的な多くのケースで Prolog らしい
エレガントな解法があるのに、ただ書き慣れているからという理由で
安易に失敗駆動ループ技法を使うのは中級プログラマとして失格だと思う
だから >>744 ではバッド・ノウハウの類いと書いた
>これはあくまでバックトラックを理解するための例として
初心者に対してバックトラックの理解を助ける最初の例として、
失敗駆動ループは不適切という話だ
もっと単純で分かりやすい例を持ち出すべきだった
>ただし、どうしても失敗駆動が必要になることもあるからね
そのとおりだね
どうしても使わなければ解決できない問題に対してだけ使うべき
たとえば>>744 のコードだと、全解探索結果リスト Xs が
メモリに乗り切れないほど巨大という極限のケースでは
失敗駆動ループ技法も(>>745と合わせて)検討候補になるだろう
逆に言えば、一般的な多くのケースで Prolog らしい
エレガントな解法があるのに、ただ書き慣れているからという理由で
安易に失敗駆動ループ技法を使うのは中級プログラマとして失格だと思う
だから >>744 ではバッド・ノウハウの類いと書いた
748デフォルトの名無しさん
2014/08/20(水) 23:58:46.17ID:32E1i6+B バックトラックの例について書く
たとえば(>>745 は気付いていると思うけど) >>744 はバックトラックの応用になる
?- multiply_of_product(X).
X = 1 ; % 最初の解が表示され、";" をタイプするとバックトラックで次の解を求める
X = 2 ;
X = 3 ;
X = 2. % 途中で止めたい時には [return] をタイプすると入力待ちに戻る
?-
この述語 multiply_of_product/1 に関して、組み込み述語 findall/3 を使って
すべての解のリストを求めたのが >>744 になる
またリストそのものもバックトラックの対象になる
?- append(Xs, Ys, [1,2,3]). % 述語 append/3 は2つのリストを結合したリストを求める
Xs = [],
Ys = [1, 2, 3] ;
Xs = [1],
Ys = [2, 3] ;
Xs = [1, 2],
Ys = [3] ;
Xs = [1, 2, 3],
Ys = [] ;
false. % すべての解を探索し終えると false を表示して入力待ちに戻る
?-
同様に findall/3 を使ってすべての解のリストを求めてみる
?- findall((X,Y), append(X,Y,[1,2,3]), ListOfPair).
ListOfPair = [ ([], [1, 2, 3]), ([1], [2, 3]), ([1, 2], [3]), ([1, 2, 3], [])].
?-
たとえば(>>745 は気付いていると思うけど) >>744 はバックトラックの応用になる
?- multiply_of_product(X).
X = 1 ; % 最初の解が表示され、";" をタイプするとバックトラックで次の解を求める
X = 2 ;
X = 3 ;
X = 2. % 途中で止めたい時には [return] をタイプすると入力待ちに戻る
?-
この述語 multiply_of_product/1 に関して、組み込み述語 findall/3 を使って
すべての解のリストを求めたのが >>744 になる
またリストそのものもバックトラックの対象になる
?- append(Xs, Ys, [1,2,3]). % 述語 append/3 は2つのリストを結合したリストを求める
Xs = [],
Ys = [1, 2, 3] ;
Xs = [1],
Ys = [2, 3] ;
Xs = [1, 2],
Ys = [3] ;
Xs = [1, 2, 3],
Ys = [] ;
false. % すべての解を探索し終えると false を表示して入力待ちに戻る
?-
同様に findall/3 を使ってすべての解のリストを求めてみる
?- findall((X,Y), append(X,Y,[1,2,3]), ListOfPair).
ListOfPair = [ ([], [1, 2, 3]), ([1], [2, 3]), ([1, 2], [3]), ([1, 2, 3], [])].
?-
749デフォルトの名無しさん
2014/08/21(木) 14:24:23.77ID:LiUTLLqd750デフォルトの名無しさん
2014/08/21(木) 15:21:18.64ID:SiLTEdjO >>749
全解をプリントするの意味にもよるが、ビジネスで一覧表を出すような場合は、
これはまた違うと思う。このような表には、集約情報を要求される場合が多く、
失敗駆動は集約には無力なので、一旦findall/3でリストに取る場合が多い。
全解をプリントするの意味にもよるが、ビジネスで一覧表を出すような場合は、
これはまた違うと思う。このような表には、集約情報を要求される場合が多く、
失敗駆動は集約には無力なので、一旦findall/3でリストに取る場合が多い。
751デフォルトの名無しさん
2014/09/16(火) 19:57:50.16ID:PVbEy2qP すみません
カットを使わずにカットと同様のモノは表現できるでしょうか
カットを使わずにカットと同様のモノは表現できるでしょうか
752デフォルトの名無しさん
2014/09/16(火) 22:10:27.01ID:+Ut5bl5+ >>751
前提条件によりけりだよ
ここで前提条件とは:
・カットの種類(グリーンなのかレッドなのか?)
・「同様」という言葉の定義(結果さえ一致すればいいのか効率も考慮するのか)
になる
一般論ではなく、具体的なコードで再質問したほうがいいと思われる
前提条件によりけりだよ
ここで前提条件とは:
・カットの種類(グリーンなのかレッドなのか?)
・「同様」という言葉の定義(結果さえ一致すればいいのか効率も考慮するのか)
になる
一般論ではなく、具体的なコードで再質問したほうがいいと思われる
753デフォルトの名無しさん
2014/09/17(水) 07:53:36.70ID:JrDwRrBo >>751
p :- q1,!.
p :- q2.
のカットはq1に副作用がなければ、
p :- q1.
p :- \+(q1),q2.
と書くことができる。
p(s(1,t(2)) :- !,q1.
p(s(X,t(Y)) :- q2.
は
p(s(1,t(2)) :- q1.
p(s(X,t(Y)) :- \+(X=1),\+(Y=2),q2.
としなくてはならない。
カットがPrologから切り捨てられない話として、否定の定義、
\+(P) :- call(P),!,fail.
\+(P).
がよくあげられる。このカットは代用が効かない。
それから組込述語findall/3の設計からくる問題なのだが、repeatを持つ
標準入力からの入力。(ここでは整数に限定しているが)
?- findall(X,(repeat,read(X),(X=end_of_file,!,fail;integer(X))),L).
この制御のためのカットも他に手がない。
p :- q1,!.
p :- q2.
のカットはq1に副作用がなければ、
p :- q1.
p :- \+(q1),q2.
と書くことができる。
p(s(1,t(2)) :- !,q1.
p(s(X,t(Y)) :- q2.
は
p(s(1,t(2)) :- q1.
p(s(X,t(Y)) :- \+(X=1),\+(Y=2),q2.
としなくてはならない。
カットがPrologから切り捨てられない話として、否定の定義、
\+(P) :- call(P),!,fail.
\+(P).
がよくあげられる。このカットは代用が効かない。
それから組込述語findall/3の設計からくる問題なのだが、repeatを持つ
標準入力からの入力。(ここでは整数に限定しているが)
?- findall(X,(repeat,read(X),(X=end_of_file,!,fail;integer(X))),L).
この制御のためのカットも他に手がない。
754753
2014/09/17(水) 07:59:41.82ID:JrDwRrBo 右括弧が一つ足らなかった。
p(s(1,t(2))) :- !,q1.
p(s(X,t(Y))) :- q2.
と
p(s(1,t(2))) :- q1.
p(s(X,t(Y))) :- \+(X=1),\+(Y=2),q2.
でした。
p(s(1,t(2))) :- !,q1.
p(s(X,t(Y))) :- q2.
と
p(s(1,t(2))) :- q1.
p(s(X,t(Y))) :- \+(X=1),\+(Y=2),q2.
でした。
755753 754
2014/09/17(水) 11:14:56.78ID:vF3wK/oS756デフォルトの名無しさん
2014/09/17(水) 21:30:48.29ID:2WfHlgOC757デフォルトの名無しさん
2014/09/17(水) 23:34:03.64ID:xNQ0rvrC 皆さん、この言語ってどういう動機で覚えたんでしょうか?
なんとなく名前がかっこいいから覚えようと思いましたが、レベル硬くて驚きました。
なんとなく名前がかっこいいから覚えようと思いましたが、レベル硬くて驚きました。
758デフォルトの名無しさん
2014/09/17(水) 23:35:01.45ID:xNQ0rvrC すいません。
硬くて→高くて。
少し触ってみましたがまだポエムすら書けない感じです。
硬くて→高くて。
少し触ってみましたがまだポエムすら書けない感じです。
759デフォルトの名無しさん
2014/09/18(木) 03:49:46.40ID:f3YnogPC sicpでprologを作る章を読んだから
760デフォルトの名無しさん
2014/09/18(木) 13:28:49.42ID:2XScWOD5 学校の授業。
761デフォルトの名無しさん
2014/09/18(木) 18:39:14.23ID:pPyVXEwN 文系の学部だと英語の構文解析の授業でprologを使うと聞いた
762デフォルトの名無しさん
2014/09/18(木) 20:52:07.83ID:fQdBdw40 >>753
>それから組込述語findall/3の設計からくる問題なのだが、repeatを持つ
>標準入力からの入力。(ここでは整数に限定しているが)
>
>?- findall(X,(repeat,read(X),(X=end_of_file,!,fail;integer(X))),L).
>
>この制御のためのカットも他に手がない。
この単純な入力処理であれば、同じ振る舞いをするコードをカット無しで書ける
http://ideone.com/vBLt2R
失敗駆動ループや findall を使わず素直に再帰で表現した初歩的なコードだ
すでに >>744,747 で書いたように、失敗駆動ループはバッド・ノウハウの類いである
また組込み述語 findall/3 の探索するゴールは、 >>748 で例を示したように
副作用を含むべきではない
(組込み述語 read/1 には、入力ストリームを「読み進める」という副作用がある)
率直に言って、この程度の単純な入力処理に対して
「この制御のためのカットも他に手がない」などと安易に判断してしまう >>756 は、
失敗駆動ループや findall といった手続き型による「小手先のテクニック」にこだわるあまり、
論理プログラミングの持つ本質的な単純明快さを見失っているように見える
>それから組込述語findall/3の設計からくる問題なのだが、repeatを持つ
>標準入力からの入力。(ここでは整数に限定しているが)
>
>?- findall(X,(repeat,read(X),(X=end_of_file,!,fail;integer(X))),L).
>
>この制御のためのカットも他に手がない。
この単純な入力処理であれば、同じ振る舞いをするコードをカット無しで書ける
http://ideone.com/vBLt2R
失敗駆動ループや findall を使わず素直に再帰で表現した初歩的なコードだ
すでに >>744,747 で書いたように、失敗駆動ループはバッド・ノウハウの類いである
また組込み述語 findall/3 の探索するゴールは、 >>748 で例を示したように
副作用を含むべきではない
(組込み述語 read/1 には、入力ストリームを「読み進める」という副作用がある)
率直に言って、この程度の単純な入力処理に対して
「この制御のためのカットも他に手がない」などと安易に判断してしまう >>756 は、
失敗駆動ループや findall といった手続き型による「小手先のテクニック」にこだわるあまり、
論理プログラミングの持つ本質的な単純明快さを見失っているように見える
763デフォルトの名無しさん
2014/09/18(木) 21:10:59.37ID:pPyVXEwN filter をカットなしで書く方法を知りたいです
カットなしだと部分リストも答えで出てくる
filter(Pred, [], []).
filter(Pred, [X|Xs], [X|Ys]) :- prove(Pred, [X]), filter(Pred, Xs, Ys).
filter(Pred, [X|Xs], Ys) :- filter(Pred, Xs, Ys).
カットなしだと部分リストも答えで出てくる
filter(Pred, [], []).
filter(Pred, [X|Xs], [X|Ys]) :- prove(Pred, [X]), filter(Pred, Xs, Ys).
filter(Pred, [X|Xs], Ys) :- filter(Pred, Xs, Ys).
764デフォルトの名無しさん
2014/09/18(木) 21:27:49.66ID:fQdBdw40765デフォルトの名無しさん
2014/09/19(金) 04:57:53.94ID:fVs2kyBw >>762
実際に使うのは、repeatを伴う入力処理の場合に限られると思うが
年齢(大田,33).
年齢(神戸,25).
年齢(下山,40).
・・・
で40歳が現れるまでの年齢リストを得たい場合も、
?- findall(_名前,(年齢(_名前,_年齢),(_年齢=40,!,fail;true)),_年齢リスト).
と書く。一般にこの問題が表面に出ないのは、普通は、
?- findall((_名前,_年齢),年齢(_名前,_年齢),L), ・・・・
と一旦、全年齢データをリストに変換してから、処理をするから。
実際に使うのは、repeatを伴う入力処理の場合に限られると思うが
年齢(大田,33).
年齢(神戸,25).
年齢(下山,40).
・・・
で40歳が現れるまでの年齢リストを得たい場合も、
?- findall(_名前,(年齢(_名前,_年齢),(_年齢=40,!,fail;true)),_年齢リスト).
と書く。一般にこの問題が表面に出ないのは、普通は、
?- findall((_名前,_年齢),年齢(_名前,_年齢),L), ・・・・
と一旦、全年齢データをリストに変換してから、処理をするから。
766デフォルトの名無しさん
2014/09/19(金) 04:59:58.17ID:fVs2kyBw767デフォルトの名無しさん
2014/09/19(金) 07:51:22.98ID:fVs2kyBw % カットの話題から逸れるが、設計が適切とは言い難いデータベースの集約問題。
% 駒場東大前から下北沢までの距離を求めなさい
井の頭線(渋谷,500).
井の頭線(神泉,900).
井の頭線(駒場東大前,1000).
井の頭線(池ノ上,600).
井の頭線(下北沢,500).
井の頭線(新代田,東松原,500).
駒場東大前から下北沢までの距離(_距離) :-
findall((_駅,_次の駅までの距離),井の頭線(_駅,_次の駅までの距離),L),
駒場東大前までを読み飛ばす(L,L2),
駒場東大前から下北沢までの距離(L2,_距離).
駒場東大前までを読み飛ばす([(駒場東大前,_次の駅までの距離)|R],[(駒場東大前,_次の駅までの距離)|R]).
駒場東大前までを読み飛ばす([_|R1],R2) :-
駒場東大前までを読み飛ばす(R1,R2).
駒場東大前から下北沢までの距離([(下北沢,_)|_],0).
駒場東大前から下北沢までの距離([(_,_次の駅までの距離)|R],_下北沢までの距離) :-
駒場東大前から下北沢までの距離(R,_次の駅から下北沢までの距離),
_下北沢までの距離 is _次の駅までの距離 + _次の駅から下北沢までの距離.
% 駒場東大前から下北沢までの距離を求めなさい
井の頭線(渋谷,500).
井の頭線(神泉,900).
井の頭線(駒場東大前,1000).
井の頭線(池ノ上,600).
井の頭線(下北沢,500).
井の頭線(新代田,東松原,500).
駒場東大前から下北沢までの距離(_距離) :-
findall((_駅,_次の駅までの距離),井の頭線(_駅,_次の駅までの距離),L),
駒場東大前までを読み飛ばす(L,L2),
駒場東大前から下北沢までの距離(L2,_距離).
駒場東大前までを読み飛ばす([(駒場東大前,_次の駅までの距離)|R],[(駒場東大前,_次の駅までの距離)|R]).
駒場東大前までを読み飛ばす([_|R1],R2) :-
駒場東大前までを読み飛ばす(R1,R2).
駒場東大前から下北沢までの距離([(下北沢,_)|_],0).
駒場東大前から下北沢までの距離([(_,_次の駅までの距離)|R],_下北沢までの距離) :-
駒場東大前から下北沢までの距離(R,_次の駅から下北沢までの距離),
_下北沢までの距離 is _次の駅までの距離 + _次の駅から下北沢までの距離.
768デフォルトの名無しさん
2014/09/19(金) 20:54:01.75ID:ClkAEpx3 >>765.766
やはり「論理プログラミングの持つ本質的な単純明快さを見失っている(>>762)」みたいだね
Prolog だと述語定義の並びは論理和を意味する
つまり、そのコードの意味は 年齢(大田,33) ∨ 年齢(神戸,25) ∨ 年齢(下山,40) になる
そして論理式には交換律 A ∨ B ≡ B ∨ A があるから、述語定義の並びに論理的な意味は無い
もし順序性を表現したいのであれば、以下のように順序性を明示的に書かなければならない
年齢(大田, 33).
年齢(神戸, 25).
年齢(下山, 40).
順序(大田, 神戸).
順序(神戸, 下山).
あるいは述語「年齢」に「次の人物」または「順序番号」を付加してもかまわない
年齢(大田, 33, 神戸).
年齢(神戸, 25, 下山).
年齢(下山, 40, end_of_list).
または
年齢(大田, 33, 1).
年齢(神戸, 25, 2).
年齢(下山, 40, 3).
これら以外にも、人物リストであれば、人物名の「ふりがな」も順序性を表す情報となりえる
また、人物リストそのものを表現することが目的であれば、直接それを述語として定義すればいい
人物リスト([年齢(大田, 33), 年齢(神戸, 25), 年齢(下山, 40)]).
どれが適切かは、アプリケーションによりけり(=ケースバイケース)になる
やはり「論理プログラミングの持つ本質的な単純明快さを見失っている(>>762)」みたいだね
Prolog だと述語定義の並びは論理和を意味する
つまり、そのコードの意味は 年齢(大田,33) ∨ 年齢(神戸,25) ∨ 年齢(下山,40) になる
そして論理式には交換律 A ∨ B ≡ B ∨ A があるから、述語定義の並びに論理的な意味は無い
もし順序性を表現したいのであれば、以下のように順序性を明示的に書かなければならない
年齢(大田, 33).
年齢(神戸, 25).
年齢(下山, 40).
順序(大田, 神戸).
順序(神戸, 下山).
あるいは述語「年齢」に「次の人物」または「順序番号」を付加してもかまわない
年齢(大田, 33, 神戸).
年齢(神戸, 25, 下山).
年齢(下山, 40, end_of_list).
または
年齢(大田, 33, 1).
年齢(神戸, 25, 2).
年齢(下山, 40, 3).
これら以外にも、人物リストであれば、人物名の「ふりがな」も順序性を表す情報となりえる
また、人物リストそのものを表現することが目的であれば、直接それを述語として定義すればいい
人物リスト([年齢(大田, 33), 年齢(神戸, 25), 年齢(下山, 40)]).
どれが適切かは、アプリケーションによりけり(=ケースバイケース)になる
769デフォルトの名無しさん
2014/09/19(金) 21:33:32.57ID:ClkAEpx3 >>767
これもまた >>765 と同様に論理的ではないデータベース設計の例だね
駅間距離を「(ある駅と駅との間の)接続関係」および「関係に伴う属性」として
論理的にデータベースを設計すると、以下のようになる
井の頭線の駅(渋谷).
井の頭線の駅(神泉).
井の頭線の駅(駒場東大前).
井の頭線の駅(池ノ上).
井の頭線の駅(下北沢).
井の頭線の駅(新代田).
井の頭線の駅(東松原).
井の頭線の駅間距離(渋谷, 神泉, 500).
井の頭線の駅間距離(神泉, 駒場東大前 , 900).
井の頭線の駅間距離(駒場東大前, 池ノ上, 1000).
井の頭線の駅間距離(池ノ上, 下北沢 , 600).
井の頭線の駅間距離(下北沢, 新代田, 500).
井の頭線の駅間距離(新代田, 東松原, 500).
ここで、鉄道路線が駅を頂点とする無向グラフとしてモデル化されることに気が付けば、
述語「井の頭線の駅」がグラフの頂点を、述語「井の頭線の駅間距離」がグラフの辺を
表していることが、直感として理解できるはずだ
これもまた >>765 と同様に論理的ではないデータベース設計の例だね
駅間距離を「(ある駅と駅との間の)接続関係」および「関係に伴う属性」として
論理的にデータベースを設計すると、以下のようになる
井の頭線の駅(渋谷).
井の頭線の駅(神泉).
井の頭線の駅(駒場東大前).
井の頭線の駅(池ノ上).
井の頭線の駅(下北沢).
井の頭線の駅(新代田).
井の頭線の駅(東松原).
井の頭線の駅間距離(渋谷, 神泉, 500).
井の頭線の駅間距離(神泉, 駒場東大前 , 900).
井の頭線の駅間距離(駒場東大前, 池ノ上, 1000).
井の頭線の駅間距離(池ノ上, 下北沢 , 600).
井の頭線の駅間距離(下北沢, 新代田, 500).
井の頭線の駅間距離(新代田, 東松原, 500).
ここで、鉄道路線が駅を頂点とする無向グラフとしてモデル化されることに気が付けば、
述語「井の頭線の駅」がグラフの頂点を、述語「井の頭線の駅間距離」がグラフの辺を
表していることが、直感として理解できるはずだ
770769
2014/09/19(金) 22:28:08.91ID:ClkAEpx3771デフォルトの名無しさん
2014/09/19(金) 22:53:53.05ID:fVs2kyBw 設計が適切とは言い難いデータベース。
リレーショナルデータベースをそのまま述語として写した場合にしばしば
現れる。あるいは何か示されたことをPrologデータベースとしてそのまま
写し取った場合。
以下のように書き換えられればもちろんよい。
井の頭線(渋谷,神泉,500).
井の頭線(神泉,駒場東大前,900).
井の頭線(駒場東大前,池ノ上,1000).
井の頭線(池ノ上,下北沢,600).
井の頭線(下北沢,新代田,500).
駒場東大前から下北沢までの距離(_距離) :-
駒場東大前から下北沢までの距離(駒場東大前,_距離).
駒場東大前から下北沢までの距離(下北沢,0).
駒場東大前から下北沢までの距離(_駅,_距離) :-
井の頭線(_駅,_次の駅,_次の駅までの距離),
駒場東大前から下北沢までの距離(_次の駅,_次の駅から下北沢までの距離),
_距離 is _次の駅から下北沢までの距離 + _次の駅までの距離.
リレーショナルデータベースをそのまま述語として写した場合にしばしば
現れる。あるいは何か示されたことをPrologデータベースとしてそのまま
写し取った場合。
以下のように書き換えられればもちろんよい。
井の頭線(渋谷,神泉,500).
井の頭線(神泉,駒場東大前,900).
井の頭線(駒場東大前,池ノ上,1000).
井の頭線(池ノ上,下北沢,600).
井の頭線(下北沢,新代田,500).
駒場東大前から下北沢までの距離(_距離) :-
駒場東大前から下北沢までの距離(駒場東大前,_距離).
駒場東大前から下北沢までの距離(下北沢,0).
駒場東大前から下北沢までの距離(_駅,_距離) :-
井の頭線(_駅,_次の駅,_次の駅までの距離),
駒場東大前から下北沢までの距離(_次の駅,_次の駅から下北沢までの距離),
_距離 is _次の駅から下北沢までの距離 + _次の駅までの距離.
772デフォルトの名無しさん
2014/09/19(金) 23:06:13.46ID:ClkAEpx3 >>771
採点すると50点だな
まず、一般的な「ある2つの駅間の距離」を述語として定義し、
それを使って具体的な述語「駒場東大前から下北沢までの距離」を定義するという、
「構造化プログラミング」のアプローチが望ましい
駒場東大前から下北沢までの距離(_距離) :-
ある2つの駅間の距離(駒場東大前, 下北沢, _距離).
判定:課題の再提出を要す
採点すると50点だな
まず、一般的な「ある2つの駅間の距離」を述語として定義し、
それを使って具体的な述語「駒場東大前から下北沢までの距離」を定義するという、
「構造化プログラミング」のアプローチが望ましい
駒場東大前から下北沢までの距離(_距離) :-
ある2つの駅間の距離(駒場東大前, 下北沢, _距離).
判定:課題の再提出を要す
773デフォルトの名無しさん
2014/09/19(金) 23:13:52.01ID:fVs2kyBw >>772
それは単に抽象プログラミングでしかない。
それは単に抽象プログラミングでしかない。
774デフォルトの名無しさん
2014/09/19(金) 23:22:26.65ID:8TBQk5yL 大学の演習で作るprolog処理系だと、バックトラックじゃなくて、節の(ユニフィケーションの変数のバインドの)展開だからカットの実装の困難さがいまいち理解できなくて困る
775デフォルトの名無しさん
2014/09/19(金) 23:43:22.71ID:ClkAEpx3776デフォルトの名無しさん
2014/09/20(土) 00:04:57.96ID:ReqVJHou >>774
メタインタプリタ/部分評価(=最適化)/プログラム変換(例:ループ融合)のように、
Prologプログラミングの対象が(データではなく)Prologプログラムそのものであった場合、
カットを含む副作用を伴う述語の形式的な定義は技術的な難問になる
メタインタプリタ/部分評価(=最適化)/プログラム変換(例:ループ融合)のように、
Prologプログラミングの対象が(データではなく)Prologプログラムそのものであった場合、
カットを含む副作用を伴う述語の形式的な定義は技術的な難問になる
777773
2014/09/20(土) 07:35:27.46ID:lJJn8OIz778デフォルトの名無しさん
2014/09/20(土) 08:01:21.59ID:lJJn8OIz findall/3の奇妙なカット処理問題が重要なのは、このカットを他の述語で置き換えることが
不可能なことを理解することによって、カットの意味の理解が一段進むと考えられるからだ。
この事例ほどにカットを直観できるものは他にないと思う。
不可能なことを理解することによって、カットの意味の理解が一段進むと考えられるからだ。
この事例ほどにカットを直観できるものは他にないと思う。
779デフォルトの名無しさん
2014/09/22(月) 07:30:22.65ID:8Y/Ncwny >>775
% Prolog 抽象プログラミングの例。
% 具象プログラミングでは述語名に現れていた情報が引数に移動する。
%
% 駒場東大前から下北沢までの距離を求めなさい
隣接する駅間の距離(井の頭線,渋谷,神泉,500).
隣接する駅間の距離(井の頭線,神泉,駒場東大前,900).
隣接する駅間の距離(井の頭線,駒場東大前,池ノ上,1000).
隣接する駅間の距離(井の頭線,池ノ上,下北沢,600).
隣接する駅間の距離(井の頭線,下北沢,新代田,500).
井の頭線の駒場東大前から下北沢までの距離(_井の頭線の駒場東大前から下北沢までの距離) :-
二駅間の距離(井の頭線,駒場東大前,下北沢,_井の頭線の駒場東大前から下北沢までの距離).
二駅間の距離(_,_到達駅,_到達駅,0).
二駅間の距離(_路線,_駅,_到達駅,_到達駅までの距離) :-
隣接する駅間の距離(_路線,_駅,_次の駅,_次の駅までの距離),
二駅間の距離(_路線,_次の駅,_到達駅,_次の駅から到達駅までの距離),
_到達駅までの距離 is _次の駅から到達駅での距離 + _次の駅までの距離.
% Prolog 抽象プログラミングの例。
% 具象プログラミングでは述語名に現れていた情報が引数に移動する。
%
% 駒場東大前から下北沢までの距離を求めなさい
隣接する駅間の距離(井の頭線,渋谷,神泉,500).
隣接する駅間の距離(井の頭線,神泉,駒場東大前,900).
隣接する駅間の距離(井の頭線,駒場東大前,池ノ上,1000).
隣接する駅間の距離(井の頭線,池ノ上,下北沢,600).
隣接する駅間の距離(井の頭線,下北沢,新代田,500).
井の頭線の駒場東大前から下北沢までの距離(_井の頭線の駒場東大前から下北沢までの距離) :-
二駅間の距離(井の頭線,駒場東大前,下北沢,_井の頭線の駒場東大前から下北沢までの距離).
二駅間の距離(_,_到達駅,_到達駅,0).
二駅間の距離(_路線,_駅,_到達駅,_到達駅までの距離) :-
隣接する駅間の距離(_路線,_駅,_次の駅,_次の駅までの距離),
二駅間の距離(_路線,_次の駅,_到達駅,_次の駅から到達駅までの距離),
_到達駅までの距離 is _次の駅から到達駅での距離 + _次の駅までの距離.
780デフォルトの名無しさん
2014/09/26(金) 11:44:22.80ID:ZJZ/lXfS Prologトリビア探検隊のなく頃に 初心者殺し編
https://sicstus.sics.se/sicstus/docs/4.3.0/html/sicstus/Glossary.html
>argument
> See predicate, structure, and arity.
>arity
> The arity of a structure is its number of arguments. For example,
> the structure customer(jones,85) has an arity of 2.
:
>compound term
> A compound term is a term that is an atom together with one or more arguments.
:
> Compound terms are recognized by the built-in predicate compound/1.
:
>string
:
>subterm selector
:
「structure」は「compound term」の古称(ゾンビ)
https://sicstus.sics.se/sicstus/docs/4.3.0/html/sicstus/Glossary.html
>argument
> See predicate, structure, and arity.
>arity
> The arity of a structure is its number of arguments. For example,
> the structure customer(jones,85) has an arity of 2.
:
>compound term
> A compound term is a term that is an atom together with one or more arguments.
:
> Compound terms are recognized by the built-in predicate compound/1.
:
>string
:
>subterm selector
:
「structure」は「compound term」の古称(ゾンビ)
781デフォルトの名無しさん
2014/10/01(水) 13:34:17.52ID:cI87Gfj0 >>772
単に部分的に抽象化しただけだと、
駒場東大前から下北沢までの距離(_距離) :-
ある2つの駅間の距離(駒場東大前, 下北沢, _距離).
ある2つの駅間の距離(_到達駅, _到達駅, 0) :- !.
ある2つの駅間の距離(_駅_1,_到達駅, _距離) :-
井の頭線の駅間距離(_駅_1, _駅_2, _駅間距離),
ある2つの駅間の距離(_駅_2, _到達駅, _距離_2),
_距離 is _距離_2 + _駅間距離.
となって、 ある2つの駅間の距離/3 という抽象定義の中に具体的な副目標、
井の頭線の駅間距離/3 が現れて設計は破綻する。それで>>779に示したように、
引数側に _路線 を設けて、井の頭線を移動する必要が生じる。
ここら当たりは、抽象プログラミングの弱点であって、常にこのような見直し
を怠ることができない。一方、具象的なプログラミングに於いてはこのような
設計変更は良かれ悪しかれ、ほとんど起こらない。
単に部分的に抽象化しただけだと、
駒場東大前から下北沢までの距離(_距離) :-
ある2つの駅間の距離(駒場東大前, 下北沢, _距離).
ある2つの駅間の距離(_到達駅, _到達駅, 0) :- !.
ある2つの駅間の距離(_駅_1,_到達駅, _距離) :-
井の頭線の駅間距離(_駅_1, _駅_2, _駅間距離),
ある2つの駅間の距離(_駅_2, _到達駅, _距離_2),
_距離 is _距離_2 + _駅間距離.
となって、 ある2つの駅間の距離/3 という抽象定義の中に具体的な副目標、
井の頭線の駅間距離/3 が現れて設計は破綻する。それで>>779に示したように、
引数側に _路線 を設けて、井の頭線を移動する必要が生じる。
ここら当たりは、抽象プログラミングの弱点であって、常にこのような見直し
を怠ることができない。一方、具象的なプログラミングに於いてはこのような
設計変更は良かれ悪しかれ、ほとんど起こらない。
783デフォルトの名無しさん
2014/10/31(金) 21:05:44.19ID:g6D744er すいません。教えてください。
prologでconnect4のルールを実装しようとしています。
connect4はこことかで遊べます。
http://www.connectfour.org/connect-4-online.php
途中までコードを書いたのですが上手く動いてくれません。
私のコードをデバッグしてもらえないでしょうか。
prologでconnect4のルールを実装しようとしています。
connect4はこことかで遊べます。
http://www.connectfour.org/connect-4-online.php
途中までコードを書いたのですが上手く動いてくれません。
私のコードをデバッグしてもらえないでしょうか。
784783
2014/10/31(金) 21:07:15.47ID:g6D744er 二重リストで盤面を表す。
get_atでリストのN番目の要素を返す。
get_stoneでBOARDの(X,Y)の位置にある石を返す。盤の外を指定したときは3を返す。
straightで連続した石の数を数える。DX,DYは連続した石を探索する方向。
よろしくお願いします。
board([[],[],[],[],[],[],[]]).
myboard([[1,2],[1,1],[1,1,1],[1,1,1,2],[],[],[1,2,1]]).
get_at(_,[],_):- fail.
get_at(0,[X|_],X).
get_at(N,[_|Ls],Y):-
N1 is N -1,
get_at(N1,Ls,Y).
get_stone(_,X,_,3):- X<0,!.
get_stone(_,X,_,3):- 6<X,!.
get_stone(_,_,Y,3):- Y<0,!.
get_stone(BOARD,X,Y,0):-
get_at(X,BOARD,Xs),
length(Xs,L),
Y >= L,!.
get_stone(BOARD,X,Y,S):-
get_at(X,BOARD,Xs),
get_at(Y,Xs,S),!.
straight(BOARD,X,Y,_,_,S,0):-
get_stone(BOARD,X,Y,S1),
S1 \== S,!.
straight(BOARD,X,Y,DX,DY,Stn,Len):-
X1 is X + DX,
Y1 is Y + DY,
Len1 is Len + 1,
straight(BOARD,X1,Y1,DX,DY,Stn,Len1),!.
get_atでリストのN番目の要素を返す。
get_stoneでBOARDの(X,Y)の位置にある石を返す。盤の外を指定したときは3を返す。
straightで連続した石の数を数える。DX,DYは連続した石を探索する方向。
よろしくお願いします。
board([[],[],[],[],[],[],[]]).
myboard([[1,2],[1,1],[1,1,1],[1,1,1,2],[],[],[1,2,1]]).
get_at(_,[],_):- fail.
get_at(0,[X|_],X).
get_at(N,[_|Ls],Y):-
N1 is N -1,
get_at(N1,Ls,Y).
get_stone(_,X,_,3):- X<0,!.
get_stone(_,X,_,3):- 6<X,!.
get_stone(_,_,Y,3):- Y<0,!.
get_stone(BOARD,X,Y,0):-
get_at(X,BOARD,Xs),
length(Xs,L),
Y >= L,!.
get_stone(BOARD,X,Y,S):-
get_at(X,BOARD,Xs),
get_at(Y,Xs,S),!.
straight(BOARD,X,Y,_,_,S,0):-
get_stone(BOARD,X,Y,S1),
S1 \== S,!.
straight(BOARD,X,Y,DX,DY,Stn,Len):-
X1 is X + DX,
Y1 is Y + DY,
Len1 is Len + 1,
straight(BOARD,X1,Y1,DX,DY,Stn,Len1),!.
785デフォルトの名無しさん
2014/10/31(金) 22:56:49.16ID:uqHhdnYm >>783
1) 盤のデータ構造に一貫性がない
初期状態と思われる述語 board/2 を見ると、X軸では長さ 7 の固定長配列を表現しているが、
もう一つの盤 myboard/1 を見ると可変長配列で表現している
盤はある定数を持つ2次元配列なのだから、X軸とY軸の表現方法は一貫性を持つべき
2) 石の表現が適切ではない
石にはプレーヤの石とコンピュータの石の2種類があり、おそらくそれらを 1 と 2 という
整数で表現している
Prolog であれば文字アトムがあるから、それらは player と computer で表現できる
タイピングが面倒と感じたなら、p と c でもかまわない
たとえば Prolog と同じ動的型付け言語の Ruby ならば、
まよわずシンボル :player と :computer で表現する発想になっていたはずだ
あるいは静的型付け言語の Standard ML であれば、以下に示す直和型として定義する
datatype stone = Player | Computer
対象とする概念に応じて適切なデータ表現を選択するのは、
(Prolog に限らず)あらゆる言語におけるプログラミングの基本だ
3) 値域の検査に一貫性がない
座標値について、述語 get_at/3 では上限だけ検査して下限を検査していない(もし N が負であれば?)
同様に述語 get_stone/4 ではY軸の座標値について上限だけが検査されていない
検査しない方針ならそれどよし、検査するならするで想定できるすべてのケースを検査すべき
いきあたりばったりのコーディングはコードを品質させ、デバッグを難しくする要因になる
(長いので、次レス以降へ続く)
1) 盤のデータ構造に一貫性がない
初期状態と思われる述語 board/2 を見ると、X軸では長さ 7 の固定長配列を表現しているが、
もう一つの盤 myboard/1 を見ると可変長配列で表現している
盤はある定数を持つ2次元配列なのだから、X軸とY軸の表現方法は一貫性を持つべき
2) 石の表現が適切ではない
石にはプレーヤの石とコンピュータの石の2種類があり、おそらくそれらを 1 と 2 という
整数で表現している
Prolog であれば文字アトムがあるから、それらは player と computer で表現できる
タイピングが面倒と感じたなら、p と c でもかまわない
たとえば Prolog と同じ動的型付け言語の Ruby ならば、
まよわずシンボル :player と :computer で表現する発想になっていたはずだ
あるいは静的型付け言語の Standard ML であれば、以下に示す直和型として定義する
datatype stone = Player | Computer
対象とする概念に応じて適切なデータ表現を選択するのは、
(Prolog に限らず)あらゆる言語におけるプログラミングの基本だ
3) 値域の検査に一貫性がない
座標値について、述語 get_at/3 では上限だけ検査して下限を検査していない(もし N が負であれば?)
同様に述語 get_stone/4 ではY軸の座標値について上限だけが検査されていない
検査しない方針ならそれどよし、検査するならするで想定できるすべてのケースを検査すべき
いきあたりばったりのコーディングはコードを品質させ、デバッグを難しくする要因になる
(長いので、次レス以降へ続く)
786デフォルトの名無しさん
2014/10/31(金) 23:16:28.31ID:uqHhdnYm (>>785 の続き)
まず >>785 のタイプミスを訂正
X:いきあたりばったりのコーディングはコードを品質させ、
O:いきあたりばったりのコーディングはコード品質を悪化させ、
--
4) fail の使用が不適切
値の検査エラーを fail として扱っているが、論理型言語だと fail は(エラーではなく)偽という制御を意味する
このコードでは想定しない値、つまりバグの検出を意図していると思われるから、fail の代わりに abort を使う
get_at(_,[],_):- writeln('Unexpected index'), abort.
get_stone(_,X,_,3):- X<0, writeln('Out of range'(x = X)), abort.
fail だと Prolog はバックトラックを試みてしまうからデバッグが困難になるけど、
abort を使えばプログラムの実行を中止して一気にインタプリタのトップレベルへ復帰(大域脱出)できる
全般的な感想として、1)..3) を見るに (Prolog 以前に)一般的なプログラミングの基礎が身に付いていないと思う
おそらく集合理論言語スレの 1 だと思うけど、大学で情報系を専攻していたのなら情けない結果だ
学生時代に遊んでいたのか、当時はできたけど今はその感覚が戻っていないだけなのか、わからないけどね
現状のレベルでは、言語処理系を自作するなんてのは、夢物語か妄想のたぐいと判断せざるをえない
まず >>785 のタイプミスを訂正
X:いきあたりばったりのコーディングはコードを品質させ、
O:いきあたりばったりのコーディングはコード品質を悪化させ、
--
4) fail の使用が不適切
値の検査エラーを fail として扱っているが、論理型言語だと fail は(エラーではなく)偽という制御を意味する
このコードでは想定しない値、つまりバグの検出を意図していると思われるから、fail の代わりに abort を使う
get_at(_,[],_):- writeln('Unexpected index'), abort.
get_stone(_,X,_,3):- X<0, writeln('Out of range'(x = X)), abort.
fail だと Prolog はバックトラックを試みてしまうからデバッグが困難になるけど、
abort を使えばプログラムの実行を中止して一気にインタプリタのトップレベルへ復帰(大域脱出)できる
全般的な感想として、1)..3) を見るに (Prolog 以前に)一般的なプログラミングの基礎が身に付いていないと思う
おそらく集合理論言語スレの 1 だと思うけど、大学で情報系を専攻していたのなら情けない結果だ
学生時代に遊んでいたのか、当時はできたけど今はその感覚が戻っていないだけなのか、わからないけどね
現状のレベルでは、言語処理系を自作するなんてのは、夢物語か妄想のたぐいと判断せざるをえない
787デフォルトの名無しさん
2014/11/01(土) 01:37:40.45ID:cR58jgTn straight の定義が妙だね。
対象のマスに期待する石がなかった場合、 Len は 0 になる。
それ以外の場合、 Len + 1 を代入した Len1 を使って再帰してる。
でもこれをやるには、 Len は既に数値でなきゃいけない。
しかも、再帰先でこの Len1 と 0 との単一化が成功するには、 Len は負の数でなきゃいけない。
対象のマスに期待する石がなかった場合、 Len は 0 になる。
それ以外の場合、 Len + 1 を代入した Len1 を使って再帰してる。
でもこれをやるには、 Len は既に数値でなきゃいけない。
しかも、再帰先でこの Len1 と 0 との単一化が成功するには、 Len は負の数でなきゃいけない。
788783
2014/11/01(土) 09:43:11.50ID:EdETwwEo >>787
Len1 = Len + 1 は Len1 = Len - 1の間違いですね。
でもこれを直しても
ERROR: straight/7: Arguments are not sufficiently instantiated
って言われちゃいます。
なにか根本的に間違ってるような気がします。
Len1 = Len + 1 は Len1 = Len - 1の間違いですね。
でもこれを直しても
ERROR: straight/7: Arguments are not sufficiently instantiated
って言われちゃいます。
なにか根本的に間違ってるような気がします。
789デフォルトの名無しさん
2014/11/01(土) 10:42:41.34ID:cR58jgTn それを実行するには、先に Len に数値が代入されてなきゃいけないの。
is の右辺の式では未確定な変数は使えない。
この再帰だと、 Len より Len1 のが先に確定するよね。
だから再帰呼び出しのあとで Len を計算するって形にすればいいと思うけど。
is の右辺の式では未確定な変数は使えない。
この再帰だと、 Len より Len1 のが先に確定するよね。
だから再帰呼び出しのあとで Len を計算するって形にすればいいと思うけど。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 今年の漢字 [ぐれ★]
- 「偽サッチャー」「自滅的」「時代遅れ」 高市首相の経済政策を海外メディアが酷評 ★4 [蚤の市★]
- ミス・ユニバース フィンランド代表の「つり目」写真が波紋… 本人釈明も批判やまず 協会謝罪「徹底的に検証」へ★3 [冬月記者★]
- 今年の漢字は「熊」に決定! 相次ぐクマ被害 去年は「金」 [冬月記者★]
- あぼーん
- 【老舗文具メーカー】「生成AIで制作していた」――サクラクレパス、“AI疑惑”ポスターの調査結果を報告 ★2 [ぐれ★]
- メキシコ🇲🇽中国に対し50%の関税これに対し中国ブチ切れ😡なんか分からんけど笑う🤭 [993451824]
- 一人殺したい奴がいる
- 【速報】今年の漢字、「熊」!wwwwwwwwwwwwwwwwwwwwwwwww [279254606]
- 残クレタワマン、始まるwwwwwwwwwwwwwwwwwwwwwwwww [329329848]
- __トランプ、G7に代わる「Core 5」構想、米 中 露 印 日をまとめる巨大枠組み、世界秩序の再編につながる可能性 [827565401]
- 【速報】今年のゲームオブザイヤー、Clair Obscur: Expedition 33 [779938112]
