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

Prologの宿題片付けます

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2010/04/23(金) 16:02:04
Prologで宿題が出たら、自分でプログラムが書くことができた
人も、思い悩んでいる人も、ここにその問題を載せてください。
宿題はその講座がどんな内容かをちょっとだけ垣間見させて
くれます。
全国の大学に100を越える講座があるといわれるProlog。
どんな宿題がでてくるのか楽しみです。
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,_残りリスト).
■ このスレッドは過去ログ倉庫に格納されています