トップページ⇒tech
245コメント149KB

Prologの宿題片付けます

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2010/04/23(金) 16:02:04
Prologで宿題が出たら、自分でプログラムが書くことができた
人も、思い悩んでいる人も、ここにその問題を載せてください。
宿題はその講座がどんな内容かをちょっとだけ垣間見させて
くれます。
全国の大学に100を越える講座があるといわれるProlog。
どんな宿題がでてくるのか楽しみです。
0159デフォルトの名無しさん2010/11/02(火) 09:13:57
<問題>
ゼロでない整数x のn 乗xn の再帰式
x^n = 1 (when n = 0)
x^n = x * x^(n-1) (when n > 0)
を利用したプログラムを書きなさい。
0160デフォルトの名無しさん2010/11/04(木) 16:09:54
>>159
http://nojiriko.asia/prolog/prolog_159.html
0161デフォルトの名無しさん2010/11/05(金) 15:25:51
>>158
http://nojiriko.asia/prolog/prolog_158.html
算数的な解法は後に。
0162デフォルトの名無しさん2010/11/07(日) 18:55:03
以下は、
「DNS & BIND クックブック ネームサーバ管理者のためのレシピ集」Cricket Liu 著 伊藤高一監訳 田淵貴昭
訳 オライリー・ジャパン発行 オーム社発売 2003年4月 のp75から採りました。
<問題>
ネームサーバが特定の応答を一定の順序で返すように設定したい。

cyclic
    これがデフォルトで、ラウンドロビンといわれることもある。レコードが返される順序は応答の
    度に循環され、前回の応答で最初に返されたレコードは、その次の応答では最後に移動される。
fixed
    レコードをいつも同じ順番で返答する。
random
    レコードをランダムな順番で返答する。

上記の仕様を満たすように述語を定義しなさい。
0163デフォルトの名無しさん2010/11/08(月) 06:37:06
>>158 (算数的解法) 引数に何を明示するかが課題。

'ノートを7冊ずつ配ると28冊余り,10冊ずつ配ると最後の一人にわたすノートは他の半分にも達しませんでした。ノートの数と人数を求めなさい。'(_ノートの数,_人数) :-
    '10冊ずつ配るとひとり少ない人数分だけは完全にあるということです',
    'これを _10冊を完全に配ることのできる人数 とすると',
    '一旦最後ひとり分(7個)も取り崩して',
    '28冊に加えてからこれを(10-7)個ずつ確実に渡すことのできる人数が_10冊を完全に配ることのできる人数ということになります'(_10冊を完全に配ることのできる人数),
    余りが最後の人が受け取る冊数になり、これは10冊の半分未満でないといけません,
    人数はそれに1を加えたものであり(_10冊を完全に配ることのできる人数,_人数),
    本の冊数は(_人数,_本の冊数).

'28冊に加えてからこれを(10-7)個ずつ確実に渡すことのできる人数が_10冊を完全に配ることのできる人数ということになります'(_10冊を完全に配ることのできる人数) :-
    _10冊を完全に配ることのできる人数 is (28 + 7) // (10 - 7).

余りが最後の人が受け取る冊数になり、これは10冊の半分未満でないといけません :-
    _最後の人が受け取る冊数 is (28 + 7) mod (10 - 7),
    _最後の人が受け取る冊数 < 10 // 2.

人数はそれに1を加えたものであり(_10冊を完全に配ることのできる人数,_人数) :-    _人数 is _10冊を完全に配ることのできる人数 + 1.

本の冊数は(_人数,_本の冊数) :-
    _本の冊数 is 7 * _人数 + 28.

%%%%%%%%%%%%%%%%%%%%%%%%% 注釈的述語 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'10冊ずつ配るとひとり少ない人数分だけは完全にあるということです' :- true.
'これを _10冊を完全に配ることのできる人数 とすると' :- true.
'一旦最後ひとり分(7個)も取り崩して' :- true.
0164z2010/11/11(木) 17:03:33
{if-else文} 身長と体重のデータを読み込み、下の定義から体型を判定するプログラムを作成せよ。

定 義:身長h(cm),体重w(Kg)とすると

w < (h-95)*0.82 やせすぎ(SLIM)

w > (h-95)*1.10 ふとりすぎ(FAT)

その中間 正常(NORMAL)

0165デフォルトの名無しさん2010/11/12(金) 09:15:20
>>164
身長h(cm),体重w(Kg) のh,w,cm,Kg をどうプログラムに反映するか悩みます。
0166デフォルトの名無しさん2010/11/12(金) 09:22:59
:- op(250,xf,cm).
:- op(250,xf,'Kg').

体型を判定する(_h cm,_w 'Kg','やせすぎ(SLIM)') :-
    _w < (_h-95) * 0.82,!.


というような定義は可能ですが、引数にリスト以外の複合項がくるのが気に入らない。
0167デフォルトの名無しさん2010/11/13(土) 10:43:10
>>164
% こういう定義の仕方を最近は好んでいます。
% 身長を読み込む/1,体重を読み込み/1, は行数の関係から省略します。
% 全文は http://nojiriko.asia/prolog/prolog_164.html を参照してください。

