-1

我在 CLIPSJNI 中有一个 AI 项目,名为“购买割草机的建议”

我有两个 .CLP 文件:konowledgebase.clp、control.clp 和 1 个 java 文件:Ksiarki.java

知识库.clp:

(defrule philips ""
   (naped ENGINE)
   (mechanizm TRADYCYJNY)
   (dodatki KOSZ)
   (cena DO_500)
 =>
   (assert(result
            (producent "Philips")
            (typ "XDD3")
            (rodzaj "spalinowa"))
            (cena "450")))

控制.clp:

(deftemplate currentState
   (slot name (default none))
   (slot state (default middle))
   (slot text)      
   (slot answerType (default radioButton))
   (multislot selected)
   (multislot answers)
)

(deftemplate result
   (slot producent (type STRING))
   (slot typ (type STRING))
   (slot rodzaj (type STRING))
   (slot cena (type INTEGER))
)

; Startup window
(defrule system-banner ""
 =>
   (assert (currentState 
      (text START_TEXT)
      (name start)
      (state initial)
      (answers))
   )
)

; Results window
(defrule EndOfQuestions ""
   ?state<-(currentState)
   (end)
 =>
   (retract ?state) 
   (assert (currentState 
      (text NO_RESULTS_END_TEXT)
      (state final)
   ))
)

; Pytanie o powierzchnie
(defrule selectPowierzchnia ""
    ?state<-(currentState)
    (not(pytaniePowierzchnia))
    =>
    (retract ?state) 
    (assert (pytaniePowierzchnia))  
    (assert (currentState
        (name powierzchnia)
        (text SELECT_PYTANIE_POWIERZCHNIA)
        (answerType checkBox)
        (answers 10 20 30 40 50 100 200 300 400 500 1000 2000 3000 4000 5000)
        (selected)
    ))
)

; Pytanie o mechanizm tnacy ====== bezsilnikowy ======
(defrule selectMechanizm ""
    ?state<-(currentState)
    (not(pytanieMechanizm))
    (powierzchnia)
    (naped NOENGINE)
    (naped ELECTRIC)
    =>
    (retract ?state) 
    (assert (pytanieMechanizm)) 
    (assert (currentState
        (name mechanizm)
        (text SELECT_PYTANIE_MECHANIZM)
        (answerType checkBox)
        (answers TRADYCYJNY ROTACYJNY ZYLKOWY WRZECIONOWY BIJAKOWY KARCZUJACY LISTWOWY)
        (selected)
    ))
)

; Pytanie o mechanizm tnacy ====== elektryczny ======
(defrule selectMechanizm ""
    ?state<-(currentState)
    (not(pytanieMechanizm))
    (powierzchnia)
    (naped ELECTRIC)
    (naped ENGINE)
    =>
    (retract ?state) 
    (assert (pytanieMechanizm)) 
    (assert (currentState
        (name mechanizm)
        (text SELECT_PYTANIE_MECHANIZM)
        (answerType checkBox)
        (answers TRADYCYJNY ROTACYJNY ZYLKOWY WRZECIONOWY BIJAKOWY KARCZUJACY LISTWOWY)
        (selected)
    ))
)

; Pytanie o mechanizm tnacy ====== spalinowy ======
(defrule selectMechanizm ""
    ?state<-(currentState)
    (not(pytanieMechanizm))
    (powierzchnia)
    (naped ENGINE)
    =>
    (retract ?state) 
    (assert (pytanieMechanizm)) 
    (assert (currentState
        (name mechanizm)
        (text SELECT_PYTANIE_MECHANIZM)
        (answerType checkBox)
        (answers TRADYCYJNY ROTACYJNY ZYLKOWY WRZECIONOWY BIJAKOWY KARCZUJACY LISTWOWY)
        (selected)
    ))
)

; Pytanie o dodatki
(defrule selectDodatki ""
    ?state<-(currentState)
    (not(pytanieDodatki))
    (mechanizm TRADYCYJNY|ROTACYJNY|ZYLKOWY|WRZECIONOWY|BIJAKOWY|KARCZUJACY|LISTWOWY)
    =>
    (retract ?state) 
    (assert (pytanieDodatki))   
    (assert (currentState
        (name dodatki)
        (text SELECT_PYTANIE_DODATKI)
        (answerType checkBox)
        (answers MULCZOWANIE KOSZ TARCZA ROZRUSZNIK BLOKADA NAPED NIE)
        (selected)
    ))
)

