Package statechum.analysis.learning

Source Code of statechum.analysis.learning.RPNIBlueFringeLearner

/*Copyright (c) 2006, 2007, 2008 Neil Walkinshaw and Kirill Bogdanov
This file is part of StateChum

StateChum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

StateChum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with StateChum.  If not, see <http://www.gnu.org/licenses/>.
*/

package statechum.analysis.learning;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import statechum.Configuration;
import statechum.Pair;
import statechum.analysis.learning.observers.Learner;
import statechum.analysis.learning.rpnicore.LearnerGraph;
import statechum.model.testset.PTASequenceEngine;

import edu.uci.ics.jung.graph.impl.*;

public abstract class RPNIBlueFringeLearner  extends Observable {
  protected int questionCounter = 0;
 
  protected final Configuration config;
 
  /** The frame in relation to which to pop dialog boxes. */
  protected Frame parentFrame;

  public RPNIBlueFringeLearner(Frame parent, Configuration c)
  {
    config = c;
    parentFrame = parent;
  }
 
  /** Retrieves the configuration used by this learner. */
  public Configuration getConfig()
  {
    return config;
  }
 
  /** Initialises this learner. */
  abstract public void init(Collection<List<String>> plus, Collection<List<String>> minus);
  abstract public void init(PTASequenceEngine en, int plus, int minus);

