/**
 *  bondInferenceEngine.java
 *  @contains a wrapper for JESS (Java Expert System Shell).
 *
 *  @author Kyungkoo Jun
 *  Bond group, CS, Purdue Univ.
 *  @date February 24, 1999
 */

package bond.agent.strategydb;

import jess.*;
import bond.core.*;
import java.io.*;

public class bondInferenceEngine
extends bondObject {

   public  Rete infegn;
   private StringBuffer kbase;

   public bondInferenceEngine() {
      infegn = new Rete();
      infegn.addUserpackage(new jess.ReflectFunctions()); // necessary for Bean support
      infegn.addUserpackage(new jess.StringFunctions());
   }

   public void setAlias(String n) {
      dir.addAlias("n", this);
   }

   public boolean executeCmd(String cmd) {
      try {
         infegn.executeCommand(cmd);
         return true;
      }
      catch (JessException e) {
         return false;
      }
   }

   public boolean insert_fact(String fact) {
      try {
         infegn.assertString(fact);
      }
      catch (JessException rexp) {
         rexp.printStackTrace();
         return false;
      }
      return true;
   }

   public boolean remove_fact(String fact) {
      try {
      infegn.retractString(fact);
      }
      catch (JessException rexp) {
         rexp.printStackTrace();
         return false;
      }
      return true;
   }

   public String show_facts() {
         return infegn.ppFacts();
   }

   public boolean clear_infegn() {
      try {
         infegn.clear();
         return true;
      }
      catch (JessException rexp) {
         rexp.printStackTrace();
         return false;
      }
   }

   public boolean reset_infegn() {
      try {
         infegn.reset();
         return true;
      }
      catch (JessException rexp) {
         rexp.printStackTrace();
         return false;
      }
   }

   /**
    * load rules and facts
    */
   public boolean load_kbase(StringBuffer kbase) {

      if (kbase == null)
         return false;

      this.kbase = kbase;

      //clear_infegn();

      StringReader sr = new StringReader(kbase.toString());
      Jesp jesp = new Jesp(sr, infegn);

      try {
         jesp.parse(false);
      }
      catch (JessException rexp) {
         rexp.printStackTrace();
         return false;
      }
      return true;
   }

   public void loadRulefromFile(String fname) {

      try {
         RandomAccessFile f = new RandomAccessFile(fname, "r");

	      StringBuffer s = new StringBuffer("");
	      String str;
	      while ( (str = f.readLine()) != null)
	         s = s.append(str+"\n");

	      if (!load_kbase(s)) {
	         System.out.println("Rule Loading Error");
	      }
      }
      catch (FileNotFoundException e) {
         e.printStackTrace();
      }
      catch (IOException e) {
         e.printStackTrace();
      }
   }

   public void addOutputRouter(String s, Writer w) {
      infegn.addOutputRouter(s, w);
   }

   public void run(int n) {

      try {
         infegn.run(n);
      }
      catch (JessException rexp) {
         rexp.printStackTrace();
      }
   }

   public StringBuffer getKBASE() {
      return kbase;
   }

   public boolean insertObject(String tmpltname, Object o) {
      try {
         Funcall f = new Funcall("definstance", this.infegn);
         f.add(new Value(tmpltname, RU.ATOM));
         f.add(new Value(o));
         f.execute(this.infegn.getGlobalContext());
      }
      catch (Exception e) {
         e.printStackTrace();
         return false;
      }
      return true;
   }

   public void say(bondMessage msg, bondObject sender) {
      System.out.println(msg.compose());
      String s = (String)msg.getParameter(":value");
      System.out.println("Result is: "+s);
      insert_fact("(replied-with "+s+")");
      run(10);
   }

   public void storeObject(String s, Object o) {
      infegn.store(s, o);
   }
}