; Pytanie o cene
(defrule selectCena ""
    ?state<-(currentState)
    (not(pytanieCena))
    (dodatki MULCZOWANIE|KOSZ|TARCZA|ROZRUSZNIK|BLOKADA|NAPED)
    =>
    (retract ?state)
    (assert (PytanieCena))
    (assert (currentState
        (name cena)
        (text SELECT_PYTANIE_CENA)
        (answerType checkBox)
        (answers 10 20 30 40 50 100 200 300 400 500 1000 2000 3000 4000 5000)
        (selected)
    ))
    (assert (end))
)

(defrule suma_pow_init
   ?i<-(powierzchnia ?p $?rp)
   (not(suma_pow ?))
 =>
   (retract ?i)
   (assert(powierzchnia $?rp))
   (assert(suma_pow ?p)))

(defrule sumuj
   ?i<-(powierzchnia ?p $?rp)
   ?j<-(suma_pow ?s $?rs)
 =>
   (retract ?i ?j)
   (assert(powierzchnia $?rp))
   (assert(suma_pow (+ ?p ?s))))

(defrule nast_pyt_pow1
   (powierzchnia)
   (suma_pow ?s)
   (test(< ?s 150))
 =>
   (assert(naped NOENGINE))
   (assert(naped ELECTRIC)))

(defrule nast_pyt_pow2
   (powierzchnia)
   (suma_pow ?s)
   (test(>= ?s 150))
   (test(< ?s 750))
 =>
   (assert(naped ELECTRIC))
   (assert(naped ENGINE)))

(defrule nast_pyt_pow3
   (powierzchnia)
   (suma_pow ?s)
   (test(< ?s 750))
 =>
   (assert(naped ENGINE)))

(defrule suma_cen_init
   ?i<-(cena ?c $?rc)
   (not(suma_cen ?))
 =>
   (retract ?i)
   (assert(cena $?rc))
   (assert(suma_cen ?c)))

(defrule sumuj_ceny
   ?i<-(cena ?c $?rc)
   ?j<-(suma_cen ?s $?rs)
 =>
   (retract ?i ?j)
   (assert(cena $?rc))
   (assert(suma_cen (+ ?c ?s))))

(defrule nast_pyt_cena1
   (cena)
   (suma_cen ?s)
   (test(< ?s 450))
 =>
   (assert(cena MALA)))

(defrule nast_pyt_cena1
   (cena)
   (suma_cen ?s)
   (test(< ?s 500))
   (test(>= ?s 450))
 =>
   (assert(cena DO_500)))

(defrule nast_pyt_cena2
   (cena)
   (suma_cen ?s)
   (test(>= ?s 500))
   (test(< ?s 750))
 =>
   (assert(cena DO_750)))

(defrule nast_pyt_cena3
   (cena)
   (suma_cen ?s)
   (test(>= ?s 750))
   (test(< ?s 1500))
 =>
   (assert(cena DO_1500)))

(defrule nast_pyt_cena4
   (cena)
   (suma_cen ?s)
   (test(>= ?s 1500))
   (test(< ?s 3000))
 =>
   (assert(cena DO_3000)))

(defrule nast_pyt_cena5
   (cena)
   (suma_cen ?s)
   (test(>= ?s 3000))
   (test(< ?s 5000))
 =>
   (assert(cena DO_5000)))

(defrule nast_pyt_cena6
   (cena)
   (suma_cen ?s)
   (test(>= ?s 5000))
   (test(< ?s 10000))
 =>
   (assert(cena DO_10000)))

(defrule nast_pyt_cena7
   (cena)
   (suma_cen ?s)
   (test(>= ?s 10000))
 =>
   (assert(cena OD_10000)))

Kosiarki.java:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.List;
import java.util.Properties;

import javax.swing.SwingUtilities;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JCheckBox;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import CLIPSJNI.Environment;
import CLIPSJNI.FactAddressValue;
import CLIPSJNI.MultifieldValue;
import CLIPSJNI.PrimitiveValue;
import CLIPSJNI.SymbolValue;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import java.util.Comparator;
import javax.swing.table.TableColumn;

public class Kosiarki implements ActionListener
{
 private Environment clips;
 private Properties properties;
 private ButtonGroup answerButtons;
 private JTextPane textPane;
 private JButton nextButton;
 private JPanel answerPanel;
 private JTable answersTable;
 private String assertedKosiarka;
 private String lastAssertedKosiarka="";

