• 検索結果がありません。

JButton b = new JButton(" "); JTextArea ta = new JTextArea(); JScrollPane sp1 = new JScrollPane(li); JScrollPane sp2 = new JScrollPane(ta); int width

N/A
N/A
Protected

Academic year: 2021

シェア "JButton b = new JButton(" "); JTextArea ta = new JTextArea(); JScrollPane sp1 = new JScrollPane(li); JScrollPane sp2 = new JScrollPane(ta); int width"

Copied!
16
0
0

読み込み中.... (全文を見る)

全文

(1)

import java.util.*; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** * RuleBaseSystem * */

public class RuleBaseSystem extends JApplet implements ActionListener { static RuleBase rb;

JPanel p1 = new JPanel(); JPanel p2 = new JPanel();

String[] s = { "my-car is inexpensive", "my-car is expensive",

"my-car is small", "my-car is big", "my-car needs a lot of gas",

"my-car is a hybrid car", "my-car has Toyota's logo", "my-car has Honda's logo", "my-car is a popular car", "my-car has a VTEC engine", "my-car has a big engine", "my-car has several seats", "my-car has only 2 seats", "my-car is a wagon", "my-car is a sports car",

"my-car has several color models", "my-car is red", "my-car is stylish", "my-car is a good face", "my-car has an aluminium body" };

JLabel la = new JLabel("ルールベースシステム"); JList li = new JList(s);

(2)

JButton b = new JButton("→"); JTextArea ta = new JTextArea();

JScrollPane sp1 = new JScrollPane(li); JScrollPane sp2 = new JScrollPane(ta); int width = 600;

int top = 30; int bottom = 250;

public void init() { setLayout(null);

setSize(width, top + bottom); p1.setLayout(new FlowLayout()); p1.add(la);

p1.setBounds(0, 0, width, top); p2.setLayout(new GridLayout(1, 3)); p2.add(sp1);

b.addActionListener(this); p2.add(b);

p2.add(sp2);

p2.setBounds(0, top, width, bottom); add(p1);

add(p2); }

@Override

public void actionPerformed(ActionEvent arg0) { if (li.getSelectedIndex() == -1) JOptionPane.showMessageDialog(null, "何も選択されていま せん"); else { rb = new RuleBase(li.getSelectedValues()); printResult((rb.forwardChain())); } }

(3)

public void printResult(String result) {

StringTokenizer st = new StringTokenizer(result.trim(), ",[]"); String s = ""; String t; while (st.hasMoreTokens()) { t = st.nextToken(); s += t + "\n"; } ta.setText(s); } } /** * ワーキングメモリを表すクラス. * * */ class WorkingMemory { // アサーションは現在の状態の集合 ArrayList<String> assertions; WorkingMemory() {

assertions = new ArrayList<String>(); } /** * 前件にマッチするアサーションに対するバインディング情報を返す<br/> * 再帰的に matchable メソッドを呼び出して変数の束縛情報を得る<br/> * (バインディング≡変数束縛情報) * * @param 前件を示す * ArrayList * @return バインディング情報が入っている ArrayList */

(4)

ArrayList<String> theAntecedents) {

// 複数の変数の束縛を保存するためのハッシュマップのリスト

ArrayList<HashMap<String, String>> bindings = new ArrayList<HashMap<String, String>>();

// 照合開始

return matchable(theAntecedents, 0, bindings); } /** * 実際に前件にマッチするアサーションに対するバインディング情報を返すメ ソッド * * @param theAntecedents * 前件を表す ArrayList * @param n * マッチする回数(前件の数だけ) * @param bindings * これまでの変数の束縛情報のリスト * @return 新たに分かった変数の束縛情報リスト */

private ArrayList<HashMap<String, String>> matchable( ArrayList<String> theAntecedents, int n, ArrayList<HashMap<String, String>> bindings) { // 全ての前件に対してチェックが終わったら if (n == theAntecedents.size()) { // これまでの束縛情報を返す return bindings; } // 1回目 else if (n == 0) { // 成功フラグ

boolean success = false; // アサーションの数だけループ

for (int i = 0; i < assertions.size(); i++) { // 変数の束縛を保存するハッシュマップの作成

(5)

HashMap<String, String>(); // 前件とアサーションを照合 if ((new Matcher()).matching(theAntecedents.get(n), assertions.get(i), binding)) { // 解った束縛情報の更新 bindings.add(binding); // 成功のフラグを立てる success = true; } } // 1回でも成功した場合は次の前件について照合 if (success) {

return matchable(theAntecedents, n + 1, bindings); } // 1回も成功しなかったら失敗 else { return null; } } // 2回目以降 else { // 成功フラグ

boolean success = false;

// 新たな束縛情報のリストの作成

ArrayList<HashMap<String, String>> newBindings = new ArrayList<HashMap<String, String>>();

// これまでの束縛情報の候補だけループ for (int i = 0; i < bindings.size(); i++) {

for (int j = 0; j < assertions.size(); j++) {

if ((new Matcher()).matching(theAntecedents.get(n),

assertions.get(j), bindings.get(i))) {

(6)

newBindings.add(bindings.get(i)); success = true; } } } // 1回でも成功したら if (success) { return matchable(theAntecedents, n + 1, newBindings); } // 1回も成功しなかった時 else { return null; } } } /** * アサーションをワーキングメモリに加える. * * @param アサーションを表す文字列 */