'定 義:身長h(cm),体重w(Kg)とすると w < (h-95)*0.82 やせすぎ(SLIM) w > (h-95)*1.10 ふとりすぎ
(FAT) その中間 正常(NORMAL)  '(_体型判定) :-
    身長を読み込む(_身長),
    体重を読み込む(_体重),
    '身長、体重から体型を判定する'(_身長,_体重,_体型判定).

'身長、体重から体型を判定する'(_身長,_体重,_体型判定) :-
    '体重が (身長-95) * 0.82 より小さい時は'(_身長,_体重,_体型判定).
'身長、体重から体型を判定する'(_身長,_体重,_体型判定) :-
    '体重が (身長-95) * 0.10 より大きい時は'(_身長,_体重,_体型判定).
'身長、体重から体型を判定する'(_身長,_体重,_体型判定) :-
    'その中間'(_身長,_体重,_体型判定).

'体重が (身長-95) * 0.82 より小さい時は'(_身長,_体重,'やせすぎ(SLIM)') :-
    _体重 < (_身長-95) * 0.82,!.

'体重が (身長-95) * 0.10 より大きい時は'(_身長,_体重,'ふとりすぎ(FAT)') :-
    _体重 > (_身長-95) * 1.10,!.

'その中間'(_身長,_体重,'正常(NORNAL)') :-
    _体重 >= (_身長-95) * 0.82,
    _体重 =< (_身長-95) * 1.10,!.
0168デフォルトの名無しさん2010/11/16(火) 10:15:32
<問題>
以下のようにスポーツができるか否かを判断するプログラムを考える。
1. 天気が晴れの場合は, テニスコードが空いているならテニスができる。
2. 天気が晴れでない場合は, 卓球室があいているなら卓球ができる。
3. 上記以外の場合はなにもしない。
ここで天気状況などの事実を次のように定義する。
weather(clear). % 天気が晴れ(これを削除すれば「天気が晴れでない」となる)
empty(tennis-court). % テニスコードが空き
......
また、スポーツができるか否かを上記事実に基つく推論する規則play-sport() は次のように定義
する。
play-sport :- weather(clear), !, empty(tennis-court), write('tennis').
play-sport :- empty(table-tennis-court), write('table tennis').
これらの規則により
weather(clear)(天気が晴れ)とempty(tennis-court)(テニスコードが空き)がともに真の
場合は, 1番目の規則が成立する。
weather(clear) が真でもempty(tennis-court) が偽の場合、1番目の規則は成立しない。しか
も既に「!」を通過したため、2 番目の推論規則がカットされ、全ての規則が成立しないこ
とになる。
weather(clear) が偽の場合は,「!」を通過せずに1番目の規則が成立しなくなるため、2 番
目の規則が適用さる。これでempty(table-tennis-court) の真偽により2番目の規則が成立す
るか否かが決まる。
0169デフォルトの名無しさん2010/11/16(火) 10:48:59
:- op(650,xfx,が).

どんなスポーツをするか(テニス) :- テニスをする,!.
どんなスポーツをするか(卓球) :- 卓球をする,!.
どんなスポーツをするか(なにもしない) :- なにもしない.

テニスをする :- テニスができる.

卓球をする :- \+(天気 が 晴れ),卓球ができる.

なにもしない :-\+(テニスをする),\+(卓球をする).

テニスができる :-
'天気が晴れの場合は, テニスコードが空いているならテニスができる。'.

'天気が晴れの場合は, テニスコードが空いているならテニスができる。' :-
天気 が 晴れ,
テニスコード が 空いている.

卓球ができる :- 卓球室 が あいている.

% 例えば以下のような定義を書く。
天気 が 晴れ.

テニスコード が 空いている.

卓球室 が あいている.
0170デフォルトの名無しさん2010/11/16(火) 10:51:02
:- op(750,xfx,が).

どんなスポーツをするか(テニス) :- テニスをする,!.
どんなスポーツをするか(卓球) :- 卓球をする,!.
どんなスポーツをするか(なにもしない) :- なにもしない.

テニスをする :- テニスができる.

卓球をする :- \+(天気 が 晴れ),卓球ができる.

なにもしない :-\+(テニスをする),\+(卓球をする).

テニスができる :-
        '天気が晴れの場合は, テニスコードが空いているならテニスができる。'.

'天気が晴れの場合は, テニスコードが空いているならテニスができる。' :-
        天気 が 晴れ,
        テニスコード が 空いている.

卓球ができる :- 卓球室 が あいている.

% 例えば以下のような定義を書く。
天気 が 晴れ.

テニスコード が 空いている.

卓球室 が あいている.

0171デフォルトの名無しさん2010/11/16(火) 11:05:04
なにもしない を定義したあたりが怖いのだけれども、
一応これで合っているか。
0172デフォルトの名無しさん2010/11/17(水) 04:44:42
超難問を見つけた 「管理会計」C.T.ホーングレン著 小倉栄一郎・加藤勝康 共著
                          日本生産性本部発行 1974年 p440
