You selected boki0.pl

headline:-
   write('% -------------------------------------------------- %'),nl,
   write('%     簿記の仕訳ルール学習支援システム(試作)       %'),nl,
   write('% -------------------------------------------------- %'),nl,
   h0.
h0:-
   write('%  boki(A,B,C):- 仕訳の基本知識を説明する'),nl,
   write('%    A = o(_) ---  簿記、仕訳の基本概念'),nl,
   write('%    A = a(_) ---  借方と貸方への記入ルール'),nl,
   write('%  boki0(A,B,C):- 仕訳のためのルール'),nl,
   write('%  boki0(A,B,query):- 同上の出力清書'),nl,
   write('%    A = b(_) ---  仕訳の基本項目'),nl,
   write('%    A = c(_) ---  仕訳の基本ルール'),nl,
   write('%    A = d(_) ---  勘定科目'),nl,
   write('%    A = e(_) ---  科目読替辞書'),nl,
   write('%    A = q(_) ---  仕訳の問題'),nl,
   write('%    A = t(_) ---  仕訳の実行'),nl,
   write('%  siwake(D,D1,L,R,C):- 簡単な仕訳を実行する'),nl,
   write('%  sindan:- ユーザへの出題・回答の診断'),nl,
   write('%  h0.   this.'),nl.
me:-
   write('% file: boki0.pl.'),nl,
   write('% created: 17-19 Mar 2003.'),nl,
   write('% modified: 20,22 Mar 2003.'),nl,
   write('% previous: siwake.pl(30 Oct 2002). '),nl,
   write('% previous: boki01.pl(Nov-Jan 2002). '),nl,
   write('% author: Kenryo INDO (Kanto Gakuen University) '),nl,
   write('% url: http://www.us.kanto-gakuen.ac.jp/indo/front.html'),
   nl.

references:-
   write('%  大栄総研.「いきなりわかる商法・会計学」,大栄出版,1996 '),nl,
   write('%  税務経理協会.「学習版会計諸則集」,税務経理協会,2002. '),nl,
   nl.

line0('-------------------------------------------------------------').
wl:- line0(L),write(L).

:- headline.

:- dynamic qdata /3.
:- dynamic udata /3.


%------------------------------------------------------------%
/* 簿記の基本概念  : boki/3, rule group o */ 
%------------------------------------------------------------%

boki(o(1), '複式簿記の流れ',Q):-
   R  = (R1,R2),
   R1 = '複式簿記は、期中に発生した取引を記録し、決算で利益を計算する',
   R2 = 'この結果、決算書(損益計算書と貸借対照表)が作成される',
   (
    Q==query
     ->
       (
        nl,write((o(1), '複式簿記の流れ:')),nl,wl,
        nl,write(R1),write('。'),nl,write(R2),write('。'), nl
       )
     ; Q=R
   ).

boki(o(2), '仕訳の基本項目',Q):-
   R = '仕訳の基本項目は、資産・負債・資本・収益・費用の5つ',
   S = (boki0(b(0),'仕訳の基本項目',X),write(X)),
   (
    Q==query
     ->
       (
        nl,write((o(2), '仕訳の基本項目:')),nl,wl,
        nl, write(R), write('である。'), 
        nl,write('具体例:'),nl,wl,
        nl, write(S), nl
       )
     ; Q=(R,S)
   ).

boki(o(3), '取引',Q):-
   R = '簿記でいう取引とは、基本項目の増減を引き起こす事象のこと',
   (
    Q==query
     ->
       (
        nl,write((o(3), '取引:')),nl,wl,
        nl, write(R), write('である。'), nl
       )
     ; Q=R
   ).

boki(o(4), '仕訳',Q):-
   R  = (R1,R2),
   R1 = '仕訳とは、取引による基本項目の増減を左右に分けて記録すること',
   R2 = 'また、仕訳のルールに従っていくつかの基本項目を同時に増減させる',
   S = (
        (boki0(q(W,s),'問',X),boki0(q(W,a),'答',Y)),
        (write(('問':X)),nl,write(('答':Y)))
   ),
   (
    Q==query
     ->
       (
        nl,write((o(4), '仕訳:')),nl,wl,
        nl, write(R1), write('である。'), 
        nl, write(R2), write('。'), nl,
        nl,write('具体例:'),nl,wl,
        nl, write(S), nl
       )
     ; Q=(R,S)
   ).

boki(o(5), '勘定科目',Q):-
   R = '勘定科目とは、仕訳の際、各基本項目につけられる名前のこと',
   S = (boki0(d(_,_),'勘定科目',X),write(X)),
   (
    Q==query
     ->
       (
        nl,write((o(5), '勘定科目:')),nl,wl,
        nl, write(R), write('である。'), nl,
        nl,write('具体例:'),nl,wl,
        nl, write(S), nl
       )
     ; Q=R
   ).


