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. % プログラムの終わり