<問題>
フラン社の推測によれば,もしある専用機械を原価$9,000で購入すれば,つぎの
5か年での年間の現金支出をともなう操業費を,毎年$2,500節約することができる.
存存価額は,等差級数法によって減価償却費を計算する場合には税金計算上ゼロであ
るが,$1,000であると期待される.税引後の希望最低投資利益率は10%であり,所得
税率は経常所得にたいして40%である.割引キャッシュ・フロー法を用いてこの投資
が望ましいものであるか否か示せ.
0173デフォルトの名無しさん2010/11/17(水) 04:49:57
>>172 誤植 <最後の行>
が望ましいものであるか否か示せ. -->
が望ましいものであるか否かを示せ.
0174デフォルトの名無しさん2010/11/17(水) 04:55:16
もう、一ヶ所誤りがあったので書き直します。
超難問を見つけた 「管理会計」C.T.ホーングレン著 小倉栄一郎・加藤勝康 共著
                     日本生産性本部発行 1974年 p440より
<問題>
フラン社の推測によれば,もしある専用機械を原価$9,000で購入すれば,つぎの
5か年での年間の現金支出をともなう操業費を,毎年$2,500節約することができる.
残存価額は,等差級数法によって減価償却費を計算する場合には税金計算上ゼロであ
るが,$1,000であると期待される.税引後の希望最低投資利益率は10%であり,所得
税率は経常所得にたいして40%である.割引キャッシュ・フロー法を用いてこの投資
が望ましいものであるか否かを示せ.
0175デフォルトの名無しさん2010/11/17(水) 14:18:52
所得税率高すぎないか?
0176デフォルトの名無しさん2010/11/17(水) 14:27:46
>>175
公民権法案の時代だから高かったなんてことないかな。
0177デフォルトの名無しさん2010/11/19(金) 09:18:40
<問題>
ポーカーの役、ストレートとフラッシュについての問題です。
どちらの役が出現し難いかを示すPrologプログラムを書きなさい。
0178デフォルトの名無しさん2010/11/22(月) 17:01:47
>>177
生まれて始めての Prologプログラムと思って頑張ってみたけど
フラッシュの数え上げしかできないよう
何だよストレートの組み合わせ44通りって・・・しっかりしろ俺
0179デフォルトの名無しさん2010/11/23(火) 09:56:33
結構Prolog向き課題なのかもしれないので
http://hibari.2ch.net/test/read.cgi/tech/1289913298/302
# [1] 授業単元:プログラミングC言語
# [2] 問題文:診断メーカー風のプログラムを作成しなさい。
#       名前を入力し、その名前に基づき何かしらの情報を出力。
#       .txtファイルを読み込み出力できるものにする事。
#       (オプション)日替わりで表示結果を変更。複数の組み合わせなど。
#
0180デフォルトの名無しさん2010/12/01(水) 10:39:01
<問題>
not(P) :- P, !, fail.
not(P).

のnot(P) を利用しプログラムnot_and(A1,A2) を書きなさい。但しnot_and(A1,A2) は
A1,A2 ともに成立する場合だけ成立しない。以下にこのプログラムの実行結果を示す.
0181デフォルトの名無しさん2010/12/02(木) 11:06:42
>>180
not_and(A,B) :- not(A),not(B).
not_and(A,B) :- not(not(A)),not(B).
not_and(A,B) :- not(A),not(not(B)).
not_and(A,B) :- not(not(A)),not(not(B)),fail.
0182デフォルトの名無しさん2010/12/02(木) 11:09:01
>>180
こういう指定だったか。
not_and(A1,A2) :- not(A1),not(A2).
not_and(A1,A2) :- not(not(A1)),not(A2).
not_and(A1,A2) :- not(A1),not(not(A2)).
not_and(A1,A2) :- not(not(A1)),not(not(A2)),fail.
0183デフォルトの名無しさん2010/12/11(土) 10:57:08
<問題>
慶応元年以降の和暦西暦変換述語を
書きなさい。
0184デフォルトの名無しさん2010/12/11(土) 18:40:29
<問題>
8Queensを解け
0185デフォルトの名無しさん2010/12/14(火) 01:36:47
http://hibari.2ch.net/test/read.cgi/tech/1286791669/538
http://hibari.2ch.net/test/read.cgi/tech/1286791669/539
# ../test/read.cgi/tech/1286791669/536
# prologでtwitterクローン作ったらどうなるの?
#
# どれだけ便利な言語なのか推し量るには実際のプログラムを見ないことには判断できない
#
# twitterクローンもしくは簡単なwikiでもいいわ
0186デフォルトの名無しさん2011/01/04(火) 15:38:54
<問題>
path(V,V).
path(V,U) :- link(V,W), path(W,U).

newLink :- read(X), oneLink(X).
oneLink(end_of_file) :- !.
oneLink(X) :- asserta(X), newLink.
add(F) :- asserta(link(dbmark,0)), see(F),
newLink, seen, see(user).

clear :- get_next, clear.
get_next :- retract(link(X,_)), !, X \== dbmark.

このプログラムを拡張して始点から終点までの経路を表示できるようにしなさい。

入力ファイルは以下

link(ac,gm).
link(gm,rq).
link(rq,lh).
link(lh,sh).
link(sh,lb).
link(lb,ad).
link(ad,ac).

実行例

| ?- add(map).
yes
| ?- path(ac,ad).
ac->gm->rq->lh->sh->lb->ad
yes
0187デフォルトの名無しさん2011/01/07(金) 05:40:47
>>186
バックトラックが起きた時の表示の工夫をしないならば、

path(V,V) :- write('->'),write(V),nl.
path(V,U) :- link(V,W),write(V),write('->'),path(W,U).