 public Kosiarki()
 {
  // okno
  JFrame frame=new JFrame("AI Name Project");
  frame.getContentPane().setLayout(new GridLayout(3, 1));
  frame.setSize(500, 300);
  frame.setLocationByPlatform(true);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  // panel - piewszy wiersz tableli 1x3 - do wyswietlania tekstow(glownie pytan)
  JPanel textPanel=new JPanel();
  textPane=new JTextPane();
  textPane.setOpaque(false);
  textPane.setEditable(false);

  StyledDocument doc=textPane.getStyledDocument();
  SimpleAttributeSet center=new SimpleAttributeSet();
  StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
  doc.setParagraphAttributes(0, doc.getLength(), center, false);

  textPanel.add(textPane);

  // panel - drugi wiersz tableli 1x3 - do wyswietlania checkboksow i radiobuttonow
  answerPanel=new JPanel();
  answerButtons=new ButtonGroup();

  // panel - trzeci i ostatni wiersz tableli 1x3 - do wyswietlania przycisku "next"
  JPanel nextButtonPanel=new JPanel();
  nextButton=new JButton();
  nextButton.setActionCommand("next");
  nextButtonPanel.add(nextButton);
  nextButton.addActionListener(this);

  // wstawiamy na okno wszystkie trzy panele
  frame.getContentPane().add(textPanel);
  frame.getContentPane().add(answerPanel);
  frame.getContentPane().add(nextButtonPanel);
  frame.setVisible(true);

  // inicjalizacja CLIPS-a
  clips=new Environment();
  clips.load("control.clp");
  clips.load("knowledgeBase.clp");
  clips.reset();
  clips.run(1);

  // ititializing file with properties
  properties=new Properties();
  loadProperties(new File("configuration.properties"));

  // w praktyce pokazujemy okno wstepne
  nextUIState();
 }

 private void nextUIState()
 {
  answerPanel.removeAll();

  // pobieramy aktualny stan UI
  MultifieldValue currentStateMultifieldValue=(MultifieldValue)clips.eval("(find-all-facts((?f currentState))TRUE)");
  List<FactAddressValue> currentStateList=currentStateMultifieldValue.listValue();
  if(currentStateList.isEmpty())
  {
   return;
  }
  FactAddressValue currentState=currentStateList.get(0);

  // sprawdzamy czy nie "zablokowalismy" sie na "name"
  assertedKosiarka=currentState.getFactSlot("name").toString();
  if(assertedKosiarka.contentEquals(lastAssertedKosiarka))
  {
   clips.run(1);
   nextUIState();
   return;
  }
  lastAssertedKosiarka=assertedKosiarka;

  // ustawienie nazw przycisku "next"/"restart"/"start"
  if(currentState.getFactSlot("state").toString().equals("final"))
  {
   nextButton.setActionCommand("restart");
   nextButton.setText(properties.getProperty("RESTART").toString());

   // Dodatkowo wypisywanie wynikow
   MultifieldValue namesMultifieldValue=(MultifieldValue)clips.eval("(find-all-facts((?f result))TRUE)");
   List<FactAddressValue> nameList=namesMultifieldValue.listValue();

   if(!nameList.isEmpty())
   {
    textPane.setText(properties.getProperty("RESULTS_END_TEXT").toString());
    System.out.println("pasujące kosiarki:");

    String headers[]={
      properties.getProperty("PRODUCENT"),
      properties.getProperty("TYP"),
      properties.getProperty("RODZAJ"),
      properties.getProperty("CENA")};

    ArrayList<Result> resultList=new ArrayList<Result>();
    for(FactAddressValue name : nameList)
    {
     resultList.add(new Result(
       name.getFactSlot("producent").getValue().toString(),
       name.getFactSlot("typ").getValue().toString(),
       name.getFactSlot("rodzaj").getValue().toString(),
       name.getFactSlot("cena").getValue().toString()));
    }

    Collections.sort(resultList, new ResultComperator());

    String data[][]=new String[nameList.size()][4];
    int i=0;
    for(Result result : resultList)
    {
     data[i][0]=properties.getProperty(result.getProducent());
     data[i][1]=result.getTyp();
     data[i][2]=result.getRodzaj();
     data[i][3]=result.getCena();

     String newName=data[i][0] + "(" + data[i][1] + ")";
     System.out.println(newName);

     i++;
    }

    answersTable=new JTable(data, headers);
    answersTable.setPreferredScrollableViewportSize(new Dimension(answerPanel.getWidth()- 25, answerPanel.getHeight()- 25));
    answersTable.getTableHeader().setReorderingAllowed(false);
    answersTable.setEnabled(false);

    TableColumn column=new TableColumn();
    column=answersTable.getColumnModel().getColumn(0);
    column.setMaxWidth(100);

    JScrollPane scrollPane=new JScrollPane(answersTable);

    answerPanel.add(scrollPane);
   }
   else
   {
    textPane.setText(properties.getProperty("NO_RESULTS_END_TEXT").toString());
   }

   answerPanel.repaint();
   return;
  }
  else if(currentState.getFactSlot("state").toString().equals("initial"))
  {
   nextButton.setActionCommand("start");
   nextButton.setText(properties.getProperty("START").toString());
  }
  else
  {
   nextButton.setActionCommand("next");
   nextButton.setText(properties.getProperty("NEXT").toString());
  }

  // ustawienie tekstu(np. pytania)
  String text=((SymbolValue)currentState.getFactSlot("text")).stringValue();
  textPane.setText(properties.getProperty(text).toString());

  // Wstawiamy przyciski(comboboksy/radioboksy)
  boolean checkboxes=false;
  if(currentState.getFactSlot("answerType").toString().equals("checkBox"))
  {
   checkboxes=true;
  }

  answerPanel.removeAll();
  answerButtons=!checkboxes ? new ButtonGroup(): null;

  MultifieldValue answersMultifieldValue=(MultifieldValue)currentState.getFactSlot("answers");
  List<PrimitiveValue> answersList=answersMultifieldValue.listValue();

  for(PrimitiveValue answer : answersList)
  {
   JToggleButton button;
   if(checkboxes)
   {
    button=new JCheckBox(properties.getProperty(answer.toString()).toString(), false);
   }
   else
   {
    button=new JRadioButton(properties.getProperty(answer.toString()).toString(), false);
   }

   // zaznaczanie domyslnie aktywnych przyciskow
   MultifieldValue selectedMultifieldValue=(MultifieldValue)currentState.getFactSlot("selected");
   List<PrimitiveValue> selectedList=selectedMultifieldValue.listValue();
   for(PrimitiveValue selected : selectedList)
   {
    if(answer.toString().equals(selected.toString()))
    {
     button.setSelected(true);
     break;
    }
   }

   button.setActionCommand(answer.toString());
   answerPanel.add(button);

   if(!checkboxes)
   {
    answerButtons.add(button);
   }
  }

  answerPanel.repaint();
 }