%------------------------------------------------------------%
/* 仕訳の作業目標 : boki/3, rule group a  */ 
%------------------------------------------------------------%

boki(a(1), '仕訳の原理:借方と貸方への記入ルール',Q):-
   R = [
    objective('まず項目とその変化パタンを認識すること'),
    constraint('問題文と勘定科目とのリンクを見出すこと'),
    constraint('勘定科目は資産/負債/資本/収益/費用のどの項目か'),
    constraint('それが増加/発生、または減少/取消のいずれであるか'),
    action('上の項目と変化のパタンに対し、仕訳の基本ルール a(2) を適用')
   ],
   (Q==query
     ->
       (
        nl,write((a(1), '仕訳の基本ルール')),nl,wl,
        write_objective(R),
        write_constraints(R),
        write_actions(R),
        nl
       )
     ;
      Q=R
   ).

boki(a(2), '仕訳の原理:借方と貸方への記入ルール',Q):-
   R = [
     objective('つぎに借方(左)と貸方(右)の記入を区別すること'),
     constraint('資金の使途をあらわす項目=資産・費用、'),
     constraint('資金の出所をあらわす項目=負債・資本・収益とすると、'),
     constraint('資金の使途をあらわす項目の増加や発生は、借方(左)'),
     constraint('資金の出所をあらわす項目の増加や発生は、貸方(右)'),
%     constraint('資金の使途をあらわす項目の減少や取消は、貸方(右)'),
%     constraint('資金の出所をあらわす項目の減少や取消は、借方(左)'),
     constraint('などのように、基本ルールcにしたがい、左右の区別')
   ],
   S = (boki0(c(1), '資金の使途', X),write(X)),
   (Q==query
     ->
       (
        nl,write((a(2),'仕訳の基本ルール')),nl,wl,
        write_objective(R),
        write_constraints(R),
        nl,write('具体例:'),nl,wl,
        nl, write(S), nl
       )
     ;
      Q=(R,S)
   ).


boki(a(3), '回答テクニック',Q):-
   R = [
     objective('試験問題の場合、各項目の勘定科目を覚え、考え方は消去法'),
     constraint('消去法で解けない場合、どの理論と組み合わせたら解けるか')
   ],
   S = (boki0(q(_,s),'問',X),write(X)),
   (Q==query
     ->
       (
        nl,write((a(3),'回答テクニック')),nl,wl,
        write_objective(R),
        write_constraints(R),
        nl,write('具体例:'),nl,wl,
        nl, write(S), nl
       )
     ;
      Q=(R,S)
   ).

% local utilities 
%------------------------------------------------------------%
write_objective(R):-
   member(objective(O),R),
   nl,write('作業目標は、'),
   nl,tab(2),write(O),write('である。'),
   nl.