だけでいいと思う。
0188デフォルトの名無しさん2011/01/07(金) 09:00:50
>>183
http://nojiriko.asia/prolog/prolog_183.html
0189デフォルトの名無しさん2011/01/07(金) 10:45:32
>>184
誰が書いても同じようなコードになりそうな気がするが、
本当にそうであるか、主要なProlog書籍に載っている
8クィーンのソースコードを比較するサイトを準備中。
0190デフォルトの名無しさん2011/01/07(金) 12:20:17
8クィーンだけをテーマした本はさすがにないけれど、
「楽しいプログラミングII 記号の世界」 中島秀之/上田和紀著
岩波書店 1992年 http://www.amazon.co.jp/dp/4000077554/

これを写し取って解説を加えるだけで、結構大仕事。
ぜひ一読を勧めます。
0191デフォルトの名無しさん2011/01/13(木) 13:19:37
>>190
これいい本なんだよね。ほとんど知られていないのが残念。
0192デフォルトの名無しさん2011/01/27(木) 21:09:43
<問題>
選手の成績順のリストと、一位からの入賞賞金のリストがあります。一位から
順に賞金を賦与するのですが、入賞者の中で同順位があった場合はその順位の
賞金と一つ下位の賞金の合計を両者で分け合います。さらに多くの同順位者が
いた場合は、同様に下位の賞金を合計していって、同順位者で分け合います。
下位の入賞者が多数いて入賞者数を超えてしまったら、該当する全員を入賞扱い
として一番下位の賞金を分け合うこととします。
このような3引数の述語 入賞賞金賦与を定義しなさい。
0193デフォルトの名無しさん2011/02/17(木) 13:44:04
ペペロンチーノのレシピが以下のように定義されています。
作り方の定義の部分を同時進行を示すことができるように改めてください。

レシピ(ペペロンチーノ,材料,'塩,コショウ',6 人前,適量).
レシピ(ペペロンチーノ,材料,'オリーブ油',6 人前,200 cc).
レシピ(ペペロンチーノ,材料,'にんにく(つぶしたもの)',6 人前,3-4 片).
レシピ(ペペロンチーノ,材料,'赤とうがらし',6 人前,1 個).
レシピ(ペペロンチーノ,材料,'パセリのみじん切り',6 人前,2-3 枚 分).
レシピ(ペペロンチーノ,作り方,1,'にんにくを細かく刻む').
レシピ(ペペロンチーノ,作り方,2,'スパゲッティをやわらかくなるまでゆでる').
レシピ(ペペロンチーノ,作り方,3,'刻んだにんにくと赤とうがらしをオリーブ油で十分に炒める').
レシピ(ペペロンチーノ,作り方,4,'ゆで上がったスパゲッティの水気を切り、深いさらに入れる').
レシピ(ペペロンチーノ,作り方,5,'にんにくを炒めた鍋からオリーブ油を直接皿に注ぐ').
レシピ(ペペロンチーノ,作り方,6,'黒コショウを振りかけてよく混ぜる').
01941932011/02/17(木) 15:15:35
大事なものを落としていました。

:- op(600,xf,cc).
:- op(600,xf,片).
:- op(600,xf,枚分).
:- op(600,xf,個).

これを先頭に置く必要がありますね。
0195デフォルトの名無しさん2011/02/18(金) 06:36:27
>>192
http://nojiriko.asia/prolog/prolog_192.html

0196デフォルトの名無しさん2011/02/18(金) 07:17:37
<問題>
>>193 の定義のうち、
レシピ(ペペロンチーノ,作り方,2,'スパゲッティをやわらかくなるまでゆでる').

'スパゲッティをやわらかくなるまでゆでる'を述語として
定義しなさい。将来調理ロボットがこの定義に従い、
料理することになるとして。
0197デフォルトの名無しさん2011/03/04(金) 18:36:00.34
<問題>
リストからランダムにひとつずつ情報を取り出します。
ただし、一度取り出した情報は引かないこととします。
このような非決定性の述語を定義してください。
第一引数にリスト、第二引数に何番目の要素を引いたか、第三引数に取り出した要素,
最後の第四引数に取り出された要素以外の要素ならびを持つものとします。
0198デフォルトの名無しさん2011/03/05(土) 07:42:24.95
>>197
要素ならび -> 要素リスト です
0199デフォルトの名無しさん2011/03/05(土) 08:07:48.64
<問題> --灘中入試問題--
ある4けたの整数を9倍したとき,やはり4けたの
整数で各位の数字の順序が逆になるといいます。
このとき,始めの整数の十の位の数字は何ですか。
0200デフォルトの名無しさん2011/03/05(土) 08:49:12.36
0000
1089
0201デフォルトの名無しさん2011/03/05(土) 09:12:43.22
>>199
算数的な解法?
1) 整数の範囲は1000~1111である
2) 最初のけたと9を掛けた最後のけたは同じ数字だから最後のけたは9である
3) 100の位は0か1にしかならないが、1だとすると1109*9しかないがこれは適合しない
4) したがって100の位は0、9を掛けた数字の10の位は0である
5) 10の位の9倍と1の位の繰り上がり8を加えものが0であるから、10の位に9を掛けたものの下一桁は
  2である
6) 9倍してその下一桁が2になるのは8*9以外にない。
7) 答えは8である。