 @Override
 public void actionPerformed(ActionEvent event)
 {
  // po kliknieciu przycisku "next" dodawane sa fakty do CLIPS-a
  if(event.getActionCommand().equals("next"))
  {
   for(Component component : answerPanel.getComponents())
   {
    if(component instanceof JToggleButton)
    {
     JToggleButton button=(JToggleButton)component;
     if(button.isSelected())
     {
      String toAssert="(" + assertedKosiarka + " " + button.getActionCommand()+ ")";
      clips.assertString(toAssert);
      System.out.println(toAssert);
     }
    }
   }

   clips.run(1);
   nextUIState();
   return;
  }

  // po kliknieciu przycisku "start"
  if(event.getActionCommand().equals("start"))
  {
   clips.assertString("(start)");
   System.out.println("(start)");

   clips.run(1);
   nextUIState();
   return;
  }

  // po kliknieciu przycisku "restart" resetujemy srodowisko CLIPS-a
  if(event.getActionCommand().equals("restart"))
  {
   clips.reset();
   System.out.println("clips.reset");

   clips.run(1);
   nextUIState();
   return;
  }
 }

 private void loadProperties(File propertiesFile)
 {
  InputStream is;
  try
  {
   is=new FileInputStream(propertiesFile);
   properties.load(is);
  }
  catch(FileNotFoundException e)
  {
   System.out.println("Cannot find configuration file.");
  }
  catch(IOException e)
  {
   System.out.println("Some problems with configuration file.");
  }
 }

 public static void main(String[] args)
 {
  SwingUtilities.invokeLater(
   new Runnable()
   {
    public void run()
    {
     new Kosiarki();
    }
   }
  );
 }

}

class Result
{
 private String producent;
 private String typ;
 private String rodzaj;
 private String cena;

 public String getProducent()
 {
  return producent;
 }

 public void setProducent(String producent)
 {
  this.producent=producent;
 }

 public String getTyp()
 {
  return typ;
 }

 public void setTyp(String typ)
 {
  this.typ=typ;
 }

 public String getRodzaj()
 {
  return rodzaj;
 }

 public void setRodzaj(String rodzaj)
 {
  this.rodzaj=rodzaj;
 }

 public String getCena()
 {
  return cena;
 }

 public void setCena(String cena)
 {
  this.cena=cena;
 }


 public Result()
 {
 }

 public Result(String producent, String typ, String rodzaj, String cena)
 {
  this.producent=producent;
  this.typ=typ;
  this.rodzaj=rodzaj;
  this.cena=cena;
 }

}

class ResultComperator implements Comparator<Result>
{
 public int compare(Result o1, Result o2)
 {
  return o1.getProducent().compareTo(o2.getProducent());
 }

}