  /** Loads PTA from a supplied file. */
  public void loadPTA(@SuppressWarnings("unused"String name)
  {
    throw new UnsupportedOperationException();
  }
 

  /** Does the learning, returning the result. */
  public abstract DirectedSparseGraph learnMachine();

  protected int counterRestarted = 0;
 
  /** Returns the number of times learner had to restart. */
  public int getRestarts()
  {
    return counterRestarted;
  }
 
  /** Given a score, we need to determine whether to ask questions. This depends on a number
   * of configuration parameters.
   *
   * @param score score we are looking at
   * @return whether any questions should be asked or we could just proceed with merging.
   */
  protected boolean shouldAskQuestions(int score)
  {
    if (!config.getAskQuestions())
      return false;
   
    if (config.getCertaintyThreshold() >= 0 && score > config.getCertaintyThreshold())
      return false;
   
    if (score < config.getMinCertaintyThreshold())
      return false;
   
    return true;
  }
 
  /** Updates listeners only if this object has been modified and debug mode is on, by calling
   * <pre>
   * setChanged()
   * </pre>
   * @param g the graph to display in the associated view
   */
  public void updateGraph(LearnerGraph g)
  {
    setChanged();
    if (config.getDebugMode())
      notifyObservers(g);
  }
 

  final String questionPrefix="<html><font color=green>";
 
  protected List<String> getShortenedQuestion(List<String> question){
    List<String> questionList = new LinkedList<String>();
    assert(question.size()>=1);
    int counter=1;
    Iterator<String> questionIter = question.iterator();
    String lastQuestion = questionIter.next();
   
    while(questionIter.hasNext())
    {
        String current = questionIter.next();
        if(current.equals(lastQuestion))
          counter++;
        else{
          questionList.add(lastQuestion.concat( (counter>1)? "(*"+counter+")":""));// in the string case, I could add "\n" at the end
          counter = 1;lastQuestion = current;         
        }
    }
    questionList.add(lastQuestion.concat( (counter>1)? "(*"+counter+")":""));
    return questionList;
  }

  protected List<String> beautifyQuestionList(List<String> question)
  {
    List<String> questionList = new LinkedList<String>();
    int i=0;
    for(String q:question)
        questionList.add(questionPrefix+"("+i++ +") "+q);
   
    return questionList;
  }
 
  /** The dialog to be displayed to a user with questions to select.
   * This field should not really be public, but since different packages refer to it,
   * I chose to make it public for the time being.
   */
  public JDialog dialog = null;
 
  /** the option pane. */
  protected JOptionPane jop = null
 
  /** Cancels a dialog, if present. With no dialog, learner thread will terminate within a reasonable amount of time.
   */
  public void terminateLearner()
  {
    assert(SwingUtilities.isEventDispatchThread());
    if (dialog != null && jop != null && dialog.isVisible())
      jop.setValue(new Integer(
                    JOptionPane.CLOSED_OPTION));// from http://java.sun.com/docs/books/tutorial/uiswing/components/examples/CustomDialog.java    }
  }
 
  /** Stores recorded answers. */
  protected AbstractOracle ans = null;
 
  /** Makes it possible to answer questions automatically.
   * 
   * @param a the class holding stored answers.
   */
  public void setAnswers(AbstractOracle a)
  {
    ans = a;
  }
 
  public static final int USER_CANCELLED = -2;
  public static final int USER_ACCEPTED = -3;
  public static final int USER_LTL = -4;
  public static final int USER_WAITINGFORSELECTION = -1;
 
  public final static String QUESTION_AUTO = "<auto>";
  public final static String QUESTION_SPIN = "<spin>";
  public final static String QUESTION_USER = "<USER>";
  protected String howAnswerWasObtained = "";
 
  protected Pair<Integer,String> handleAutoAnswer(List<String> question)
  {
    howAnswerWasObtained = QUESTION_USER;
    Pair<Integer,String> AutoAnswer = ans == null? null:ans.getAnswer(question);
    if (AutoAnswer != null)
    {
      howAnswerWasObtained = QUESTION_AUTO;
      return AutoAnswer;
    }
   
    return null;
  }
 
  protected void setAutoOracle()
  {
    if (config.getAutoAnswerFileName().length() > 0)
    {
      ans = new StoredAnswers();
      try {
        ((StoredAnswers)ans).setAnswers(new FileReader(config.getAutoAnswerFileName()));
      } catch (Exception e) {
        ans = null;
      }
    }
  }
 
  protected Pair<Integer,String> checkWithEndUser(LearnerGraph model,List<String> question, final Object [] moreOptions){
    Pair<Integer,String> autoAnswer = handleAutoAnswer(question);if (autoAnswer != null) return autoAnswer;

    final List<String> questionList = beautifyQuestionList(question);
    final AtomicInteger answer = new AtomicInteger(USER_WAITINGFORSELECTION);
    updateGraph(model);
    try {
      SwingUtilities.invokeAndWait(new Runnable() {
        public void run() {
          final Object[] options = new Object[1+moreOptions.length];
          //final JList nonrejectElements = new JList(new String[] { "<html><font color=gray>a","<html><font color=gray>b"});
          final JList rejectElements = new JList(questionList.toArray());
          options[0]="Accept";System.arraycopy(moreOptions, 0, options, 1, moreOptions.length);
          final JLabel label = new JLabel("<html><font color=red>Click on the first non-accepting element below", SwingConstants.CENTER);
          jop = new JOptionPane(new Object[] {label,rejectElements},
                      JOptionPane.QUESTION_MESSAGE,JOptionPane.YES_NO_CANCEL_OPTION,null,options, options[0]);
          dialog = new JDialog(parentFrame,"Valid input string?",false);
          dialog.setContentPane(jop);
         
          // the following chunk is partly from http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html
          dialog.setDefaultCloseOperation(
                WindowConstants.DO_NOTHING_ON_CLOSE);
          dialog.addWindowListener(new WindowAdapter() {
              public void windowClosing(@SuppressWarnings("unused") WindowEvent we) {
                jop.setValue(new Integer(
                                    JOptionPane.CLOSED_OPTION));// from http://java.sun.com/docs/books/tutorial/uiswing/components/examples/CustomDialog.java
              }
          });
          jop.addPropertyChangeListener(new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent e) {
                    String prop = e.getPropertyName();
                   
              Object value = e.getNewValue();

              if (dialog.isVisible() && e.getSource() == jop
                           && (prop.equals(JOptionPane.VALUE_PROPERTY)))
              {
                int i = 0;for(;i < options.length && options[i] != value;++i);
                  if (i == options.length)
                    i = USER_CANCELLED;// nothing was chosen
                  else
                    i = USER_ACCEPTED-i; // to ensure that zero translates into USER_ACCEPTED and other choices into lower numbers
                 
                // one of the choices was made, determine which one and close the window
                answer.getAndSet( i );
                synchronized(answer)
                {
                  answer.notifyAll();
                }

                dialog.setVisible(false);dialog.dispose();
                    }
                }
            });
          rejectElements.addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent e) {
              if (dialog.isVisible() && e.getSource() == rejectElements &&
                  !e.getValueIsAdjusting() && !rejectElements.isSelectionEmpty())
              {
                answer.getAndSet( rejectElements.getLeadSelectionIndex() );
                synchronized(answer)
                {
                  answer.notifyAll();
                }
               
                dialog.setVisible(false);dialog.dispose();
              }
            }
           
          });       
          dialog.pack();
          //rejectElements.setListData(questionList.toArray());
          dialog.setVisible(true);
        }
      });
      synchronized (answer) {
        while(answer.get() == USER_WAITINGFORSELECTION)
            answer.wait();// wait for a user to make a response
      }
    } catch (InvocationTargetException e) {
      e.printStackTrace();
      // if we cannot make a call, return a negative number - nothing do not know what else to do about it.
    }
    catch (InterruptedException e) {
     
      // if we are interrupted, return a negative number - nothing do not know what else to do about it.
    }
    if (answer.get() == USER_WAITINGFORSELECTION) // this one if an exception was thrown
      answer.getAndSet(USER_CANCELLED);
    return new Pair<Integer,String>(answer.get(),null);
  }
 
  public int getQuestionCounter() {
    return questionCounter;
  }

  public void setQuestionCounter(int questionCnt) {
    this.questionCounter = questionCnt;
  }

  protected static void dumpSets(String output, Collection<List<String>> sPlus, Collection<List<String>> sMinus)
  { 
    try
    {
      System.out.println("dumping sets");
      XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(output)));
      encoder.writeObject(sPlus);
      encoder.writeObject(sMinus);
      encoder.close();
      throw new IllegalArgumentException("finished");
    }
    catch(FileNotFoundException e)
    {
      IllegalArgumentException ex = new IllegalArgumentException("failed to write output file");
      ex.initCause(e);throw ex;
    }   
  }
 
  public abstract Learner getLearner();
}
TOP

Related Classes of statechum.analysis.learning.RPNIBlueFringeLearner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.