0202デフォルトの名無しさん2011/03/07(月) 20:07:39.26
>>199

'ある4けたの整数を9倍したとき,やはり4けたの整数で各位の数字の順序が逆になるといいます。このとき,始めの整数の十の位の数字は何ですか。'(_始めの整数の十の位の数字) :-
    '9倍して9999を超えない最大数'(_9倍して9999を超えない最大数),
    for(1000,_ある4桁の数,_9倍して9999を超えない最大数),
    number_chars(_ある4桁の数,Chars),
    reverse(Chars,RChars),
    _ある4桁の数の9倍の数 is _ある4桁の数 * 9,
    number_chars(_ある4桁の数の9倍の数,RChars),
    始めの整数の十の位の数字は(_ある4桁の数,_始めの整数の十の位の数字).

始めの整数の十の位の数字は(_ある4桁の数,_始めの整数の十の位の数字) :-
    _答え is (_ある4桁の数 // 10) mod 10.

'9倍して9999を超えない最大数'(_9倍して9999を超えない最大数) :-
    _9倍して9999を超えない最大数 is 9999 // 9.
0203デフォルトの名無しさん2011/03/07(月) 20:22:26.24
<問題>
>>199 の問題に対し、出来る限り>>201の考え方に
沿った述語定義によって解を示す、Prologプログラムを
書きなさい。
0204デフォルトの名無しさん2011/03/09(水) 11:14:07.62
<問題>

足引之 山河之瀬之 響苗尓 弓月高 雲立渡

万葉集の第七巻(1088)に出てくる柿本人麻呂の歌です。
日めくり万葉集というテレビ番組でガンダムの安彦良和さんが
興味深いコメントをされていて、題材にしたくなりました。

さて、この歌の出来る限り詳しい解説をPrologの述語として
定義してください。
0205デフォルトの名無しさん2011/03/26(土) 12:21:06.56
>>203
例えば、ここはどう定義すればよいのだろうか。

2) 最初のけたと9を掛けた最後のけたは同じ数字だから最後のけたは9である
0206デフォルトの名無しさん2011/03/26(土) 12:28:36.89
ある4けたの整数の第一桁は1しかない。1を9倍する9であるが、
繰り上がりが生じると、4桁を維持できなくなる。
したがって繰り上がりは生じない。すなわち9である。

という論理の表現。
0207デフォルトの名無しさん2011/05/25(水) 02:24:56.80
http://beebee2see.appspot.com/i/azuY_PuCBAw.jpg
簡単で申し訳ないが助けてくれm(_ _)m
0208デフォルトの名無しさん2011/05/25(水) 05:53:24.47
>>207
http://nojiriko.asia/prolog/prolog_207.html
0209デフォルトの名無しさん2011/05/25(水) 14:50:06.37
本当ににありがとうm(_ _)m
助かります。
0210デフォルトの名無しさん2011/07/15(金) 17:19:45.63
>>204
パイプオルガンの響きが立ち昇っていくような歌だね。
0211デフォルトの名無しさん2011/07/17(日) 23:14:43.69
ここで質問する内容かどうか分かりませんが
差分リストで以下の述語を書く方法はありますか?

