【論理】Prolog【初心者】

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

これは良い言語だ…
2011/12/10(土) 19:03:03.16
>>361
N1,N2が対になって左から右に移動する。そういう視覚的なところ。
2011/12/10(土) 21:37:06.68
冗長なのはいいけど、わかりにくいのは何とかしたいな。

人にもよると思うけど、>357と>359を比べると個人的には>357の方が
頭のスタック使用量が少なくて理解しゃすい。
2011/12/10(土) 22:19:54.19
>>363
findall/3は事実上SQLのselectだからそういうコードに慣れている人には
全然分かりにくくない。>>362とは違った見解を述べると、変数の束縛とその解放と
いうPrologの特長がfindallという枠組みのなかで明示的なバックトラックなしに
巧みに現れているという点で面白いと思う。
もうちょっと専門的にいうと、member/2ではできないことがappend/3で実現できている
というところが味噌なんだけれど。
2011/12/10(土) 22:24:07.98
     ____    ━┓
   /      \   ┏┛
  /  \   ,_\.  ・
/    (●)゛ (●) \
|  ∪   (__人__)    |
/     ∩ノ ⊃  /
(  \ / _ノ |  |
.\ “  /__|  |
  \ /___ /
2011/12/10(土) 22:35:49.05
うん、どうみても>359の方がわかりやすいな。
findAllも使ってるし。
2011/12/10(土) 22:38:56.29
普通findallを使ってリスト処理するときにはmember/2を使って

findall(N,(member(M,[1,2,3]),N is M + 1),L),

のようなリスト要素の取り出し方をするのだけれど、>>359のように
2要素ずつ取り出す場合にはmember/2では不可能でappend/3だと
うまくいく。一般に
?- member(A,L). と
?- append(_,[A|_],L). は同義と思われているが、appendの方がスーパーで
あることを如実に示す例ということ。
2011/12/10(土) 23:52:34.14
findallによるリスト処理がよくわからん

# written in ruby
list = [1,2,3,4,5]
newlist = list.map{|e| e += 1}

// written in java
int[] list = new int[]{1,2,3,4,5};
int [] newlist = new int[list.length];
for(int i = 0; i < list.length; i++)
 newlist[i] = list[i] + 1;

をfindallで書くとどうなるの?
2011/12/11(日) 00:04:24.49
>>368

like368(List,NewList) :-
  findall(N2,(member(N1,List),N2 is N1 + 1),NewList).

?- like368([1,2,3,4,5],X).
X = [2,3,4,5,6]

findall/3は第二引数が偽になるまで第二引数全体をcallする。一回真になる度に
第一引数に指定された項をリストに積んでいく。第二引数が最終的に偽になったら
リストの収集を必ず成功裏に了える。積み終わったリストは第三引数と単一化される。
2011/12/11(日) 00:12:52.32
>>369
おお、すごいなあ....
findall/3にはこんな使い方があるんだね
勉強になったよ

% >>368とは別人desu
2011/12/11(日) 00:18:42.22
>>369
ありがとうございます
memberとfindallの挙動とにらめっこしてたらだんだん分かってきました
ちなみにこれはリストの処理方法として一般的なコーディングですか?
大学の演習では習わなかった、というかrubyのArray#mapすらやり方が分からなくて困惑してました(笑
2011/12/11(日) 00:42:44.59
>>371
最近はこの記法を使うことが多くなりました。万能ではありませんが、
この方が宣言的に読むことができる場合が多い。
>>357が指摘されているように、再帰的な定義が読みやすい宣言的な
定義であるとは限らないのです。

注意するべき事は、第二引数に来るSubgoalが非決定的な述語で
あるという点です。述語を定義するときに決定的に定義するか、
それともできる限り非決定的に定義を作って置くかいうことに成ります。
Prologの良さを引き出すためには、非決定的な定義をするスキルを
上げて、積極的にそのような定義をしていく方がいいようです。
373369
垢版 |
2011/12/11(日) 09:17:01.68
member/2を外してfindallの第二引数を定義し直してみましょう。

like368(List,NewList) :-
    findall(N,add_1(List,N),NewList).

add_1([N1|_],N) :- N is N1 + 1.
add_1([_|R],N) :-
    add_1(R,N).

しかし、こうなるとlike368の再帰による定義は

like368([],[]).
like368([N1|R1],[N2|R2]) :-
    N2 is N1 + 1,
    like368(R1,R2).

ですから、何をやってるのかわからない、ということにもなる。

つまり、何故findallによる定義を使うかですが、
memberやappendといった既存の高名な非決定性の再帰述語!!を
使ってadd_1のような定義を省略します。こうすることによって再帰定義の
繰り返しをひとつ回避してほんの僅かですが宣言性を高めようと
しているのです。
2011/12/11(日) 09:43:08.70
>>373
そうではないと思う。add_1/2が非決定性の述語と定義されているから
あるいは、定義することに決めたから、findall/3が必然になったのだ。
データ構造の設計で、リストからリストへと展開することを基本とする
なら、再帰述語中心の定義になるだろうし、
Prologの基本はデータベース述語(単位節)であって本質的に非決定性で
あることは避けられないという立場からの設計なら、集約述語である
findall/3の使用は必須のものとなる。
宣言性の強弱は確かにあるが些細な差であって、より重要なことはこの
ような設計上の差異である。
2011/12/11(日) 11:34:15.70
prologは非決定性を持つといえるのか?
非決定性というが、prologの場合、結果は順序まで含めて決定的。
この点ではSQLはまだ非決定性を持つが、結果を集合として考えるならやはり
決定的かな。

それと、単位節は要するに表でRDBと同じ。
その意味では、prologをprologたらしめているのは、単位節以外にあるといえる。
2011/12/11(日) 13:05:16.05
例えばAとBとCという概念があって,これら単体ではPrologの本質とは言えないが,
これらの概念の組み合わせ方が本質だったりする場合があるので,
そういう場合は、AやBやCという概念を持ついろんなモノをまとめて表にしていくとぼんやりと見えてくる.
メンデレーエフが周期表を発見したときのように.

2011/12/11(日) 17:39:13.48
>>375
Prologは非決定性モデルを、仕様の表に出さない決定的プロセスによって実装している
この立場に立つ人は、Prologでは、解の出現順序が決定的でなければ困るような問題を扱ってはならない

これの一番の利点はモデルを考えるとき(つまり論文を書くとき)に解を普通の集合として取り扱えること

逆に言うと、Prologの実装の決定性に依存するような問題を考えるときにはPrologの利点はなくなり、かえって実装が複雑になる
(もちろん、どんな問題であれ、解を効率的に見つけるというアルゴリズムを考えるときにはPrologの決定的な側面を厳密に考慮しなくてはならない)
2011/12/11(日) 20:01:37.69
prologの言語仕様は、解の出現順序を決定的に定義してたと思う。
ISOの規格文書が見つからないので引用できないけど。
2011/12/11(日) 20:13:59.14
ISOのWebサイトは見づらすぎるね
こちとらAdobe Readerなんてはいってないんだよ
380379
垢版 |
2011/12/11(日) 20:15:03.51
ごめん入出力はISOなのに脳みそはJISと認識してたわ
2011/12/12(月) 06:57:02.61
>>375
Prologの単位節はもうこれ以上、書き換えることのない、どん詰まりの情報だ。
中島秀之氏はこれをプリミティブなものと表現したが。
RDBは列ごとに集合を表すが、Prologの単位節の引数にそういった意味合いは
まったくない。あくまでRDBに模して(RDBとの親和性といった)、引数部分に情報
を配置することが可能というだけ。
Prologのプログラムとはこのどん詰まりに導くためにルールが書かれていると
解釈できるのであって、どちらがPrologの根幹かなどと問うこと自体無意味だ。
2011/12/12(月) 07:03:09.67
RDBの正規化もどん詰まりの情報では?
意味合いを持たせる持たせないの話なら使い手次第では?
2011/12/12(月) 07:26:04.30
>>382
RDBの正規化とProlog項記述の関係については「考えたこともない」状態なので
俄にはまともな返信ができません。
2011/12/12(月) 07:43:31.73
>>381
どちらにというとそうだけど、帰納論理プログラミングなんかは、
明らかに具体的な情報を基礎にルールを見つけて組み立てるという
方向のアプローチですね。そういう方向性のようなものは個々の
Prologプログラマの中にもあるということではないか。Prologを
証明器として捉える人は、ルール重視になるだろうし。
2011/12/12(月) 08:13:19.07
prologをデータベース代わりに使う人は
単位節を主として、ルールを副と考えるよね。
このスレには昔から「prologの根幹は単位節」と唱える人がいるみたいだし。
それはprologの、ではなくデータベースの根幹だといつも思う。
2011/12/12(月) 08:55:46.87
>>385
ルールだけでは成立しない一方、単位節だけでPrologプログラムが
成立してしまうということも言えるのではないか。
387385
垢版 |
2011/12/12(月) 09:00:11.78
>>386
ルールだけでは成立しないは言い過ぎか。なんて言えばいいのかな。
2011/12/12(月) 09:01:39.56
>>386
ルールだけでは成立しないは言い過ぎか。なんて言えばいいのかな。
2011/12/12(月) 09:28:02.13
内包と外延が近い表記法でバランスよくプログラムに記述できる
ところがPrologの大きな魅力だ、というくらいでいいんじゃないか。
2011/12/12(月) 12:59:25.07
よく分からない。

ボディがtrueのルールがファクトなのでしょう?
ルールはファクトを包含しているのでしょう?
なら節は全てルールだけと言えるでしょう?

仮にファクトだけで成立するならそれは命題論理であって、一階述語論理ではない、つまりPrologではない。
2011/12/12(月) 16:09:09.71
>>390
それだと、
先祖関係にはルールがあって、なぜ、親子関係には
ルール(本体)がないの?という問に答えられないよ。
2011/12/12(月) 16:33:00.97
>>375
棄て去った解候補の順序が決まっているかどうかなんて関係あるかな。
2011/12/14(水) 15:55:43.43
Prolog Cafe 1.2.5で
| ?- frend(taro,hanako).
{EXISTENCE ERROR: procedure frend/2 does not exist}
| ?-
などといわれます。このエラーは何ですか?
2011/12/14(水) 19:29:31.30
>>393
節データベースにfriend/2が存在しないという意味。
assert(frend(taro,hanako)).
と入力すれば節データベースに追加される。
確認するには、
listing.
と入力する。

assertせずにソースファイルから節データベースに読み込む場合は、
['hogehoge.pl'].
と入力する。
2011/12/15(木) 07:59:20.08
>>393
friend(taro,hanako).
と定義されているのではありませんか?
2011/12/21(水) 11:28:06.93
データが基礎であり、則ちデータベースが基礎である。 そのデータベースを最も自然体で保持できるプログラム言語は Prologである。これだけで十分で、特に単位節がPrologの基本 などと云う必要もない。
2011/12/23(金) 00:30:36.61
Prologは関係データベースと演繹データベースの派生として解釈できる
しかし、Prologはデータベースが基礎であるというのは言い過ぎ
理由は、永続的に記録できるデータはソースファイルに書いた分だけで、稼働中に追加されたデータはただちに消えるか、Prologの仕様にない方法で記録するしかないから

Prologをデータベースというのなら、C言語もデータベースということになる
C言語の方はさらに表現能力が高い演繹データベースということになる
2011/12/23(金) 05:14:48.50
>>397
Prologをオンメモリデータベースシステムとして捉えたら欠点だらけと
いうことになる。ここでも指摘されているが、assertzが無闇と遅く、
初期状態の回復に時間がかかる。節順序を指定してのUPDATEが
できない、等。しかし、現実にはそれを補強しながら使われている。
Prologのデータベースや単位節を強調した話題は、全部態度表明。
オブジェクト指向の初期に差分プログラミングが強調されたようなレベル。
2011/12/23(金) 07:12:56.08
>>397 Prologデータベースについては、単一レベル記憶的なイメージの 実現を夢見るのが一番ハッピーなのではないか。あまり永続性に 拘るのもいかがなものか。その昔、コアメモリなんてものもあった。
2011/12/23(金) 16:21:20.36
停電したらどうしようという話でしょ。
2011/12/23(金) 16:27:24.34
なんか話がループしてるような気がする。
暇なひとはマインドマップでも書いて見ると良い。
もちえん枝葉にはそれぞれ議論があるだろからきれいな図にはならず、
きっと面倒だろう。
2011/12/23(金) 17:15:31.47
>>400
データベースとして使う時はPrologサーバーとして使うから、
トランザクションの度に子プロセスを生成して、そこにコピーが
できるわけだから、保存ファイルにlistingするのではないかな。
2011/12/24(土) 14:13:21.25
Prologをデータベースとしてとらえたときに、特に優れている点は、複数の関係のJoinしたときのパターンマッチングの速度の速さ
特に劣っている点がデータの更新と永続性
2011/12/24(土) 17:32:27.27
節の定義順を維持しようとすると、全ての節を一度retractしなくては
ならない。ここらあたりの基本動作は改変しないと本格的なデータベースには
使えない。
最低限、節の定義位置の相対番号によりretract/assert指定は可能にする
必要がある。
2011/12/24(土) 17:39:41.47
それから、永続性の問題の方は、オンメモリデータベース共通の問題だが、
停止したあとの再現が確実に行われる必要がある。現在はこれに使用する
ユーティリティの作成から全てをエンドユーザ任せの水準だが、Prolog処理系が
安全で安定した動作/環境を保証する必要がある。
2011/12/24(土) 22:41:14.94
>>403
Joinってそんなに速かったっけ?
Oracleとかと比べたデータあります?
2011/12/25(日) 00:47:56.96
>>406
正確には、演繹データベースの中ではPrologはボディ部のマッチングが特に速く、適切なホーン説が存在すればあればJoinが関係データベースよりも速くなる

r(X,Y) and s(Y,Z) and t(Z)
という結合を考えるとき、Oracleみたいな関係データベースは、rとsとtの全タプルの全組み合わせを生成する

一方Prologでは、例えば
s(Y, "test") :- s(Y,Z),t(Z)
みたいなホーン節があれば前述の結合は、rとsだけの結合の組み合わせさえ生成すればよくなる

Prologは演繹データベースの中でも本体部分のマッチングがかなり高速なので、適当なホーン説があれば関係データベースを含む他のデータベースのjoinよりもPrologのjoinは速い

Prologをデータベースとして利用するときには、データを定期的に走査して、データマイニング技術により、テーブル間の自然結合を高速にするホーン説をストックしている
(逆にいうと、データを頻繁に更新するときにはこの利点はまったくなくなる)
2012/01/09(月) 06:09:35.01
どこで無限ループおきてるかわからないときの
デバック方法みたいなものはないのでしょうか
2012/01/09(月) 06:44:57.67
>>408
http://www.swi-prolog.org/gtrace.html

SWI-Prologなら
gtrace, test_chat.
とかやるとステップ実行したり変数束縛やらコールスタックを確認できる。
410デフォルトの名無しさん
垢版 |
2012/01/15(日) 06:07:27.61
LiLFeSの話題もここでいいの?
2012/01/15(日) 06:10:34.10
>>410
勿論、歓迎だけど、わかる人いるかなぁ。
2012/01/15(日) 06:49:13.11
>>411
レスが付かない場合は、twitterにここのスレへのリンクを貼ればいいんだよ。
#レス番号付きで。2ch嫌いでなければ結構答えてくれる。
2012/01/20(金) 21:44:26.43
プログラムを中断して、その状態を保存しておいて、後で再開するにはどうすればいいのでしょうか?
2012/01/23(月) 17:13:47.54
>>413
どう答えて良いか困惑するけれど、多分「そういうことはできない」というのが解だと思う。
この言語をそういうレベルで使ってはいけないし、サポートする組込述語もない。
2012/01/29(日) 17:12:11.70
PrologってSchemeの list? みたいなリスト判定ってないのかしら?
入れ子になってるリストを1つのリストにまとめるのが出来なくて困ってる

matome([a, b, [c, [d, e], f], g], X).

X = [a, b, c, d, e, f, g]

みたいなのを作りたくてappendいじくり回してるけど出来ない…
2012/01/29(日) 17:49:43.61
>>415
パターンマッチで分岐すればいいだろ。
2012/01/30(月) 16:37:19.88
>>415
list/1は組込述語になっている処理系が多いと思いますが定義するなら

list([]) :- !.
list([_|_]).
418417
垢版 |
2012/01/30(月) 16:40:01.14
>>415
まちがえました。
list(L) :- \+(var(L)),L=[].
list(L) :- \+(var(L)),L=[_|_].

でした。
2012/01/30(月) 16:46:15.87
>>415
list/1の定義ができていれば、

平坦化([],[]).
平坦化([L|R1],L2) :-
    list(L),
    平坦化(L,L1),
    append(L1,R2,L2),
    平坦化(R1,R2).
平坦化([A|R1],[A|R2]) :-
    \+(list(A)),
    平坦化(R1,R2).
2012/01/30(月) 16:53:29.64
>>417 は意図して間違えたわけではなく、本当に間違えたのですが、
>>417 >>418 のような間違いと訂正が「残る」記述であるべきですね。
その点2chのような掲示板は大変よろしい。
書き換えられ、完成されたものには魅力がありません。
2012/02/05(日) 01:47:19.97
>>415
↓のflattenが参考になる
http://www.geocities.jp/m_hiroi/prolog/prolog03.html
422デフォルトの名無しさん
垢版 |
2012/02/15(水) 05:18:36.92
尾崎隆大ってこの世界では有名なの?
2012/02/15(水) 07:11:16.34
>>422
本人ですが、全然有名ではないですよ。
少しPrologに貢献した時期もあったかも
知れませんが、それは1990年より前ですから。
424デフォルトの名無しさん
垢版 |
2012/02/16(木) 14:08:29.13
本人だと・・・
雷電どういうことだ!?
2012/02/16(木) 14:11:21.62
ぬぅ ま・・・まさか
まさかこの目で見ようとは
2012/02/16(木) 16:53:25.72
知っているのか雷電!
2012/02/16(木) 17:29:56.16
うむ
2012/02/16(木) 19:42:37.03
つか本人が降臨しているとはな…ついったでお世話になってますお
2012/02/17(金) 07:51:51.38
prologは再帰を積極的に用いてループを実現していますが。
趣向の域を出ない感じがします。
再帰でなければいけない論拠ってありますか?
2012/02/17(金) 08:23:32.80
>>429
「Prologは」というところを「論理式では」と置き換えて読み直されることを
勧めます。
2012/02/17(金) 08:57:54.03
>>429
http://www.amazon.co.jp/dp/B000JA2VJO
「プログラムの理論」 Zohar Manna著 五十嵐滋訳 を読んでみたら、
としかいえない。
432デフォルトの名無しさん
垢版 |
2012/02/17(金) 10:16:40.69
Prologに限って云えば>>430が正解のような気もするが。
元々、プログラムが停止する(解を持つ)ことを証すための形式として、
再帰が選択されている。
多分>>429はチューリングマシンの計算表を基礎だとして、再帰はループに
変換できるのだから、再帰に終止するPrologは趣向ではないかとしたのだ
と思うが、正しいプログラムを書く一つの戦略として、再帰が選ばれている、
可能な限り再帰で書かせようとするプログラム言語が存在していると考えれば
いいのだろうと思う。
2012/02/17(金) 10:56:33.41
>再帰はループに変換できる
その上で何故趣向と思ったかの一つは。
同じ処理をさせるにしてもは再帰はループよりかなり効率が悪い。
再帰中はローカル変数が解放されないのでメモリの資源効率が悪い。
それにともなって実行効率も落ちます。
2012/02/17(金) 11:00:39.29
再帰をループに自動変換し中間言語を生成するようなアルゴリズムでも
あれば凄いと思うのですが、僕の知っているprologにはそんなものは無いようです。
2012/02/17(金) 11:02:20.28
>>433
これはPrologだけに通用する話ですが、
単一化、バックトラックといった法外にコストのかかる処理を
絶対的な基本としていて、再帰とループの効率の差など、
最初から度外視している系です。
2012/02/17(金) 11:07:45.84
末尾再帰をループに変換する処理系ならあるでしょ
2012/02/17(金) 12:27:27.38
Prologだから論理プログラミングしなきゃいけないなんて誰が決めたんですか…!
あなたがかきたいようにかけばいいじゃないですかぁ…!
2012/02/17(金) 14:29:43.53
>>437
Prologは副目標、節の選択は出現順に逐次的に処理されることになっています。
このことを利用して、多くの利用者がPrologの手続き的解釈という立場に立ってこの言語を
利用しています。

?- repeat,read(X),write(X),X=end_of_file.

というような記述は一見極めて手続き的ですが、repeatの定義

repeat.
repeat :- repeat.

に再帰が「隠されて」います。論理式というモデルに対して何も付け加えたり変更したりして
いないPrologですから、再帰から逃れることはできませんが、隠すことはできるのです。
再帰的定義が連なっている定義は決して読みやすいとは言いがたいことが多く、この読みにくさ
から逃れるために情報の生成器(上の場合生成情報なしのrepeat)に再帰処理を押し込んで、
その後を手続き的に処理するという手法はごく普通のものです。
2012/02/17(金) 17:45:06.40
とりあえず末尾再帰最適化とか、
proper tail callとか勉強してくれ。> 再帰くん
2012/02/26(日) 17:59:36.65
>>397
「Prologの仕様にない方法で記録するしかないから」
とあるけど、これはどういう意味なのだろうか。
2012/02/29(水) 07:24:48.76
Prologの仕様のひとつにISO規格があるけれど、
あまり逸脱しないための枠組みくらいの意味しか
ない。そのくらい無視されている。
442デフォルトの名無しさん
垢版 |
2012/02/29(水) 07:32:27.54
ISO規格の日本語訳が必要だね。それへのリンクをWikipediaの
冒頭付近に持ってくる。
2012/02/29(水) 07:34:51.94
正式にPrologと名乗っていいかどうかを承認する機関とかあればいいけど
そこまでしてイソイソする需要もないんだし
どうしてもイソにこだわるならSWI-Prologとかならドキュンメントにイソってる述語かどうかかいてあるから
イソい述語だけ使うようにすればいいんじゃないかな
2012/02/29(水) 07:39:57.82
イソい述語が貧弱すぎるのもダメなんじゃないかな。
最小限のイソの上にPure 100% Prologな述語を作りこんでいくって言う発想は
どうしても性能的に問題がでてくるでゲソ?
だからイソ述語を沢山定義していったほうがいいと思うの。
Level 1, 2, 3とか段階に分けてもいいかもしれんけどね。
レベルが高いほど高機能で低いほどよりプリミティブな述語なの。
2012/02/29(水) 07:40:28.74
>>443
少なくとも日本ではSWI-Prologが標準に近い地位にあるから、
日本語訳するとしたら、こちらの方だろうな。
2012/02/29(水) 07:43:39.90
そういえば、SWI-Prologのdoc_serverだっけ?
pldoc形式かなんかで書いたドキュメント文の末尾にピリオドが自動で付与されるから、
出力が「こんにちは。.」みたいな不恰好になっちゃうよね。
2012/02/29(水) 07:44:07.13
もしかしてイカ娘さんの登場かな?
2012/03/12(月) 23:21:34.18
初心者です。
Prologのソースファイルに
do :- ...
do.
のような記述がよくあるんですが、これってdoのbodyをdoでくるまずそのまま書いちゃだめなんでしょうか?
2012/03/12(月) 23:42:15.80
>>448
具体的なコードをコピペしてもらえると、期待する答えがもらえやすいと思う

とりあえず可能性を推測してみる
・1行目のbody部では(たとえばバックトラックを応用した)手続き型の処理が書かれていて、
 必ず否定で処理が終わる
 でも、処理全体としては肯定で終了させたいから、2行目に必ず真となる述語が置かれている
・述語doに引数があり、複数のbody付き定義でcase文に相当する多分岐処理を記述している
 そして、最後のbody無しdoは(case文における)空のdefault節を表現している
2012/03/13(火) 00:04:25.78
>>449
http://hlab.ta.chiba-u.jp/article.php?story=20090206114807903
このコードです。まったくの初心者なので支離滅裂なことを言っているかもしれませんが、
・initCells :- hogehoge.のあとinitCells.と書いているのでgoの中でinitCellsを改めて呼び出す必要はないのでは?
・initCellsは常に否定で終わるのに、goの中の以降の処理が実行されているのはなぜ?
というのが疑問です。
2012/03/13(火) 00:38:43.29
>>450
まず最初に、コードの解説から
これは>>449で書いた最初のケースの具体例で、手続き的な2重ループ処理だね
述語between/3はバックトラックで再呼び出しされるたびに別の解を返すから、
その between(1, MX, I), between(1, MY, J), ...., fail. という部分は、
以下のCコードの処理と似ている
 for (i = 1; i <= mx; i++) {
   for (j = 1; j <= my; j++)
     ....
 }
バックトラックは、initCells :- ... の最後のfail呼び出しを契機に発生し、
between x2が返す全ての解を探索し終えると(=二重ループ処理を抜けると)否定を返す
でも、(>>450で書いたように)initCells全体の処理は肯定で終わらせたいから、
最後にbody部が空な(=常に真を返す) initCells. が置かれてる
Prologでしばしば見かける手続き的なコーディング技法だね(自分は好まないけど....)

次に、質問について答えよう
>・initCells :- hogehoge.のあとinitCells.と書いているので
> goの中でinitCellsを改めて呼び出す必要はないのでは?

initCells定義のbody内でinitCellsが(再帰的に)呼ばれているのは、ループ処理を実現するため
だから、そのループを開始するきっかけとしてgoからinitCellsの呼び出しが必要になる

>・initCellsは常に否定で終わるのに、goの中の以降の処理が実行されているのはなぜ?

最後に置かれた(body部が空の)initCells定義が、常に肯定(真)を返すから
2012/03/13(火) 00:45:08.83
>>450
以下のPrologプログラミング解説ページ内にある、
「繰り返し - 失敗駆動ループ」という節が参考になると思う

・M.Hiroi's Home Page / Prolog Programming
 http://www.geocities.jp/m_hiroi/prolog/prolog03.html#chap14
2012/03/13(火) 11:16:10.30
>>451
理解できました。initCells.を対話シェルでの質問と同じように捉えていました。
あくまで引数なし体部なしの述語定義なんですね。
2012/03/17(土) 20:48:38.00
>>440
Prologプログラマが自分で勝手に作った構文でパーサやデコーダを作ってデータをテキストやバイナリに変換してファイルに書き込む
という意味
2012/03/18(日) 05:29:34.55
>>454
現在のProlog処理系環境では、
listing と consult が最速。
clause や assert を使って
自前で処理すると遅くなる。

get_heap_vector 的な述語があるなら、
そういう可能性もあるだろうけれど。
2012/03/19(月) 02:12:06.59
Prolog で、例えば eq という同値関係を記述するのに
eq(X, X).
eq(X, Y) :-
 eq(Y, X).
eq(X, Z) :-
 eq(X, Y),
 eq(Y, Z).
としたのですが、この関係を満たさない質問を Prolog に与えると無限ループに陥ります。
例えば
?- eq(a,a).
yes
ですが
?- eq(a,b).
(無限ループ)
となってしまいます。
2012/03/19(月) 07:30:01.96
>>456
これは左再帰と呼ばれる問題です。
Prologが自然言語解析に向いていると期待されて、
集中して研究された始めた時にいきなりこの問題で躓きました。

p :- p, ...

という定義をすると無限ループに陥ります。一番左(実効として) に
pがくる再帰が不可ということになります。
>>456 の例ですと、第二節の本体からの呼び出し :- e(Y,X).
で :- e(b,a). は
第一節 e(X,X). と適合せず、第二節 e(X,Y) :- e(Y,X). が適合して
e(b,a) :- e(a,b). となり、 :- e(a,b). を呼び出すことになり、
最初の質問に戻ってこれを繰り返すことになります。

結論としてPrologで第二節、第三節で意図された定義は不可能です。
2012/03/19(月) 09:58:06.54
解決方法

1. eqを述語でなく関数とする
2. XSBのような導出節をテーブル化してくれる処理系を使う
3. マジックセット変形する
2012/03/22(木) 07:28:43.08
おはようございます
いま一筆書きゲームがブームですが
Prologで一筆書きを解けますか?

ただし上記ゲームには、一部の経路に
・一方通行
・必ず2回通る経路
があり
・ワープ1つ(一方の点に入ったら他方の点に強制ワープ。何度も使える。)
があります
2012/03/22(木) 19:24:15.07
要はそういうプログラムを書けってことね
2012/03/22(木) 19:47:20.63
学校の宿題は自分で考えたほうが本人の為になると思うな
2012/03/22(木) 21:13:34.63
Prologで表現できるかできないかを聞きたいだけ
できるなら自分で作るし
できないなら他を当たる
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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