/*
* JFLAP - Formal Languages and Automata Package
*
*
* Susan H. Rodger
* Computer Science Department
* Duke University
* August 27, 2009
* Copyright (c) 2002-2009
* All rights reserved.
* JFLAP is open source software. Please see the LICENSE for terms.
*
*/
package gui.action;
import grammar.Grammar;
import gui.environment.Environment;
import gui.environment.Universe;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import automata.Automaton;
import automata.AutomatonSimulator;
import automata.Configuration;
/**
* This is the action used for the simulation of input on an automaton with no
* interaction. This method can operate on any automaton. It uses a special
* exception for the case of the multiple tape Turing machine.
*
* @author Thomas Finley
*/
public class NoInteractionSimulateAction extends SimulateAction {
public NoInteractionSimulateAction(Grammar gram,
Environment environment) {
super(gram, environment);
putValue(NAME, "Fast Run...");
putValue(ACCELERATOR_KEY, null);
this.environment = environment;
}
/**
* Instantiates a new NoInteractionSimulateAction
.
*
* @param auto
* the automaton that input will be simulated on
* @param environment
* the environment object that we shall add our simulator pane to
*/
public NoInteractionSimulateAction(Automaton automaton,
Environment environment) {
super(automaton, environment);
putValue(NAME, "Fast Run...");
putValue(ACCELERATOR_KEY, null);
this.environment = environment;
}
/**
* Reports a configuration that accepted.
*
* @param configuration
* the configuration that accepted
* @param component
* the parent component of dialogs brought up
* @return true
if we should continue searching, or false
* if we should halt
*/
protected boolean reportConfiguration(Configuration configuration,
Component component) {
JComponent past = (JComponent) gui.sim.TraceWindow
.getPastPane(configuration);
past.setPreferredSize(new java.awt.Dimension(300, 400));
String[] options = { "Keep looking", "I'm done" };
int result = JOptionPane.showOptionDialog(component, past,
"Accepting configuration found!", JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE, null, options, null);
return result == 0;
}
/**
* Confirms if the user wants to keep searching. This should be called
* periodically to give the user a chance to break out of infinite loops.
*
* @param generated
* the number of configurations generated sofar
* @param component
* the parent component of dialogs brought up
* @return true
if we should continue searching, or false
* if we should halt
*/
protected boolean confirmContinue(int generated, Component component) {
int result = JOptionPane.showConfirmDialog(component, generated
+ " configurations have been generated. "
+ "Should we continue?");
return result == JOptionPane.YES_OPTION;
}
/**
* This will search configurations for an accepting configuration.
*
* @param automaton
* the automaton input is simulated on
* @param simulator
* the automaton simulator for this automaton
* @param configs
* the initial configurations generated
* @param initialInput
* the object that represents the initial input; this is a String
* object in most cases, but may differ for multiple tape turing
* machines
*/
public void handleInteraction(Automaton automaton,
AutomatonSimulator simulator, Configuration[] configs,
Object initialInput) {
JFrame frame = Universe.frameForEnvironment(environment);
// How many configurations have we had?
int numberGenerated = 0;
// When should the next warning be?
int warningGenerated = WARNING_STEP;
// How many have accepted?
int numberAccepted = 0;
while (configs.length > 0) {
numberGenerated += configs.length;
// Make sure we should continue.
if (numberGenerated >= warningGenerated) {
if (!confirmContinue(numberGenerated, frame))
return;
while (numberGenerated >= warningGenerated)
warningGenerated *= 2;
}
// Get the next batch of configurations.
ArrayList next = new ArrayList();
for (int i = 0; i < configs.length; i++) {
if (configs[i].isAccept()) {
numberAccepted++;
if (!reportConfiguration(configs[i], frame))
return;
} else {
next.addAll(simulator.stepConfiguration(configs[i]));
}
}
configs = (Configuration[]) next.toArray(new Configuration[0]);
}
if (numberAccepted == 0) {
JOptionPane.showMessageDialog(frame, "The input was rejected.");
return;
}
JOptionPane.showMessageDialog(frame, numberAccepted + " configuration"
+ (numberAccepted == 1 ? "" : "s")
+ " accepted, and\nother possibilities are exhausted.");
}
/** The environment. */
private Environment environment = null;
/** The steps in warnings. */
protected static final int WARNING_STEP = 500;
}