このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1308749241/801
#  [1] 授業単元:スタックとキュー 
#  [2] 問題文(含コード&リンク): http://codepad.org/Os0523nV 
#    3問あります。問題文もリンク先に書いてあります。  
#  
#  【問題1】
#  スタックを実現するための配列stack[]をグローバル変数として宣言したものを下に示す。
#     /* スタックを実現する配列 */
#      #define STACK_SIZE 5
#         #define NO_DATA -1
#  
#         int stack[STACK_SIZE];
#         int sp=-1;
#  
#  ここで、スタックの最大サイズは5とし、スタックポインタは-1に初期化している。
#  
#  以下の各関数を作成しなさい。
#  1)スタックをプッシュする関数:int Push(int data)
#    引数の整数データをスタックに積み上げ、スタックポインタをインクリメントする。
#    プッシュが成功した場合は0を返し、スタックがオーバーフローした場合は-1を返す。
#  2)スタックをポップする関数:int Pop()
#    スタックからデータを取り出し、スタックポインタをデクリメントする。ポップが成功した場合は
#    取り出した整数を返し、スタックにデータがない場合は-1を返す。
#  3)スタックを底から頂上へ向けて表示する関数:void ShowStack()
#    スタックに積み上がったデータを順に表示する。
#  
#  上記の各関数を使用して、スタックにデータをプッシュおよびポップするメインプログラムを作成し、以下のスタック動作を行いなさい。
#  
#  1)スタックをNO_DATAで初期化する。
#  2)スタックにデータ(例えば 111,222,333,444,555)を順にプッシュする。
#  3)適当にポップおよびプッシュを行うことにより、スタックの機能を確認する。
#  4)プッシュおよびポップを行った際にスタックにある全データを表示する。
#  
#  <表示例>
#  (1) Push (2) Pop (0) Exit :1
#  Data:111
#  Stack : [111]
#  (1) Push (2) Pop (0) Exit :1
#  Data:222
#  Stack : [111][222]
#  (1) Push (2) Pop (0) Exit :1
#  Data:333
#  Stack : [111][222][333]
#  (1) Push (2) Pop (0) Exit :1
#  Data:444
#  Stack : [111][222][333][444]
#  (1) Push (2) Pop (0) Exit :1
#  Data:555
#  Stack : [111][222][333][444][555]
#  (1) Push (2) Pop (0) Exit :1
#  Data:666
#  Stack Overflow!
#  Stack Push is failed!
#  (1) Push (2) Pop (0) Exit :2
#  Pop data is 555
#  Stack : [111][222][333][444]
#  (1) Push (2) Pop (0) Exit :2
#  Pop data is 444
#  Stack : [111][222][333]
#  (1) Push (2) Pop (0) Exit :1
#  Data:666
#  Stack : [111][222][333][666]
#  (1) Push (2) Pop (0) Exit :2
#  Pop data is 666
#  Stack : [111][222][333]
#  (1) Push (2) Pop (0) Exit :2
#  Pop data is 333
#  Stack : [111][222]
#  (1) Push (2) Pop (0) Exit :2
#  Pop data is 222
#  Stack : [111]
#  (1) Push (2) Pop (0) Exit :2
#  Pop data is 111
#  Stack : 
#  (1) Push (2) Pop (0) Exit :2
#  Stack Empty!
#  Stack Pop is failed!
#  (1) Push (2) Pop (0) Exit :0
#  
#  

スタックサイズ(5).

'引数の整数データをスタックに積み上げ、スタックポインタをインクリメントする。プッシュが成功した場合は0を返し、スタックがオーバーフローした場合は-1を返す。'(N,_スタック1,_スタック2,_診断) :-
        スタックをプッシュする(N,_スタック1,_スタック2,_診断).

スタックをプッシュする(N,_スタック,_スタック,-1) :-
        スタックがオーバーフローした場合(_スタック),!.
スタックをプッシュする(N,_スタック,[N|_スタック],0) :-
        プッシュが成功した場合([N|_スタック]),!.

スタックがオーバーフローした場合(_スタック) :-
        スタックサイズ(_スタックサイズ),
        length(_スタック,_現在の要素数),
        _現在の要素数 >= _スタックサイズ,!.

プッシュが成功した場合(L) :-
        スタックサイズ(_スタックサイズ),
        length(_スタック,_プッシュした後の要素数),
        _スタックサイズ >= _プッシュした後の要素数,!.

'スタックからデータを取り出し、スタックポインタをデクリメントする。ポップが成功した場合は取り出した整数を返し、スタックにデータがない場合は-1を返す'(_値,_スタック1,_スタック2) :-
        スタックをポップする(_スタック1,_スタック2,N).

スタックをポップする(_スタック1,_スタック2,N) :-
        ポップが成功した場合は取り出した整数を返し(_スタック1,_スタック2,N).
スタックをポップする(_スタック1,_スタック2,N).
        'スタックにデータがない場合は-1を返す'(_スタック1,_スタック2,N),

ポップが成功した場合は取り出した整数を返し([N|_スタック],_スタック,N) :- !.

'スタックにデータがない場合は-1を返す'([],[],-1).

スタックを底から頂上へ向けて表示する(_スタック) :-
        reverse(_スタック,_反転したスタック),
        表示する(_反転したスタック).

表示する([]).
表示する([_要素|R]) :-
        writef('%t\n',[_要素]),
        表示する(R).