concatmap(F,[X|Xs],Ys) :-
call(F,X,As),
concatmap(F,Xs,Bs),
append(As,Bs,Ys).
concatmap(_,[],[]).
0212 忍法帖【Lv=10,xxxPT】 2011/07/18(月) 00:38:34.36
>210
( ´,_ゝ`)プッ
0213デフォルトの名無しさん2011/07/21(木) 06:16:09.94
>>210
弓月嶽は、伊勢に遷るまで天皇の神が祀られていた
三輪山のとなりの山で、天照大神がここに降り立ったと
少なくとも安彦さんは解釈しているようだ。
そのことを知っていた人麻呂が神々しさを感じて、この歌を
詠んだ。
0214デフォルトの名無しさん2011/07/21(木) 06:26:33.56
たとえば、以下のような述語を定義していくことは可能だが、
>>213のような領域の述語定義となると、やはり大変。

足引之はあしひきのと読み山に掛かる枕詞である :-
    枕詞(足引之),
    訓み(足引之,あしひきの).
    掛かり(足引之,山).
0215デフォルトの名無しさん2011/07/29(金) 21:43:15.27
与えたリストをシャッフルするshuffle/2を実装してください。

?- shuffle([a,b,c], X).
X = [b,a,c];
false
0216デフォルトの名無しさん2011/07/30(土) 05:05:44.82
>>215
% SWI-Prolog 仕様

shuffle(_元のカードの束,_切られたカードの束) :-
    length(_元のカードの束,_カードの枚数の束),
    length(Ln,100),
    shuffle(Ln,_カードの枚数,_元のカードの束,_切られたカードの束).

shuffle([],_,_カードの束,_カードの束) :- !.
shuffle([_|Ln],_カードの枚数,_カードの束1,_カードの束) :-
    _乱数値 is random(_カードの枚数),
    length(L0,_乱数値),
    append(L0,L1,_カードの束1),
    append(L1,L0,_カードの束2),
    shuffle(Ln,_カードの枚数,_カードの束2,_カードの束).
02172162011/07/30(土) 05:09:16.94
すみません。一ヶ所まちがえた。
>>215
% SWI-Prolog 仕様

shuffle(_元のカードの束,_切られたカードの束) :-
    length(_元のカードの束,_カードの枚数),
    length(Ln,100),
    shuffle(Ln,_カードの枚数,_元のカードの束,_切られたカードの束).

shuffle([],_,_カードの束,_カードの束) :- !.
shuffle([_|Ln],_カードの枚数,_カードの束1,_カードの束) :-
    _乱数値 is random(_カードの枚数),
    length(L0,_乱数値),
    append(L0,L1,_カードの束1),
    append(L1,L0,_カードの束2),
    shuffle(Ln,_カードの枚数,_カードの束2,_カードの束).
0218デフォルトの名無しさん2011/07/30(土) 05:52:18.51
>>215
% 一回ずつ非決定性述語仕様で切っていくには、

shuffle(_元のカードの束,_切られたカードの束) :-
    length(_元のカードの束,_カードの枚数),
    _乱数値 is random(_カードの枚数),
    length(L0,_乱数値),
    shuffle(L0,_元のカードの束,_切られたカードの束).

shuffle(L0,_元のカードの束,_切られたカードの束) :-
    append(L0,L1,_元のカードの束),
    append(L1,L0,_切られたカードの束).
shuffle(L0,_元のカードの束,_切られたカードの束) :-
    append(L0,L1,_元のカードの束),
    append(L1,L0,_切られたカードの束1),
    shuffle(_切られたカードの束1,_切られたカードの束).
0219デフォルトの名無しさん2011/07/30(土) 06:01:16.05
>>218
実際の動作に近く、好ましくみえるのだが、これを使って
しかも、何回切るかという指定をするとなると大変むずかしい。
大域変数や一時述語を作って、assert/retractを繰り返さない限り、
不可能。
>>216 のように引数に切る回数を入れるように拡張する
必要がある。すなわち、この述語のなかにforを組み込む。
02202192011/07/30(土) 06:02:27.82
>>219
大域変数を使用するか、・・・
02212152011/07/30(土) 10:25:20.82
>>216
ありがとうございます。
私は組み込み述語のselectを使って作ってみました。

% SWI-Prolog

shuffle([], []) :- !.
shuffle(_入力リスト, _出力リスト) :-
  length(_入力リスト, _リスト長),
  _選択位置 is random(_リスト長),
  nth0(_選択位置, _入力リスト, _選択要素),
  select(_選択要素, _入力リスト, _残りリスト),
  shuffle(_残りリスト, _出力リスト1),
  _出力リスト = [_選択要素 | _出力リスト1].
02222152011/07/30(土) 10:40:31.85
「シャッフル」という言葉を、単純にランダムのリストの要素を
並び換えるという意味で使いました。
すみません。説明不足でした。
02232152011/07/30(土) 10:42:10.29
×単純にランダムのリストの要素を並び換える
○単純にリストの要素をランダムに並び換える
0224デフォルトの名無しさん2011/08/01(月) 08:18:45.05
>>221
一番自然なコードは

shuffle_n(0,_,_リスト,_リスト) :- !.
shuffle_n(_n,_カードの枚数,_入力リスト,_出力リスト) :-
    shuffle(_入力リスト,_切られたリスト),
    _n_1 is _n - 1,
    shuffle_n(_n_1,_カードの枚数,_切られたリスト,_出力リスト).

shuffle(_カードの枚数,_入力リスト,_出力リスト) :-
    _乱数値1 is random(_カードの枚数) + 1,
    _乱数値2 is random(_カードの枚数) + 1,
    交換(1,[_乱数値1,_乱数値2],V1,V2,_入力リスト,_出力リスト).

交換(N,_交換位置リスト,V1,V2,[A|R1],[A|R2]) :-
    \+(member(N,_交換位置リスト)),
    N2 is N + 1,
    交換(N2,_交換位置リスト,V1,V2,R1,R2),!.
交換(N,_交換位置リスト,V1,V2,[A|R1],[V2|R2]) :-
    var(V1),
    V1 = A,
    N2 is N + 1,
    交換(N2,_交換位置リスト,V1,V2,R1,R2),!.
交換(_,_,V1,V2,[A|R],[V1|R]) :-
    var(V2),
    V2 = A,!.
0225デフォルトの名無しさん2011/08/01(月) 08:30:07.23
>>217 >>218 >>221 >>224
この強烈な差異が、Prologの面白さでもあり、弱点でもあるのでしょう。
0226デフォルトの名無しさん2011/08/01(月) 22:46:06.81
リストをある要素で、複数のリストに分割するsplit/3を実装せよ。

?- split([1,0,2,3,0,4,0,0,5], 0, X).
X = [[1],[2,3],[4],[],[5]]
0227デフォルトの名無しさん2011/08/01(月) 23:35:58.03
>>226

split([],_,[]) :- !.
split(L1,_区切り文字,L2) :-
    split(L1,_区切り文字,L,R),
    split(R,_区切り文字,L3),
    append([L],L3,L2).

split([],_,[],[]) :- !.
split([_区切り文字|R],_区切り文字,[],R) :- !.
split([A|R1],_区切り文字,[A|R2],R) :-
    split(R1,_区切り文字,R2,R).
02282262011/08/01(月) 23:41:36.82
>>227
速いですね!
これから、解析させてもらいます
0229デフォルトの名無しさん2011/08/02(火) 00:19:04.36
>>226
split(L1,_区切り文字,L2) :-
    findall(L,(
          split_3(L1,_区切り文字,L)),
        L2).

split_3(L1,_区切り文字,L1) :-
    \+(member(_区切り文字,L1)),!.
split_3(L1,_区切り文字,L0) :-
    split_4(L1,_区切り文字,L0,R).
split_3(L1,_区切り文字,L0) :-
    split_4(L1,_区切り文字,_,R),
    split_3(R,_区切り文字,L0).

split_4(L1,_区切り文字,L0,R) :-
    append(L0,[_区切り文字|R],L1),!.
0230デフォルトの名無しさん2011/08/02(火) 00:28:15.46
>>226
ごめんなさい。>>227はこれでよいのか。

split([],_,[]) :- !.
split(L1,_区切り文字,[L|R2]) :-
    split(L1,_区切り文字,L,R),
    split(R,_区切り文字,R2).

split([],_,[],[]) :- !.
split([_区切り文字|R],_区切り文字,[],R) :- !.
split([A|R1],_区切り文字,[A|R2],R) :-
    split(R1,_区切り文字,R2,R).
0231デフォルトの名無しさん2011/08/02(火) 00:33:39.57
>>226
これもありそう。

split(L1,_区切り文字,[L0|R2]) :-
    split_4(L1,_区切り文字,L0,R),
    split(R,_区切り文字,R2).
split(L1,_区切り文字,[L1]).

split_4(L1,_区切り文字,L0,R) :-
    append(L0,[_区切り文字|R],L1),!.
02322262011/08/02(火) 00:43:24.06
ちょっと考え込んでしまいましたが、
シンプルに、こんな感じではいかがでしょうか?

split([], _, [[]]) :- !.
split([S|R], S, [[]|L]) :- split(R, S, L), !.
split([H|R], S, [[H|H1]|L]) :- split(R, S, [H1|L]), !.
02332262011/08/02(火) 00:45:53.37
アプローチとしては、リストの末尾から時間を逆戻しする感じで、
具体例を考えて、次に変数を導入するようにしてみました。

split([], 0, [[]]).
split([5], 0, [[5]]).
split([0,5], 0, [[],[5]]).
split([0,0,5], 0, [[],[],[5]]).
split([4,0,0,5], 0, [[4],[],[5]]).
0234デフォルトの名無しさん2011/08/02(火) 00:57:12.26
>>232
そうですね。それがいい。
0235デフォルトの名無しさん2011/08/02(火) 09:48:45.44
>>226
非決定性述語をもうひとつ。速度効率無視。

split(L,_区切り文字,X) :-
    最初に区切り文字が出現するまでの部分も対象(L,_区切り文字,X).
split(L,_区切り文字,X) :-
    区切り文字と区切り文字に囲まれた部分(L,_区切り文字,X).
split(L,_区切り文字,X) :-
    最後の要素は残り要素に区切り文字が出現しない(L,_区切り文字,X).
split(L,_区切り文字,L) :-
    リストのなかに区切り文字が存在しないときは(L,_区切り文字).

最初に区切り文字が出現するまでの部分も対象(L,_区切り文字,X) :-
    append(X,[_区切り文字|_],L),
    \+(member(_区切り文字,X)).

区切り文字と区切り文字に囲まれた部分(L,_区切り文字,X) :-
    append(_,[_区切り文字|X],[_区切り文字|_],L),
    \+(member(_区切り文字,X)).

最後の要素は残り要素に区切り文字が出現しない(L,_区切り文字,X) :-
    append(L0,[_区切り文字|X],L),
    \+(member(_区切り文字,X)).

リストの中に区切り文字が存在しないときは(L,_区切り文字) :-
    \+(member(_区切り文字,L)).

append([],L1,L2,L) :-
    append(L1,L2,L).
append([A|R1],L1,L2,[A|R]) :-
    append(R1,L1,L2,R).
0236デフォルトの名無しさん2011/08/03(水) 12:33:35.25
>>215

shuffle(_カードの束,_切られたカードの束) :- shuffle([_,_,_,_,_],_カードの束,_切られたカードの束).

shuffle([],_カードの束,_カードの束) :- !.
shuffle([_|Ln],_カードの束,_切られたカードの束) :-
    概ね分割する(_カードの束,_カードの束_1,_カードの束_2),
    カードを雑に併合(1,_カードの束_1,_カードの束_2,_カードの束_3),
    shuffle(Ln,_カードの束_3,_切られたカードの束).

概ね分割する(_カードの束,_カードの束_1,_カードの束_2) :-
    _分割数1 is random(7) + 20,
    length(_カードの束_1,_分割数1),
    append(_カードの束_1,_カードの束_2,_カードの束),
    カードを雑に併合(_カードの束_1,_カードの束_2,_カードの束_3),

カードを雑に併合(1,_カードの束_1,_カードの束_2,_カードの束) :-
    _重なる枚数 is truncate(random(4) * 0.4 + 1),
    length(L,_重なる枚数),
    append(L,R1,_カードの束1),
    カードを雑に併合(2,R,_カードの束_2,_カードの束_3),
    append(L,_カードの束_3,_カードの束),!.
カードを雑に併合(2,_カードの束_1,_カードの束_2,_カードの束_3) :-
    _重なる枚数 is truncate(random(4) * 0.4 + 1),
    length(L,_重なる枚数),
    append(L,R2,_カードの束2),
    カードを雑に併合(1,_カードの束_1,R,_カードの束_3),
    append(L,_カードの束_3,_カードの束),!.
カードを雑に併合(_,_カードの束_1,_カードの束_2,_カードの束) :-
    append(_カードの束_1,_カードの束2,_カードの束),!.
0237デフォルトの名無しさん2011/08/04(木) 09:14:38.92
>>215

shuffle(_カードの束,_切られたカードの束) :-
    length(_カードの束,_カードの枚数),
    _カードの枚数 > 2,
    M is _カードの枚数 // 12 + 3,
    _乱数値 is random(M),
    length(L0,_乱数値),
    append(L0,L1,_カードの束),
    shuffle(L1,_カードの束_2),
    append(_カードの束_2,L0,_切られたカードの束),!.
shuffle(_カードの束,_カードの束).
0238デフォルトの名無しさん2011/08/04(木) 09:23:19.35
>>215
トランプの場合は >>236 と >>237 の組合せで切ってると思う。
0239デフォルトの名無しさん2011/08/05(金) 08:30:19.87
# 「どうでもいいけど猫同士のコミュニケーションの代数構造どうなってんすかね」 by m0h1can on twitter
#
# これにヒントを得て、
#
# 述語 「猫は回さない」 を定義せよ。
#
0240デフォルトの名無しさん2011/10/07(金) 07:36:05.65
このあたりを参考に型推論をせよ
ttp://rainyday.blog.so-net.ne.jp/2008-06-16
ただし参考例は返値しか推定できないので
返値から逆に関数の引数の型なども推定できるようにせよ
0241デフォルトの名無しさん2011/10/08(土) 13:02:12.04
>488 名前: 365 Mail: sage 投稿日: 2011/09/29(木) 18:07:57.87
>>>485
>Prolog で型チェック:Rainy Day Codings:So-net blog
> http://rainyday.blog.so-net.ne.jp/2008-06-16
>
>題名は型チェックだけど、コードはまぎれもなく型推論
>
>489 名前: デフォルトの名無しさん Mail: sage 投稿日: 2011/09/29(木) 19:09:02.35
>ああPrologだから単一化で型推論が起きるのか。
>
>490 名前: デフォルトの名無しさん Mail: sage 投稿日: 2011/10/04(火) 18:43:07.61
>prologで型推定が一番楽にできそう
>しかし返値しか推定してないね
0242デフォルトの名無しさん2011/12/16(金) 00:41:29.75
|....,,__
|_::;; ~"'ヽ
| //^''ヽ,,)
|  i⌒"
| ∀`) < 誰もいない きのこるならいまのうち
|⊂
| ノ
      _,,,......,,__
  /_~ ,,...:::_::;; ~"'ヽ
 (,, '"ヾヽ  i|i //^''ヽ,,)
   ^ :'⌒i    i⌒"
      |( ´∀`) < きのこ のこーのこ げんきのこ ♪
      |(ノ   |つ
      |     |
     ⊂ _ ノ
       ""U
      _,,,......,,__
  /_~ ,,...:::_::;; ~"'ヽ
 (,, '"ヾヽ  i|i //^''ヽ,,)
   ^ :'⌒i    i⌒"
     (´∀` )| < エリンギ まいたけ ブナシメジ ♪
    ⊂|  (ノ |
      |     |
      ヽ _ ⊃
      .U""
|
| ミ
| ミ  サッ!
| ミ
|
0243デフォルトの名無しさん2012/05/25(金) 08:00:45.01
http://toro.2ch.net/test/read.cgi/tech/1332279659/111
などは如何なものでしょうか?
0244デフォルトの名無しさん2012/06/29(金) 16:45:14.54
>>37

'リストの要素として、4個目のaを見つけて残りのリスト'(_リスト,_残りのリスト) :-
    'リストの要素として、4個目のaを見つけて残りのリスト'(1,_リスト,_残りのリスト).

'リストの要素として、4個目のaを見つけて残りのリスト'(4,[a|_残りのリスト],_残りのリスト) :- !.
'リストの要素として、4個目のaを見つけて残りのリスト'(N,[a|R1],_残りのリスト) :-
    N_2 is N + 1,
    'リストの要素として、4個目のaを見つけて残りのリスト'(N_2,R1,_残りのリスト),!.
'リストの要素として、4個目のaを見つけて残りのリスト'(N,[_|R1],_残りのリスト) :-
    'リストの要素として、4個目のaを見つけて残りのリスト'(N,R1,_残りのリスト).
0245デフォルトの名無しさん2012/06/29(金) 16:54:54.11
>>38

'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(N個目,X,_リスト,_残りリスト) :-
    'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(1,N個目,X,_リスト,_残りリスト).

'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(N,N,X,[X|_残りリスト],_残りリスト) :- !.
'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(M,N,X,[X|R],_残りリスト) :-
    M_2 is M + 1,
    'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(M_2,N,X,R,_残りリスト),!.
'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(M,N,X,[_|R],_残りリスト) :-
    'リストの要素が変数Xで与えられるとする。N個目のXの残りのリストを返す'(M,N,X,R,_残りリスト).
■ このスレッドは過去ログ倉庫に格納されています