public void addAssertion(String theAssertion) { System.out.println("ADD:" + theAssertion); assertions.add(theAssertion); } /** * 指定されたアサーションがすでに含まれているかどうかを調べる. * * @param アサーションを表す * String

(7)

*/

public boolean contains(String theAssertion) { return assertions.contains(theAssertion); } /** * ワーキングメモリの情報をストリングとして返す. * * @return ワーキングメモリの情報を表す String */

public String toString() {

return assertions.toString(); } } /** * ルールベースを表すクラス. * * */ class RuleBase { String fileName; FileReader f; StreamTokenizer st; WorkingMemory wm; ArrayList<Rule> rules; /** * コンストラクタ * * @param assertion * リストで選ばれた状態の一覧 */

public RuleBase(Object[] assertion) { // ファイルのパス

(8)

fileName = "???/CarShop.data"; // ワーキングメモリーの生成 wm = new WorkingMemory();

for (int i = 0; i < assertion.length; i++) // String 型に直して追加

wm.addAssertion(String.valueOf(assertion[i])); rules = new ArrayList<Rule>();

// ルールの読み込み loadRules(fileName); } /** * 前向き推論を行うためのメソッド<br/> * 新しいアサーションが生成されなくなるまで以下を続ける<br/> * <ol> * <li>前件とアサーションのマッチングを行う</li> * <li>マッチングに成功したら後件を新たなアサーションとしてワーキングメ モリに追加</li> * </ol> */

public String forwardChain() { boolean newAssertionCreated; // 新しいアサーションが生成されなくなるまで続ける. do { // 新しくアサーションが生成されたかどうかのフラグ newAssertionCreated = false; // ルールの数だけループ

for (int i = 0; i < rules.size(); i++) { // ルールを先頭から取得

Rule aRule = rules.get(i); // 一応表示 System.out.println("apply rule:" + aRule.getName()); // 取得したルールの前件を取得 ArrayList<String> antecedents = aRule.getAntecedents();

(9)

// 取得したルールの後件を取得

String consequent = aRule.getConsequent(); // マッチング開始

ArrayList<HashMap<String, String>> bindings = wm

.matchingAssertions(antecedents);

// 変数の束縛情報がない→(マッチング失敗) if (bindings != null) {

// 束縛情報のリスト分ループ

for (int j = 0; j < bindings.size(); j++) { // 後件をインスタンシエーション String newAssertion = instantiate((String) consequent, bindings.get(j)); // ワーキングメモリーになければ 成功 if (!wm.contains(newAssertion)) { System.out.println("Success: " + newAssertion); wm.addAssertion(newAssertion); // フラグをセット newAssertionCreated = true; } } } } System.out.println("Working Memory" + wm); } // 新しいアサーションが生成される限り do 内を繰り返す while (newAssertionCreated);

System.out.println("No rule produces a new assertion"); // ワーキングメモリの内容を返す

(10)

return wm.toString(); }

/**

* 後件に含まれる変数を束縛情報を利用して具体化するメソッド<br/> * ?x is made in Japan → my-car is made in Japan

* * @param thePattern * 後件 * @param theBindings * 束縛情報 * @return 具体化された後件 */

private String instantiate(String thePattern, HashMap theBindings) { String result = "";

// 後件をトークンに分割

StringTokenizer st = new StringTokenizer(thePattern); // トークンの数だけループ

for (int i = 0; i < st.countTokens();) { String tmp = st.nextToken(); // トークンが束縛情報に含まれる if (var(tmp)) {

// 変数なら束縛情報から文字列を取り出す

result = result + " " + (String) theBindings.get(tmp); } // それ以外はそのまま else { result = result + " " + tmp; } } return result.trim(); }

private boolean var(String str1) { // 先頭が ? なら変数

(11)

return str1.startsWith("?"); } /** * ルールを読み込むメソッド * * @param theFileName * ファイルの名前 */

private void loadRules(String theFileName) { String line; try { int token; f = new FileReader(theFileName); st = new StreamTokenizer(f); // ファイルを読み終わるまで続ける

while ((token = st.nextToken()) != StreamTokenizer.TT_EOF) { // 読み込んだものによって処理を変える switch (token) { // 文字 case StreamTokenizer.TT_WORD: // 各変数の初期化 String name = null;

ArrayList<String> antecedents = null; String consequent = null;

// 読み込んだ部分が"rule"のとき if ("rule".equals(st.sval)) { // 次に進める st.nextToken(); // ルールの名前を name に保存 name = st.sval; // 次に進める st.nextToken(); // 読み込んだ部分が"if"のとき if ("if".equals(st.sval)) {

(12)

antecedents = new ArrayList<String>(); st.nextToken(); // 前件は複数ある場合が あるので"then"と一致するまで保存する while (!"then".equals(st.sval)) { antecedents.add(st.sval); st.nextToken(); } // 同じように後件の保存 if ("then".equals(st.sval)) { st.nextToken(); consequent = st.sval; } } } // ルールの生成

rules.add(new Rule(name, antecedents, consequent)); break; // 文字以外(数字とか改行とか) default: System.out.println("エラー?" + token); break; } } } catch (Exception e) { System.out.println(e); }// ルールの表示

for (int i = 0; i < rules.size(); i++) {

System.out.println(rules.get(i).toString()); }

(13)

} } /** * ルールを表すクラス. */ class Rule { // 名前 String name; // 前件 ArrayList<String> antecedents; // 後件 String consequent; // コンストラクタ

Rule(String theName, ArrayList<String> theAntecedents, String theConsequent) { this.name = theName; this.antecedents = theAntecedents; this.consequent = theConsequent; } /** * ルールの名前を返す. * * @return 名前を表す String */

public String getName() { return name; } /** * ルールを String 形式で返す * * @return ルールを整形した String */

(14)

public String toString() {

return name + " " + antecedents.toString() + "->" + consequent; } /** * ルールの前件を返す. * * @return 前件を表す ArrayList */

public ArrayList<String> getAntecedents() { return antecedents; } /** * ルールの後件を返す. * * @return 後件を表す String */

public String getConsequent() { return consequent; } } class Matcher { StringTokenizer st1; StringTokenizer st2;

HashMap<String, String> vars;

Matcher() {

vars = new HashMap<String, String>(); }

/**

* 予め変数の束縛が決まっている場合はこっちを呼び出す *

(15)

* 比較するトークン1 * @param string2 * 比較するトークン2 * @param bindings * 事前にわかっている変数の束縛リスト * @return 照合成功かどうか */

public boolean matching(String string1, String string2, HashMap<String, String> bindings) { this.vars = bindings;

return matching(string1, string2); }

public boolean matching(String string1, String string2) { // 同じなら成功 if (string1.equals(string2)) return true; // 各々トークンに分ける st1 = new StringTokenizer(string1); st2 = new StringTokenizer(string2); // 数が異なったら失敗 if (st1.countTokens() != st2.countTokens()) return false; // 定数同士

for (int i = 0; i < st1.countTokens();) {

if (!tokenMatching(st1.nextToken(), st2.nextToken())) { // トークンが一つでもマッチングに失敗したら失敗 return false; } } // 最後まで O.K. なら成功 return true;

(16)

}

boolean tokenMatching(String token1, String token2) { if (token1.equals(token2))

return true;

if (var(token1) && !var(token2))

return varMatching(token1, token2); if (!var(token1) && var(token2))

return varMatching(token2, token1); return false;

}

boolean varMatching(String vartoken, String token) { if (vars.containsKey(vartoken)) { if (token.equals(vars.get(vartoken))) { return true; } else { return false; } } else { vars.put(vartoken, token); } return true; } boolean var(String str1) { // 先頭が ? なら変数 return str1.startsWith("?"); } }

参照

関連したドキュメント

In view of the result by Amann and Kennard [AmK14, Theorem A] it suffices to show that the elliptic genus vanishes, when the torus fixed point set consists of two isolated fixed

We develop three concepts as applications of Theorem 1.1, where the dual objects pre- sented here give respectively a notion of unoriented Kantorovich duality, a notion of

In this survey paper we present the natural applications of certain integral inequalities such as Chebychev’s inequality for synchronous and asynchronous mappings, H61der’s

The (strong) slope conjecture relates the degree of the col- ored Jones polynomial of a knot to certain essential surfaces in the knot complement.. We verify the slope conjecture

We construct some examples of special Lagrangian subman- ifolds and Lagrangian self-similar solutions in almost Calabi–Yau cones over toric Sasaki manifolds.. Toric Sasaki

In this section, we show that, if G is a shrinkable pasting scheme admissible in M (Definition 2.16) and M is nice enough (Definition 4.9), then the model category structure on Prop

If K is positive-definite at the point corresponding to an affine linear func- tion with zero set containing an edge E along which the boundary measure vanishes, then in

A cyclic pairing (i.e., an inner product satisfying a natural cyclicity condition) on the cocommutative coalge- bra gives rise to an interesting structure on the universal