它编译得很好,但是当我在命令行上启动它时,我有:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at Kosiarki.nextUIState(Kosiarki.java:199)
        at Kosiarki.<init>(Kosiarki.java:101)
        at Kosiarki$1.run(Kosiarki.java:333)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$200(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

还有更多的例外。我想补充一点,我对java很弱,我写这个是看另一个程序的例子。

我需要这方面的帮助。知识库不是问题,只有这个java文件。

4

3 回答 3

0

非常感谢。我发现了更多错误并修复了它们。现在我的文件如下:

Kosiarki.java:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.List;
import java.util.Properties;

import javax.swing.SwingUtilities;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JCheckBox;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import CLIPSJNI.Environment;
import CLIPSJNI.FactAddressValue;
import CLIPSJNI.MultifieldValue;
import CLIPSJNI.PrimitiveValue;
import CLIPSJNI.SymbolValue;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import java.util.Comparator;
import javax.swing.table.TableColumn;

public class Kosiarki implements ActionListener
{
 private Environment clips;
 private Properties properties;
 private ButtonGroup answerButtons;
 private JTextPane textPane;
 private JButton nextButton;
 private JPanel answerPanel;
 private JTable answersTable;
 private String assertedKosiarka;
 private String lastAssertedKosiarka="";

 public Kosiarki()
 {
  // okno
  JFrame frame=new JFrame("AI Name Project");
  frame.getContentPane().setLayout(new GridLayout(3, 1));
  frame.setSize(500, 300);
  frame.setLocationByPlatform(true);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  // panel - piewszy wiersz tableli 1x3 - do wyswietlania tekstow(glownie pytan)
  JPanel textPanel=new JPanel();
  textPane=new JTextPane();
  textPane.setOpaque(false);
  textPane.setEditable(false);

  StyledDocument doc=textPane.getStyledDocument();
  SimpleAttributeSet center=new SimpleAttributeSet();
  StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
  doc.setParagraphAttributes(0, doc.getLength(), center, false);

  textPanel.add(textPane);

  // panel - drugi wiersz tableli 1x3 - do wyswietlania checkboksow i radiobuttonow
  answerPanel=new JPanel();
  answerButtons=new ButtonGroup();

  // panel - trzeci i ostatni wiersz tableli 1x3 - do wyswietlania przycisku "next"
  JPanel nextButtonPanel=new JPanel();
  nextButton=new JButton();
  nextButton.setActionCommand("next");
  nextButtonPanel.add(nextButton);
  nextButton.addActionListener(this);

  // wstawiamy na okno wszystkie trzy panele
  frame.getContentPane().add(textPanel);
  frame.getContentPane().add(answerPanel);
  frame.getContentPane().add(nextButtonPanel);
  frame.setVisible(true);

  // inicjalizacja CLIPS-a
  clips=new Environment();
  clips.load("control.clp");
  clips.load("knowledgeBase.clp");
  clips.reset();
  clips.run(1);

  // ititializing file with properties
  properties=new Properties();
  loadProperties(new File("configuration.properties"));

  // w praktyce pokazujemy okno wstepne
  nextUIState();
 }

 private void nextUIState()
 {
  answerPanel.removeAll();

  // pobieramy aktualny stan UI
  MultifieldValue currentStateMultifieldValue=(MultifieldValue)clips.eval("(find-all-facts((?f currentState))TRUE)");
  List<FactAddressValue> currentStateList=currentStateMultifieldValue.listValue();
  if(currentStateList.isEmpty())
  {
   return;
  }
  FactAddressValue currentState=currentStateList.get(0);

  // sprawdzamy czy nie "zablokowalismy" sie na "name"
  assertedKosiarka=currentState.getFactSlot("name").toString();
  if(assertedKosiarka.contentEquals(lastAssertedKosiarka))
  {
   clips.run(1);
   nextUIState();
   return;
  }
  lastAssertedKosiarka=assertedKosiarka;

  // ustawienie nazw przycisku "next"/"restart"/"start"
  if(currentState.getFactSlot("state").toString().equals("final"))
  {
   nextButton.setActionCommand("restart");
   nextButton.setText(properties.getProperty("RESTART").toString());

   // Dodatkowo wypisywanie wynikow
   MultifieldValue namesMultifieldValue=(MultifieldValue)clips.eval("(find-all-facts((?f result))TRUE)");
   List<FactAddressValue> nameList=namesMultifieldValue.listValue();

   if(!nameList.isEmpty())
   {
    textPane.setText(properties.getProperty("RESULTS_END_TEXT").toString());
    System.out.println("pasujące kosiarki:");

    String headers[]={
      properties.getProperty("PRODUCENT"),
      properties.getProperty("TYP"),
      properties.getProperty("RODZAJ"),
      properties.getProperty("CENA")};

    ArrayList<Result> resultList=new ArrayList<Result>();
    for(FactAddressValue name : nameList)
    {
     resultList.add(new Result(
       name.getFactSlot("producent").getValue().toString(),
       name.getFactSlot("typ").getValue().toString(),
       name.getFactSlot("rodzaj").getValue().toString(),
       name.getFactSlot("cena1").getValue().toString()));
    }

    Collections.sort(resultList, new ResultComperator());

    String data[][]=new String[nameList.size()][4];
    int i=0;
    for(Result result : resultList)
    {
     data[i][0]=properties.getProperty(result.getProducent());
     data[i][1]=result.getTyp();
     data[i][2]=result.getRodzaj();
     data[i][3]=result.getCena();

     String newKosiarka=data[i][0] + "(" + data[i][1] + ")";
     System.out.println(newKosiarka);

     i++;
    }

    answersTable=new JTable(data, headers);
    answersTable.setPreferredScrollableViewportSize(new Dimension(answerPanel.getWidth()- 25, answerPanel.getHeight()- 25));
    answersTable.getTableHeader().setReorderingAllowed(false);
    answersTable.setEnabled(false);

    TableColumn column=new TableColumn();
    column=answersTable.getColumnModel().getColumn(0);
    column.setMaxWidth(100);

    JScrollPane scrollPane=new JScrollPane(answersTable);

    answerPanel.add(scrollPane);
   }
   else
   {
    textPane.setText(properties.getProperty("NO_RESULTS_END_TEXT").toString());
   }

   answerPanel.repaint();
   return;
  }
  else if(currentState.getFactSlot("state").toString().equals("initial"))
  {
   nextButton.setActionCommand("start");
   nextButton.setText(properties.getProperty("START").toString());
  }
  else
  {
   nextButton.setActionCommand("next");
   nextButton.setText(properties.getProperty("NEXT").toString());
  }

  // ustawienie tekstu(np. pytania)
  String text=((SymbolValue)currentState.getFactSlot("text")).stringValue();
  textPane.setText(properties.getProperty(text).toString());

  // Wstawiamy przyciski(comboboksy/radioboksy)
  boolean checkboxes=false;
  if(currentState.getFactSlot("answerType").toString().equals("checkBox"))
  {
   checkboxes=true;
  }

  answerPanel.removeAll();
  answerButtons=!checkboxes ? new ButtonGroup(): null;

  MultifieldValue answersMultifieldValue=(MultifieldValue)currentState.getFactSlot("answers");
  List<PrimitiveValue> answersList=answersMultifieldValue.listValue();

  for(PrimitiveValue answer : answersList)
  {
   JToggleButton button;
   if(checkboxes)
   {
    button=new JCheckBox(properties.getProperty(answer.toString()).toString(), false);
   }
   else
   {
    button=new JRadioButton(properties.getProperty(answer.toString()).toString(), false);
   }

   // zaznaczanie domyslnie aktywnych przyciskow
   MultifieldValue selectedMultifieldValue=(MultifieldValue)currentState.getFactSlot("selected");
   List<PrimitiveValue> selectedList=selectedMultifieldValue.listValue();
   for(PrimitiveValue selected : selectedList)
   {
    if(answer.toString().equals(selected.toString()))
    {
     button.setSelected(true);
     break;
    }
   }

   button.setActionCommand(answer.toString());
   answerPanel.add(button);

   if(!checkboxes)
   {
    answerButtons.add(button);
   }
  }

  answerPanel.repaint();
 }

 @Override
 public void actionPerformed(ActionEvent event)
 {
  // po kliknieciu przycisku "next" dodawane sa fakty do CLIPS-a
  if(event.getActionCommand().equals("next"))
  {
   for(Component component : answerPanel.getComponents())
   {
    if(component instanceof JToggleButton)
    {
     JToggleButton button=(JToggleButton)component;
     if(button.isSelected())
     {
      String toAssert="(" + assertedKosiarka + " " + button.getActionCommand()+ ")";
      clips.assertString(toAssert);
      System.out.println(toAssert);
     }
    }
   }

   clips.run(1);
   nextUIState();
   return;
  }

  // po kliknieciu przycisku "start"
  if(event.getActionCommand().equals("start"))
  {
   clips.assertString("(start)");
   System.out.println("(start)");

   clips.run(1);
   nextUIState();
   return;
  }

  // po kliknieciu przycisku "restart" resetujemy srodowisko CLIPS-a
  if(event.getActionCommand().equals("restart"))
  {
   clips.reset();
   System.out.println("clips.reset");

   clips.run(1);
   nextUIState();
   return;
  }
 }

 private void loadProperties(File propertiesFile)
 {
  InputStream is;
  try
  {
   is=new FileInputStream(propertiesFile);
   properties.load(is);
  }
  catch(FileNotFoundException e)
  {
   System.out.println("Cannot find configuration file.");
  }
  catch(IOException e)
  {
   System.out.println("Some problems with configuration file.");
  }
 }

 public static void main(String[] args)
 {
  SwingUtilities.invokeLater(
   new Runnable()
   {
    public void run()
    {
     new Kosiarki();
    }
   }
  );
 }

}

class Result
{
 private String producent;
 private String typ;
 private String rodzaj;
 private String cena1;

 public String getProducent()
 {
  return producent;
 }

 public void setProducent(String producent)
 {
  this.producent=producent;
 }

 public String getTyp()
 {
  return typ;
 }

 public void setTyp(String typ)
 {
  this.typ=typ;
 }

 public String getRodzaj()
 {
  return rodzaj;
 }

 public void setRodzaj(String rodzaj)
 {
  this.rodzaj=rodzaj;
 }

 public String getCena()
 {
  return cena1;
 }

 public void setCena(String cena1)
 {
  this.cena1=cena1;
 }


 public Result()
 {
 }

 public Result(String producent, String typ, String rodzaj, String cena1)
 {
  this.producent=producent;
  this.typ=typ;
  this.rodzaj=rodzaj;
  this.cena1=cena1;
 }

}

class ResultComperator implements Comparator<Result>
{
 public int compare(Result o1, Result o2)
 {
  return o1.getProducent().compareTo(o2.getProducent());
 }

}

控制.clp:

(deftemplate currentState
   (slot name (default none))
   (slot state (default middle))
   (slot text)      
   (slot answerType (default radioButton))
   (multislot selected)
   (multislot answers)
)

(deftemplate result
   (slot producent (type STRING))
   (slot typ (type STRING))
   (slot rodzaj (type STRING))
   (slot cena1 (type INTEGER))
)

; Startup window
(defrule system-banner ""
 =>
   (assert (currentState 
      (text START_TEXT)
      (name start)
      (state initial)
      (answers))
   )
)

; Results window
(defrule EndOfQuestions ""
   ?state<-(currentState)
   (end)
 =>
   (retract ?state) 
   (assert (currentState 
      (text NO_RESULTS_END_TEXT)
      (state final)
   ))
)

; Pytanie o powierzchnie
(defrule selectPowierzchnia ""
   ?state<-(currentState)
    (start)
   (not(pytaniePowierzchnia))
   =>
   (retract ?state) 
   (assert (pytaniePowierzchnia))   
   (assert (currentState
      (name powierzchnia)
      (text SELECT_PYTANIE_POWIERZCHNIA)
      (answerType checkBox)
      (answers 10 20 30 40 50 100 200 300 400 500 1000 2000 3000 4000 5000)
      (selected )
   ))
)

; Pytanie o mechanizm tnacy ====== bezsilnikowy ======
(defrule selectMechanizm ""
   ?state<-(currentState)
   (not(pytanieMechanizm))
   (not(powierzchnia ?))
   (naped NOENGINE)
   (naped ELECTRIC)
   =>
   (retract ?state) 
   (assert (pytanieMechanizm))   
   (assert (currentState
      (name mechanizm)
      (text SELECT_PYTANIE_MECHANIZM)
      (answerType checkBox)
      (answers TRADYCYJNY ROTACYJNY ZYLKOWY WRZECIONOWY BIJAKOWY KARCZUJACY LISTWOWY)
      (selected)
   ))
)

; Pytanie o mechanizm tnacy ====== elektryczny ======
(defrule selectMechanizm ""
   ?state<-(currentState)
   (not(pytanieMechanizm))
   (not(powierzchnia ?))
   (naped ELECTRIC)
   (naped ENGINE)
   =>
   (retract ?state) 
   (assert (pytanieMechanizm))   
   (assert (currentState
      (name mechanizm)
      (text SELECT_PYTANIE_MECHANIZM)
      (answerType checkBox)
      (answers TRADYCYJNY ROTACYJNY ZYLKOWY WRZECIONOWY BIJAKOWY KARCZUJACY LISTWOWY)
      (selected)
   ))
)

; Pytanie o mechanizm tnacy ====== spalinowy ======
(defrule selectMechanizm ""
   ?state<-(currentState)
   (not(pytanieMechanizm))
   (not(powierzchnia ?))
   (naped ENGINE)
   =>
   (retract ?state) 
   (assert (pytanieMechanizm))   
   (assert (currentState
      (name mechanizm)
      (text SELECT_PYTANIE_MECHANIZM)
      (answerType checkBox)
      (answers TRADYCYJNY ROTACYJNY ZYLKOWY WRZECIONOWY BIJAKOWY KARCZUJACY LISTWOWY)
      (selected)
   ))
)

; Pytanie o dodatki
(defrule selectDodatki ""
   ?state<-(currentState)
   (not(pytanieDodatki))
   (mechanizm TRADYCYJNY|ROTACYJNY|ZYLKOWY|WRZECIONOWY|BIJAKOWY|KARCZUJACY|LISTWOWY)  ;;;;;
   =>
   (retract ?state) 
   (assert (pytanieDodatki))   
   (assert (currentState
      (name dodatki)
      (text SELECT_PYTANIE_DODATKI)
      (answerType checkBox)
      (answers MULCZOWANIE KOSZ TARCZA ROZRUSZNIK BLOKADA NAPED NIE)
      (selected)
   ))
)

; Pytanie o cene
(defrule selectCena ""
   ?state<-(currentState)
   (not(pytanieCena))
   (dodatki MULCZOWANIE|KOSZ|TARCZA|ROZRUSZNIK|BLOKADA|NAPED|NIE)
   =>
   (retract ?state)
   (assert (PytanieCena))
   (assert (currentState
      (name cena)
      (text SELECT_PYTANIE_CENA)
      (answerType checkBox)
      (answers 10 20 30 40 50 100 200 300 400 500 1000 2000 3000 4000 5000)
      (selected)
   ))
   ;(assert (end))
)

(defrule suma_pow_init
   ?i<-(powierzchnia ?p)
   (not(suma_pow ?))
 =>
   (retract ?i)
   (assert(suma_pow ?p)))

(defrule sumuj_pow
   ?i<-(powierzchnia ?p)
   ?j<-(suma_pow ?s)
 =>
   (retract ?i ?j)
   (assert(suma_pow (+ ?p ?s))))

(defrule nast_pyt_pow1
   (not(powierzchnia ?))
   (suma_pow ?s)
   (test(< ?s 150))
 =>
   (assert(naped NOENGINE))
   (assert(naped ELECTRIC)))

(defrule nast_pyt_pow2
   (not(powierzchnia ?))
   (suma_pow ?s)
   (test(>= ?s 150))
   (test(< ?s 750))
 =>
   (assert(naped ELECTRIC))
   (assert(naped ENGINE)))

(defrule nast_pyt_pow3
   (not(powierzchnia ?))
   (suma_pow ?s)
   (test(> ?s 750))
 =>
   (assert(naped ENGINE)))

(defrule suma_cen_init
   ?i<-(cena ?c)
   (not(suma_cen ?))
 =>
   (retract ?i)
   (assert(suma_cen ?c)))

(defrule sumuj_ceny
   ?i<-(cena ?c)
   ?j<-(suma_cen ?s)
 =>
   (retract ?i ?j)
   (assert(suma_cen (+ ?s ?c))))

(defrule nast_pyt_cena1
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 450))
   (test(< ?s 500))
 =>
   (assert(cena DO_500))
   (assert (end)))