write_constraints(R):-
  forall(
    nth1(K,R,constraint(X)),
    (
     (\+ (nth1(K1,R,constraint(_)),K1  T = 'ただし、'; T = ''
     ),
     nl,write(T),
     nl,tab(2),
     write(X)
    )
  ),
  nl,
  write('を判断せよ。'),
  nl.

write_actions(R):-
  forall(
    nth1(K,R,action(X)),
    (
     (\+ (nth1(K1,R,action(_)),K1  T = 'そして、'; T = ''
     ),
     nl,write(T),
     nl,tab(2),
     write(X)
    )
  ),
  nl,
  write('しなさい。'),
  nl.



%------------------------------------------------------------%
/* 財務諸表と基本項目 : boki0/3, rule group b  */ 
%------------------------------------------------------------%

boki0(R,A,query):-
   boki0(R,A,(B,C)),forall(member(X,[A,B,C]),(nl,write(X))).

% ↑清書用:Swi-Prolog 5.0.9 のバグでユニファイされた結果表示
% が文字化けするため。Swi-Prolog 1.9.0だと一応表示される。
% いずれにせよ、日本語文字列は一部文字化けし、処理エラーする。


boki0(b(0),'仕訳の基本項目',X):-
   boki(b(1),'損益計算書項目',X);
   boki(b(2),'貸借対照表項目',X).

boki0(b(1),'損益計算書項目',X):-
   member(X,['収益','費用']).

boki0(b(2),'貸借対照表項目',X):-
   member(A,['資産','負債','資本']),
   ( X == query -> boki0(b(_), A, query); true ).

boki0(b(4),'損益計算書',X):-
   X = ['収益'(A), '費用'(B), '純利益'(C)],
   % 損益法
   C = A - B.

boki0(b(5),'貸借対照表(期首)',X):-
   X = ['資産'(A), '負債'(B), '資本'(C)],
   A = B + C.

boki0(b(6),'貸借対照表(期末)',X):-
   X = ['資産'(A), '負債'(_B), '資本'(_C), '純利益'(D)],
   boki(e(1),'貸借対照表(期首)',Y),
   Y = ['資産'(A0), '負債'(_B0), '資本'(_C0)],
   boki0(b(4),'損益計算書',Z),
   Z = ['収益'(_E), '費用'(_F), '純利益'(D)],
   % 財産法
   A = A0 + D.

% 注意:SWI-prologのバグと思われるが、'貸借対照表'
% のように最後に「表」がつくとなぜかエラーになる。


boki0(b(7), '資産', X):-
   A= '資産の定義:',
   B= '企業による資金の運用形態・利用状況,将来の利益に結びつくもの.',
   C= '勘定科目の具体例:',
   D= (boki0(d(1,_),'勘定科目',('資産',K)),write(K)),
   X = [A,B,C,D].

boki0(b(8), '負債', X):-
   A= '負債の定義:',
   B= '企業によって調達された資金のうち,他人に対し返済義務を負うもの.',
   C= '勘定科目の具体例:',
   D= (boki0(d(2,_),'勘定科目',('負債',K)),write(K)),
   X = [A,B,C,D].

boki0(b(9), '資本', X):-
   A= '資本の定義:',
   B= '資産総額から負債総額を引いた純資産.出資者自身の拠出と過去の利益.',
   C= '勘定科目の具体例:',
   D= (boki0(d(3,_),'勘定科目',('資本',K)),write(K)),
   X = [A,B,C,D].

boki0(b(10), '収益', X):-
   A= '収益の定義:',
   B= '純資産(資本)を増加させる取引で,増資など営業活動でないものを除く.',
   C= '勘定科目の具体例:',
   D= (boki0(d(4,_),'勘定科目',('収益',K)),write(K)),
   X = [A,B,C,D].

boki0(b(11), '費用', X):-
   A= '費用の定義:',
   B= '純資産を減少させる取引や利益獲得の手段.ただし減資などを除く.',
   C= '勘定科目の具体例:',
   D= (boki0(d(5,_),'勘定科目',('費用',K)),write(K)),
   X = [A,B,C,D].


%------------------------------------------------------------%
/* 仕訳の基本ルール : boki0/3, rule group c */ 
%------------------------------------------------------------%
% 借方(左)の増加や発生は、資金の使途を表す項目=資産・費用。
% 貸方(右)の増加や発生は、資金の出所を表す項目=負債・資本・収益。

boki0(c(0), '貸借の一致', ('借方合計'(X),'貸方合計'(Y))):- X=Y.


boki0(c(1), '資金使途の項目', ('資産','増加','借方(左)')).
boki0(c(2), '資金使途の項目', ('費用','発生','借方(左)')).
boki0(c(3), '資金使途の項目', ('資産','減少','貸方(右)')).
boki0(c(4), '資金使途の項目', ('費用','取消','貸方(右)')).

boki0(c(5), '資金出所の項目', ('負債','増加','貸方(右)')).
boki0(c(6), '資金出所の項目', ('資本','増加','貸方(右)')).
boki0(c(7), '資金出所の項目', ('収益','発生','貸方(右)')).
boki0(c(8), '資金出所の項目', ('負債','減少','借方(左)')).
boki0(c(9), '資金出所の項目', ('資本','減少','借方(左)')).
boki0(c(10), '資金出所の項目', ('収益','取消','借方(左)')).


%------------------------------------------------------------%
/*  勘定科目 : boki0/3, rule group d */ 
%------------------------------------------------------------%
% 資産
boki0(d(1,1),'勘定科目',('資産','現金')).
boki0(d(1,2),'勘定科目',('資産','当座預金')). %二勘定制
boki0(d(1,3),'勘定科目',('資産','当座')). %一勘定制
boki0(d(1,4),'勘定科目',('資産','貸倒引当金')). %評価勘定(マイナス)
boki0(d(1,5),'勘定科目',('資産','受取手形')).
boki0(d(1,6),'勘定科目',('資産','小口現金')).
boki0(d(1,7),'勘定科目',('資産','売掛金')).
boki0(d(1,8),'勘定科目',('資産','有価証券')).
boki0(d(1,9),'勘定科目',('資産','商品')).
boki0(d(1,10),'勘定科目',('資産','貸付金')).
boki0(d(1,11),'勘定科目',('資産','前渡金')).
boki0(d(1,12),'勘定科目',('資産','建物')).
boki0(d(1,13),'勘定科目',('資産','機械')).
boki0(d(1,14),'勘定科目',('資産','備品')).
boki0(d(1,15),'勘定科目',('資産','車両')).
boki0(d(1,16),'勘定科目',('資産','土地')).
boki0(d(1,17),'勘定科目',('資産','借地権')).
boki0(d(1,18),'勘定科目',('資産','電話加入権')).
boki0(d(1,19),'勘定科目',('資産','開発費')).
boki0(d(1,20),'勘定科目',('資産','試験研究費')).
% 負債
boki0(d(2,1),'勘定科目',('負債','支払手形')).
boki0(d(2,2),'勘定科目',('負債','買掛金')).
boki0(d(2,3),'勘定科目',('負債','借入金')).
boki0(d(2,4),'勘定科目',('負債','預り金')).
boki0(d(2,5),'勘定科目',('負債','前受金')).
boki0(d(2,6),'勘定科目',('負債','社債')).
boki0(d(2,7),'勘定科目',('負債','退職給与引当金')).
boki0(d(2,8),'勘定科目',('負債','当座貸越')). %二勘定制
% 資本
boki0(d(3,1),'勘定科目',('資本','資本金')).
boki0(d(3,2),'勘定科目',('資本','資本準備金')).
boki0(d(3,3),'勘定科目',('資本','利益準備金')).
boki0(d(3,4),'勘定科目',('資本','別途積立金')).
boki0(d(3,5),'勘定科目',('資本','未処分利益')).
% 収益
boki0(d(4,1),'勘定科目',('収益','売上')).
boki0(d(4,2),'勘定科目',('収益','受取利息')).
boki0(d(4,3),'勘定科目',('収益','受取手数料')).
boki0(d(4,4),'勘定科目',('収益','受取家賃')).
boki0(d(4,5),'勘定科目',('収益','雑収入')).
% 費用
boki0(d(5,1),'勘定科目',('費用','仕入')).
boki0(d(5,2),'勘定科目',('費用','給料')).
boki0(d(5,3),'勘定科目',('費用','消耗品費')).
boki0(d(5,4),'勘定科目',('費用','修繕費')).
boki0(d(5,5),'勘定科目',('費用','通信費')).
boki0(d(5,6),'勘定科目',('費用','広告宣伝費')).
boki0(d(5,7),'勘定科目',('費用','運賃')).
boki0(d(5,8),'勘定科目',('費用','支払家賃')).
boki0(d(5,9),'勘定科目',('費用','旅費交通費')).
boki0(d(5,10),'勘定科目',('費用','接待交際費')).
boki0(d(5,11),'勘定科目',('費用','租税公課')).
boki0(d(5,12),'勘定科目',('費用','水道光熱費')).
boki0(d(5,13),'勘定科目',('費用','支払保険料')).
boki0(d(5,14),'勘定科目',('費用','福利厚生費')).
boki0(d(5,15),'勘定科目',('費用','支払手数料')).
boki0(d(5,16),'勘定科目',('費用','雑費')).
boki0(d(5,17),'勘定科目',('費用','支払利息割引料')).
boki0(d(5,18),'勘定科目',('費用','雑損失')).
% 仮分類
%(現金過不足は判明したら上記に分類する。
% 決算時でもなお未確定なら、雑損失・雑収入とする。)
boki0(d(6,1),'勘定科目',('仮分類','現金過不足')).
% 未分類
boki0(d(7,1),'勘定科目',('未分類','原材料')).
boki0(d(7,2),'勘定科目',('未分類','工程仕掛品')).
boki0(d(7,3),'勘定科目',('未分類','仕掛品')).
boki0(d(7,4),'勘定科目',('未分類','差異')).
boki0(d(7,5),'勘定科目',('未分類','製品')).
boki0(d(7,6),'勘定科目',('未分類','売掛')).
boki0(d(7,7),'勘定科目',('未分類','A事業部')).
boki0(d(7,8),'勘定科目',('未分類','支店')).
boki0(d(7,9),'勘定科目',('未分類','減価償却引当金')).
boki0(d(7,10),'勘定科目',('未分類','商品販売益')).
boki0(d(7,11),'勘定科目',('未分類','原材料')).
boki0(d(7,12),'勘定科目',('未分類','工程仕掛品')).
boki0(d(7,13),'勘定科目',('未分類','仕掛品')).
boki0(d(7,14),'勘定科目',('未分類','間接費')).
boki0(d(7,15),'勘定科目',('未分類','直接労務費')).
boki0(d(7,16),'勘定科目',('未分類','支店')).
boki0(d(7,17),'勘定科目',('未分類','機械')).
boki0(d(7,18),'勘定科目',('未分類','固定資産売却益金')).


%------------------------------------------------------------%
/*  仕訳上の科目読み替え : boki0/3, rule group e */ 
%------------------------------------------------------------%

boki0(e(1),'仕訳辞書',('お金','現金','通貨')).
boki0(e(2),'仕訳辞書',('貨幣','現金','通貨')).
boki0(e(3),'仕訳辞書',('紙幣','現金','通貨')).
boki0(e(4),'仕訳辞書',('他人振り出し小切手','現金','通貨代用証券')).
boki0(e(5),'仕訳辞書',('送金小切手','現金','通貨代用証券')).
boki0(e(6),'仕訳辞書',('郵便為替証券','現金','通貨代用証券')).
boki0(e(7),'仕訳辞書',('配当金領収書','現金','通貨代用証券')).
boki0(e(8),'仕訳辞書',('公社債の期限到来済の利札','現金','通貨代用証券')).
boki0(e(9),'仕訳辞書',('予約販売','前受金')).


%------------------------------------------------------------%
/* 仕訳の簡単な例題 : boki0/3, rule group q */ 
%------------------------------------------------------------%

boki0(q(1,s),'問','100円の商品を販売し,代金は現金で受け取った。').
boki0(q(2,s),'問','¥12,000の商品を仕入れ,代金は掛とした。').
boki0(q(3,s),'問','上記で仕入れた商品を¥15,000で販売し,代金は掛とした。').

boki0(q(1,a),'答',('現金',100 ; '売上',100)).
boki0(q(2,a),'答',('仕入',12000 ; '買掛金',12000)).
boki0(q(3,a),'答',('売上',15000 ; '売上',15000)).

%日商簿記検定の例題
% いくつかの連続する取引と科目の選択肢

boki0(q(4,s),'問','既製服の小売りをしている関東商店の10月中における取引は,下記のとおりであった。よって,次の中から勘定科目を選んで,仕訳を示しなさい。').

boki0(q(4,s),'科目','売掛金').
boki0(q(4,s),'科目','貸付金').
boki0(q(4,s),'科目','交通費').
boki0(q(4,s),'科目','買掛金').
boki0(q(4,s),'科目','借入金').
boki0(q(4,s),'科目','現金').
boki0(q(4,s),'科目','資本金').
boki0(q(4,s),'科目','商品').
boki0(q(4,s),'科目','商品売買益').
boki0(q(4,s),'科目','当座預金').
boki0(q(4,s),'科目','広告料').
boki0(q(4,s),'科目','通信費').

boki0(q(4,s),'問','10月3日 太田商会から婦人用スーツ5着@¥40,000を仕入れ,代金は今月末に支払うことにした。').
boki0(q(4,s),'問','8日 電話代¥5,000を現金で支払った。').
boki0(q(4,s),'問','21日 10月3日に仕入れた婦人用スーツのうち,1着を¥50,000で売り渡し,代金のうち¥30,000は現金で受け取り,残額は翌月受け取ることにした。').
boki0(q(4,s),'問','31日 太田商会への10月3日の商品代金¥200,000を,小切手を振り出して支払った。').



%------------------------------------------------------------%
/* 仕訳の実行 : boki0/3, rule group t */ 
%------------------------------------------------------------%

% 正しい貸方・借方の勘定科目の組み合わせを生成する。

% 前出の仕訳の基本ルールcを、改めて要約すると、以下のようである。

% 借方(左)で(['増加','発生']):-
%   資金使途の項目(['資産','費用']).
% 貸方(右)で(['増加','発生']):-
%   資金出所の項目(['負債','資本','収益']).
% 借方(左)で(['減少','取消']):-
%   資金出所の項目(['負債','資本','収益']).
% 貸方(右)で(['減少','取消']):-
%   資金使途の項目(['資産','費用']).

% 例1:
%  取引内容: 販売(売上:収益&増加→右)
%        受取(現金:資産&増加→左)  
%    仕訳: (借)現金 50  (貸)売上  50
% 例2:
%   取引内容: 仕入(買掛金:負債&減少→左)
%         支払(現金:資産&減少→右)
%    仕訳: (借)買掛金 80 (貸)現金  80


boki0(t(0),'取引パタン',((L1,X,Z1),(L2,Y,Z2))):-
   boki0(c(_), '資金使途の項目', (X,Z1,L1)),
   boki0(c(_), '資金出所の項目', (Y,Z2,L2)),
   member((F,Z1),[(1,'増加'),(1,'発生'),(2,'減少'),(2,'取消')]),
   member((F,Z2),[(1,'増加'),(1,'発生'),(2,'減少'),(2,'取消')]),
   member(L1,['借方(左)','貸方(右)']),
   member(L2,['借方(左)','貸方(右)']),
   L2 \= L1.

boki0(t(1),'価格',(Y,'円')):-
   member(Y,[100,5000,12000,15000,30000,40000,50000,200000]).

boki0(t(2),'日付',D):-
   member(D, ['10月3日','8日','21日','31日','翌月']).

boki0(t(3),'取引先',E):-
   member(E,['太田商会','関東商店']).

boki0(t(4),'仕訳パタン',((X:Z1,Y:Z2),(L1:A,L2:B))):-
   boki0(t(0),'取引パタン',((L1,X,Z1),(L2,Y,Z2))),
   boki0(d(_,_),'勘定科目',(X,A)),
   boki0(d(_,_),'勘定科目',(Y,B)).

boki0(t(5),'仕訳データ',((X:Z1,Y:Z2),(L1:A,L2:B,C-'円',D,E))):-
   boki0(t(1),'価格',(C,'円')),
   boki0(t(2),'日付',D), %'省略可能'
   boki0(t(3),'取引先',E), % '省略可能'
   boki0(t(4),'仕訳パタン',((X:Z1,Y:Z2),(L1:A,L2:B))).

boki0(t(6),'仕訳清書',((L,OL,C-'円' ; R,OR,C-'円'),((X,Z1),(Y,Z2),D,E))):-
   boki0(t(5),'仕訳データ',((X:Z1,Y:Z2),(L1:A,L2:B,C-'円',D,E))),
   member(('借方(左)',OL,'(借)'),[(L1,A,L),(L2,B,L)]),
   member(('貸方(右)',OR,'(貸)'),[(L1,A,R),(L2,B,R)]).

siwake((P1,Q1),(P2,Q2),(L,A,Y),(R,B,Y),C):-
   boki0(d(P1,Q1),_,(_,A)),
   boki0(d(P2,Q2),_,(_,B)),
   boki0(t(6),'仕訳清書',((L,A,Y;R,B,Y),C)),
   write((L,A,Y;R,B,Y)),nl,write(C).


% siwake /5 は、勘定科目が右左とも1つづつのときに限り、
% 担当者が勘定科目を番号で指定し、取引の日付けや金額などと
% 共にデータ入力すると、正しい仕訳が出力される。

% boki0(t) のルール群は、最終的な仕訳に至るまでの中間的作業
% に相当し、取引や仕訳の正しいパタンと勘定科目を生成・確認
% することができるので、担当者の知的作業を助けになる。


%------------------------------------------------------------%
/* 出題・診断プログラム : sindan /0    */ 
%------------------------------------------------------------%
% imported and modified: file: quiz1.pl(5 Mar 2003)

% 学習者の仕訳知識を診断するためのテスト問題
% を出題し、回答を診断・分析する。より具体的には
% 以下の2タイプの知識にかんする質問の選択肢を、
% 乱数を使って生成する。
%--------------------------------
% 問題1:勘定科目と項目の関係について
% 問題2:仕訳のルールについて
%--------------------------------


%--------------------------------
% 問題データベース(生成プログラム)
%--------------------------------

% 問題文、選択肢、および正解
%--------------------------------

'質問'(1,'問題文','勘定科目と項目の関係で正しいものを選びなさい。',_):-
   L = [7,8,9,10,11],
   forall(member(N,L),
     (
      boki0(b(N), A, _),
      random_choice((X,Ans),
        (boki0(d(_,_),'勘定科目',(Ans,X)), Ans \= '未分類')
      ),
      (Ans = A -> Y = yes; Y = no),
      K is N - 6,
      update_qdata(1,K,(A,X,Y))
     )
   ).


'質問'(1,'選択肢'(K),(X-'は'-A-'である。'),Y):-
   L = [1,2,3,4,5],
   member(K,L),
   qdata(_,1,K,(A,X,Y)).

'質問'(1,'選択肢'(6),('以上の中に正しいものがない。'),Y):-
   (\+ qdata(_,1,_K,(_A,_X,yes)) -> Y = yes; Y = no).


'質問'(2,'問題文',('以下の選択肢の中から、正しいものを一つ選びなさい。'),_):-
   length(L,5),
   forall(nth1(K,L,_),
     (
      random_choice((A,B,Ans),
        boki0(c(_), '資金使途の項目', (A,B,Ans))
      ),
      random_choice(C,
        member(C,['借方(左)','貸方(右)'])
      ),
      (Ans = C -> Y = yes; Y = no),
      update_qdata(2,K,(A,B,C,Y))
     )
   ).

'質問'(2,'選択肢'(K),(A-'の'-B-'は'-C-'に記入する。'),Y):-
   L = [1,2,3,4,5],
   member(K,L),
   qdata(_,2,K,(A,B,C,Y)).

'質問'(2,'選択肢'(6),('以上の中に正しいものがない。'),Y):-
   (\+ qdata(_,2,_K,(_,_,_,yes)) -> Y = yes; Y = no).


%  問題生成コマンド
%--------------------------------
question(N,problem,Q,Y):-
   '質問'(N,'問題文',Q,Y).

question(N,alternative(No),S,Ans):-
   '質問'(N,'選択肢'(No),S,Ans).

%  問題の初期化・生成
%--------------------------------
init_qdata(N):-
   retractall(qdata(_,N,K,_A)),
   tstamp(no,T),
   assert(qdata(T,N,K,unspecified)).

update_qdata(N,K,A):-
   retractall(qdata(_,N,K,_B)),
   tstamp(no,T),
   assert(qdata(T,N,K,A)).


%  乱数によるゴールの選択
%--------------------------------
random_choice(G,P):-
   findall(G,P,Z),
   length(Z,N),
   R is random(N),
   nth0(R,Z,G).


%--------------------------------
% クイズ出題・採点プログラム
%--------------------------------

quiz(N):-
   init_qdata(N),
   question(N,problem,Text,_),
   wr_question(Text,60),
   wr_alternative(N),
   init_udata(N),
   user_input(User),
   question(N,alternative(User),_,Y),
   update_user_response(N,User,Y,C),
   wr_result(C,_M).


%--------------------------------
% 簡易インタフェース
%--------------------------------

% 問題文章の表示 etc.
%--------------------------------
wr_question(B,Y):-
   wr_star(_,Y),
   nl,tab(4),
   write(B),
   nl,
   wr_star(_,Y),
   nl.

% '選択肢'の表示
%--------------------------------
wr_alternative(N):-
   question(N,alternative(X),Y,_Z),
   tab(5),
   write(X),
   write('.  '),
   write(Y),
   nl,
   fail.

wr_alternative(_):-!.


% 採点結果表示
%--------------------------------
wr_result(C,M):- 
  (
   (C,M) = (1,'正解です!')
   ;
   (C,M) = (0,'不正解です。')
   ),
   wr_star(_,30),
   nl,tab(4),
   write(M),
   nl,
   wr_star(_,30),
   nl.


%  ユーザ回答記録の初期化・更新
%--------------------------------
init_udata(N):-
   retractall(udata(_T,N,_,_)).

update_user_response(N,U,Y,C):-
   (
    (Y,C) = (yes,1)
   ;
    (Y,C) = (no,0)
   ),
   retractall(udata(_,N,U,C)),
   tstamp(no,T),
   assert(udata(T,N,U,C)).


% ユーザーによる回答入力
%--------------------------------
user_input(User):-
  nl,tab(4),
  write('Type a number ( 番号を入力)->'),
  read(User).

%--------------------------------
% その他のユーティリティー
%--------------------------------

% データの画面表示
%--------------------------------
wn(Z):- write(Z), nl.

'書け'(X):-  write(X).


% ☆ラインの繰り返し
%--------------------------------
wr_star([],0).
wr_star(L,N):-
  length(L,N),
  X='*',
  L=[X|Y],
  write(X),
  wr_star(Y,N1),
  N1 is N - 1.


% ---------------------
% 質問・診断の実行
% ---------------------

% クイズ実行
% ---------------------
sindan:-
  quiz(_N),fail.

% 学習診断と教示のメイン
% ---------------------
sindan:-
   nl,
   write('% --------------------------'),nl,
   write('%  診断結果を出力します。(y)'),nl,
   write('% --------------------------'),nl,
   read(y),
   sindan0,
   save_results.

sindan0:-
   umodel(A,B,C,D), 
   kyoji(A,B,C,D),
   fail.

sindan0:- 
   nl,
   write('% 診断おわり。').


% 学習者モデル抽出サブシステム
%--------------------------------
umodel(1,B,C,0):-
   C = (X,Y,no),
   qdata(_,1,B,C),
   udata(_,1,B,0),
   nl,
   write('% --------------------------'),
   nl,
   write('% 質問 1 で'),
   write('不正解だった回答パタン:'),
   nl,
   write('% あなたの選んだ答え:'),
   write(((X,Y),'選択肢番号'=B)),
   nl.

umodel(2,B,C,0):-
   C = (X,Y,Z,no),
   qdata(_,2,B,C),
   udata(_,2,B,0),
   nl,
   write('% --------------------------'),
   nl,
   write('% 質問 2 で'),
   write('不正解だった回答パタン:'),
   nl,
   write('% あなたの選んだ答え:'),
   write(((X,Y,Z),'選択肢番号'=B)),nl,
   nl.

umodel(1,B,C,1):-
   C = (X,Y,yes),
   qdata(_,1,B,C),
   udata(_,1,B,1),
   nl,
   write('% --------------------------'),
   nl,
   write('% 質問 1 は正解でした。'),
   nl,
   write('% あなたの選んだ答え:'),
   write(((X,Y),'選択肢番号'=B)),
   nl.

umodel(2,B,C,1):-
   C = (X,Y,Z,yes),
   qdata(_,2,B,C),
   udata(_,2,B,1),
   nl,
   write('% --------------------------'),
   nl,
   write('% 質問 2 は正解でした。'),
   nl,
   write('% あなたの選んだ答え:'),
   write(((X,Y,Z),'選択肢番号'=B)),nl,
   nl.


% 教示サブシステム
%--------------------------------
kyoji(1,_K,(A,B,no),0):-
   nl,
   write('% まちがえた項目と科目の関係:'),
   write((A,B)),nl,
   boki0(d(_,_),'勘定科目',(A1,B)),
   write('% 正しくは、この科目は「'),
   write(A1),write('」に属します。'),nl,
   write('% これらの項目、「'), 
   write(A1),write('」と「'),write(A),
   write('」に属する科目を復習してください。'),nl,
   wr_right_answer(1),
   nl.

kyoji(2,_K,(A,B,C0,no),0):-
   boki0(c(_), W, (A,B,C)),
   nl,
   (
    boki0(c(_), W, (A,B,_)),
    write('% あなたが答えた項目は「'),
    write(W),
    write('」をあらわすものです。ですから、'),nl,
    write('% 基本ルールにより、'),
    write(C0),write(' ではなく、'),
    write(C),write(' に記入します。')
   ),
   nl,
   wr_right_answer(2),
   nl.

kyoji(1,_K,(_A,_B,yes),1):-
   nl,
   write('% これにかんしては、とくにアドバイスはありません。'),
   nl.

kyoji(2,_K,(_A,_B,_C,yes),1):-
   nl,
   write('% これにかんしては、とくにアドバイスはありません。'),
   nl.

wr_right_answer(1):-
   nl,
   write('% ちなみに、この問題の正解選択肢は、'),
   tab(2),
   (
    qdata(_,1,J,(A1,B1,yes))->
     (
      write((A1,B1,'選択肢番号':J)),
      write('でした。'),nl,
      write('% この項目/科目も復習してください。')
     )
    ;
     write('ありませんでした。')
   ).

wr_right_answer(2):-
   nl,
   qdata(_,2,J,(A1,B1,C1,yes)),
   boki0(c(_), W1, (A1,B1,C1)),
   !,
   nl,
   write('% ちなみにこの問題の正解のひとつは、'),
   write((A1,B1,C1,'選択肢番号':J)),
   write('でした。'),nl,
   write('% また項目「'),
   write(A1),
   write('」は'),
   write(W1),
   write('です。').

% 問題と診断結果の保存
%--------------------------------
save_results:-
   nl,
   write('% ------------------------------------------'),nl,
   write('%  問題と診断結果をファイルに保存します。(y)'),nl,
   File='sindan0.txt',
   write('%  なお保存先ファイル名は、'),
   write(File),
   write('%  です。'),nl,
   write('% ------------------------------------------'),nl,
   (
    read(y)
     ->
      (
       G=forall(
         ((D = qdata(_,A,B,C);D = udata(_,A,B,C)),D),
         (nl,write(D),write('.'))
       ),
       tell_goal(File,(nl,G,nl,sindan0,nl))
      )
     ;
      (
       write('確認:ファイル保存しないのですね?(y)'),
       (read(y)->true; save_results),
       write('了解。'),
       nl
      )
   ).



% 任意ゴール実行中画面の保存
%--------------------------------
tell_goal(File,G):-
  %File='sindan0.txt',
   (current_stream(File,write,S0)->close(S0);true),
%   open(File,write,S,[alias(siwa0)]),
   open(File,write,S),
   tell(File),
   nl,
   tstamp('% file output start time ',_),
   nl,
   write('%----------  start from here ------------%'),
   G,
   write('%----------  end of data ------------%'),
   nl,
   tstamp('% file output end time ',_),
   tell(user),
   close(S),
   % The following is to cope with the duplicated stream problem.
   % Sorry, I'm not ascertain now the cause of it whether a bug of swi. 
   (current_stream(File,write,S1)->close(S1);true).


% 実行時刻の取得
%--------------------------------
tstamp(no,T):-
   get_time(U),
   convert_time(U,A,B,C,D,E,F,_G),
   T = [date(A/B/C), time(D:E:F)],
   nl.

tstamp(Word,T):-
   \+ var(Word),
   Word \= no,
   get_time(U),
   convert_time(U,A,B,C,D,E,F,_G),
   T = [date(A/B/C), time(D:E:F)],
%   format('~`.t~t~a~30|~`.t~t~70|~n',[Word]),
   write((Word,T)),
   nl.



% プログラムの終わり





return to front page.