(defrule nast_pyt_cena2
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 500))
   (test(< ?s 750))
 =>
   (assert(cena DO_750))
   (assert (end)))

(defrule nast_pyt_cena3
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 750))
   (test(< ?s 1500))
 =>
   (assert(cena DO_1500))
   (assert (end)))

(defrule nast_pyt_cena4
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 1500))
   (test(< ?s 3000))
 =>
   (assert(cena DO_3000))
   (assert (end)))

(defrule nast_pyt_cena5
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 3000))
   (test(< ?s 5000))
 =>
   (assert(cena DO_5000))
   (assert (end)))

(defrule nast_pyt_cena6
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 5000))
   (test(< ?s 10000))
 =>
   (assert(cena DO_10000))
   (assert (end)))

(defrule nast_pyt_cena7
   (not(cena ?))
   (suma_cen ?s)
   (test(>= ?s 10000))
 =>
   (assert(cena OD_10000))
   (assert (end)))

Knowledgebase.clp 是一样的。

您是否有任何想法强制 CLIPSJNI 在规则 nast_pyt_pow# 和 nast_pyt_cena# 中添加事实 (naped ...) 和 (cena ...) ?

于 2014-01-11T12:38:53.823 回答
0

对不起这个烂摊子。我让它完全工作,但在结果屏幕上它确实显示价格(cenia)。我给你我的项目压缩包:https ://dl.dropboxusercontent.com/u/96736379/projekt2.zip

于 2014-01-11T19:58:24.453 回答
0

堆栈跟踪告诉您此语句是问题所在

nextButton.setText(properties.getProperty("START").toString());

确保Properties文件configuration.properties包含对应的条目START,例如

START=100
于 2014-01-10T14:41:54.533 回答