JDialogAvatarModelChecker.java 52.52 KiB
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
*
* ludovic.apvrille AT enst.fr
*
* This software is a computer program whose purpose is to allow the
* edition of TURTLE analysis, design and deployment diagrams, to
* allow the generation of RT-LOTOS or Java code from this diagram,
* and at last to allow the analysis of formal validation traces
* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
* from INRIA Rhone-Alpes.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
package ui.window;
import avatartranslator.AvatarSpecification;
import avatartranslator.AvatarStateMachineElement;
import avatartranslator.modelchecker.AvatarModelChecker;
import avatartranslator.modelchecker.CounterexampleQueryReport;
import avatartranslator.modelchecker.SafetyProperty;
import avatartranslator.modelchecker.SpecificationActionLoop;
import avatartranslator.modelchecker.SpecificationReachability;
import avatartranslator.modelchecker.SpecificationPropertyPhase;
import myutil.*;
import ui.util.IconManager;
import ui.MainGUI;
import ui.TGComponent;
import ui.avatarbd.AvatarBDSafetyPragma;
import graph.RG;
import graph.AUTGraph;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
/**
* Class JDialogAvatarModelChecker
* Dialog for managing the model checking of avatar specifications
* Creation: 1/06/2016
*
* @author Ludovic APVRILLE
* @version 1.1 1/06/2016
*/
public class JDialogAvatarModelChecker extends javax.swing.JFrame implements ActionListener, Runnable, MasterProcessInterface {
private final static String[] INFOS = {"Not started", "Running", "Stopped by user", "Finished"};
private final static Color[] COLORS = {Color.darkGray, Color.magenta, Color.red, Color.blue};
private final static String[] WORD_BITS = {"32 bits", "16 bits", "8 bits"};
private final static String[] SEARCH_TYPE = {"BFS", "DFS"};
public final static int REACHABILITY_ALL = 1;
public final static int REACHABILITY_SELECTED = 2;
public final static int REACHABILITY_NONE = 3;
public final static int LIVENESS_ALL = 4;
public final static int LIVENESS_SELECTED = 5;
public final static int LIVENESS_NONE = 6;
protected static String graphDir;
protected static boolean graphSelected = false;
protected static String graphDirDot;
protected static boolean graphSelectedDot = false;
protected static boolean ignoreEmptyTransitionsSelected = true;
protected static boolean ignoreConcurrenceBetweenInternalActionsSelected = true;
protected static boolean ignoreInternalStatesSelected = true;
protected static boolean generateDesignSelected = false;
protected static int reachabilitySelected = REACHABILITY_NONE;
protected static int livenessSelected = LIVENESS_NONE;
protected static boolean safetySelected = false;
protected static boolean checkNoDeadSelected = false;
protected static boolean checkReinitSelected = false;
protected static boolean checkActionLoopSelected = false;
protected static boolean limitStatesSelected = false;
protected static boolean generateCountertraceSelected = false;
protected static boolean generateCountertraceAUTSelected = false;
protected static String countertracePath;
protected static String stateLimitValue;
protected static boolean limitTimeSelected = false;
protected static String timeLimitValue;
protected static int wordRepresentationSelected = 1;
protected static int searchTypeSelected = 0;
protected MainGUI mgui;
protected final static int NOT_STARTED = 1;
protected final static int STARTED = 2;
protected final static int STOPPED = 3;
private int mode;
protected final static int NO_GRAPH = 1;
protected final static int GRAPH_OK = 2;
private int graphMode;
private String graphAUT;
private AvatarSpecification spec;
private avatartranslator.modelchecker.AvatarModelChecker amc;
private ModelCheckerMonitor mcm;
private Date startDate, endDate;
private Date previousDate;
private int previousNbOfStates;
//components
protected JTextArea jta;
protected JButton start;
protected JButton stop;
protected JButton close;
protected JButton show;
protected JButton display;
protected JComboBox wordRepresentationBox;
protected JComboBox searchTypeBox;
//protected JRadioButton exe, exeint;
//protected ButtonGroup exegroup;
//protected JLabel gen, comp;
//protected JTextField code1, code2, unitcycle, compiler1, exe1, exe2, exe3, exe2int, loopLimit;
protected JRadioButton noReachability, reachabilityCheckable, reachabilityAllStates;
protected ButtonGroup reachabilities;
protected JRadioButton noLiveness, livenessCheckable, livenessAllStates;
protected ButtonGroup liveness;
protected boolean showLiveness;
protected JCheckBox stateLimit;
protected JTextField stateLimitField;
protected JCheckBox timeLimit;
protected JTextField timeLimitField;
protected JCheckBox noDeadlocks;
protected JCheckBox reinit;
protected JCheckBox actionLoop;
protected JCheckBox safety;
protected JCheckBox countertrace;
protected JCheckBox countertraceAUT;
protected JTextField countertraceField;
protected JButton checkUncheckAllPragmas;
protected java.util.List<JCheckBox> customChecks;
protected JCheckBox saveGraphAUT, saveGraphDot, ignoreEmptyTransitions, ignoreInternalStates,
ignoreConcurrenceBetweenInternalActions, generateDesign;
protected JTextField graphPath, graphPathDot;
protected JTabbedPane jp1;
protected JScrollPane jsp;
// Information
protected JLabel nbOfStates, nbOfLinks, nbOfPendingStates, elapsedTime, nbOfStatesPerSecond, nbOfDeadlocks, nbOfReachabilities, nbOfReachabilitiesNotFound, info;
private Thread t;
private boolean go = false;
// private boolean hasError = false;
private java.util.Timer timer;
//protected boolean startProcess = false;
protected Map<String, Integer> verifMap;
/*
* Creates new form
*/
public JDialogAvatarModelChecker(Frame f, MainGUI _mgui, String title, AvatarSpecification _spec, String _graphDir, boolean _showLiveness) {
super(title);
mgui = _mgui;
spec = _spec;
if (graphDir == null) {
graphDir = _graphDir + File.separator + "rgavatar$.aut";
}
if (graphDirDot == null) {
graphDirDot = _graphDir + File.separator + "rgavatar$.dot";
}
countertracePath = "trace$.txt";
stateLimitValue = "100";
timeLimitValue = "5000";
//showLiveness = _showLiveness;
showLiveness = true;
customChecks = new LinkedList<JCheckBox>();
initComponents();
myInitComponents();
pack();
verifMap = new HashMap<String, Integer>();
/*if ((mgui != null) && (spec != null)) {
mgui.drawAvatarSpecification(spec);
}*/
//getGlassPane().addMouseListener( new MouseAdapter() {});
getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
protected void myInitComponents() {
mode = NOT_STARTED;
graphMode = NO_GRAPH;
setButtons();
}
@SuppressWarnings("unchecked")
protected void initComponents() {
Container c = getContentPane();
setFont(new Font("Helvetica", Font.PLAIN, 14));
c.setLayout(new BorderLayout());
//setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Issue #41 Ordering of tabbed panes
jp1 = GraphicLib.createTabbedPane();//new JTabbedPane();
JPanel jpopt = new JPanel();
GridBagLayout gridbagopt = new GridBagLayout();
GridBagConstraints copt = new GridBagConstraints();
jpopt.setLayout(gridbagopt);
jpopt.setBorder(new javax.swing.border.TitledBorder("Options"));
copt.gridwidth = 1;
copt.gridheight = 1;
copt.weighty = 1.0;
copt.weightx = 1.0;
copt.fill = GridBagConstraints.HORIZONTAL;
copt.gridwidth = GridBagConstraints.REMAINDER; //end row
JPanel jp01 = new JPanel();
GridBagLayout gridbag01 = new GridBagLayout();
GridBagConstraints c01 = new GridBagConstraints();
jp01.setLayout(gridbag01);
jp01.setBorder(new javax.swing.border.TitledBorder("Graph generation options"));
c01.gridwidth = 1;
c01.gridheight = 1;
c01.weighty = 1.0;
c01.weightx = 1.0;
c01.fill = GridBagConstraints.HORIZONTAL;
c01.gridwidth = GridBagConstraints.REMAINDER; //end row
if (TraceManager.devPolicy == TraceManager.TO_CONSOLE) {
generateDesign = new JCheckBox("[For testing purpose only] Generate Design", generateDesignSelected);
generateDesign.addActionListener(this);
jp01.add(generateDesign, c01);
}
c01.gridwidth = 1;
ignoreEmptyTransitions = new JCheckBox("Do not display empty transitions as internal actions", ignoreEmptyTransitionsSelected);
ignoreEmptyTransitions.addActionListener(this);
jp01.add(ignoreEmptyTransitions, c01);
c01.anchor = GridBagConstraints.EAST;
c01.fill = GridBagConstraints.NONE;
jp01.add(new JLabel("Search type: "), c01);
c01.anchor = GridBagConstraints.WEST;
c01.fill = GridBagConstraints.HORIZONTAL;
searchTypeBox = new JComboBox(SEARCH_TYPE);
searchTypeBox.setSelectedIndex(searchTypeSelected);
searchTypeBox.addActionListener(this);
jp01.add(searchTypeBox, c01);
c01.anchor = GridBagConstraints.EAST;
c01.fill = GridBagConstraints.NONE;
jp01.add(new JLabel("Word size: "), c01);
c01.gridwidth = GridBagConstraints.REMAINDER; //end row
c01.anchor = GridBagConstraints.WEST;
c01.fill = GridBagConstraints.HORIZONTAL;
wordRepresentationBox = new JComboBox(WORD_BITS);
wordRepresentationBox.setSelectedIndex(wordRepresentationSelected);
wordRepresentationBox.addActionListener(this);
jp01.add(wordRepresentationBox, c01);
ignoreConcurrenceBetweenInternalActions = new JCheckBox("Ignore concurrency between internal actions", ignoreConcurrenceBetweenInternalActionsSelected);
ignoreConcurrenceBetweenInternalActions.addActionListener(this);
jp01.add(ignoreConcurrenceBetweenInternalActions, c01);
ignoreInternalStates = new JCheckBox("Ignore states between internal actions", ignoreInternalStatesSelected);
ignoreInternalStates.addActionListener(this);
jp01.add(ignoreInternalStates, c01);
//Limitations
c01.gridwidth = 1;
stateLimit = new JCheckBox("Limit number of states in RG:", limitStatesSelected);
stateLimit.addActionListener(this);
jp01.add(stateLimit, c01);
c01.gridwidth = GridBagConstraints.REMAINDER;
stateLimitField = new JTextField(stateLimitValue);
jp01.add(stateLimitField, c01);
c01.gridwidth = 1;
timeLimit = new JCheckBox("Time constraint for RG generation (ms):", limitTimeSelected);
timeLimit.addActionListener(this);
jp01.add(timeLimit, c01);
c01.gridwidth = GridBagConstraints.REMAINDER;
timeLimitField = new JTextField(timeLimitValue);
jp01.add(timeLimitField, c01);
JPanel jpbasic = new JPanel();
GridBagLayout gridbagbasic = new GridBagLayout();
GridBagConstraints cbasic = new GridBagConstraints();
jpbasic.setLayout(gridbagbasic);
jpbasic.setBorder(new javax.swing.border.TitledBorder("Basic properties"));
cbasic.gridwidth = 1;
cbasic.gridheight = 1;
cbasic.weighty = 1.0;
cbasic.weightx = 1.0;
cbasic.fill = GridBagConstraints.HORIZONTAL;
cbasic.gridwidth = GridBagConstraints.REMAINDER; //end row
// Deadlocks
cbasic.gridwidth = 1;
noDeadlocks = new JCheckBox("No deadlocks?", checkNoDeadSelected);
noDeadlocks.addActionListener(this);
jpbasic.add(noDeadlocks, cbasic);
// Reinit
reinit = new JCheckBox("Reinitialization?", checkReinitSelected);
reinit.addActionListener(this);
jpbasic.add(reinit, cbasic);
// Internal action loop
cbasic.gridwidth = GridBagConstraints.REMAINDER;
actionLoop = new JCheckBox("No internal action loops?", checkActionLoopSelected);
actionLoop.addActionListener(this);
jpbasic.add(actionLoop, cbasic);
// Reachability
cbasic.gridwidth = 1;
jpbasic.add(new JLabel("Reachability:"), cbasic);
reachabilities = new ButtonGroup();
noReachability = new JRadioButton("None");
noReachability.addActionListener(this);
jpbasic.add(noReachability, cbasic);
reachabilities.add(noReachability);
reachabilityCheckable = new JRadioButton("Selected states");
reachabilityCheckable.addActionListener(this);
jpbasic.add(reachabilityCheckable, cbasic);
reachabilities.add(reachabilityCheckable);
cbasic.gridwidth = GridBagConstraints.REMAINDER;
reachabilityAllStates = new JRadioButton("All states");
reachabilityAllStates.addActionListener(this);
jpbasic.add(reachabilityAllStates, cbasic);
reachabilities.add(reachabilityAllStates);
noReachability.setSelected(reachabilitySelected == REACHABILITY_NONE);
reachabilityCheckable.setSelected(reachabilitySelected == REACHABILITY_SELECTED);
reachabilityAllStates.setSelected(reachabilitySelected == REACHABILITY_ALL);
// Liveness
cbasic.gridwidth = 1;
jpbasic.add(new JLabel("Liveness:"), cbasic);
liveness = new ButtonGroup();
noLiveness = new JRadioButton("None");
noLiveness.addActionListener(this);
if (showLiveness) {
jpbasic.add(noLiveness, cbasic);
}
liveness.add(noLiveness);
livenessCheckable = new JRadioButton("Selected states");
livenessCheckable.addActionListener(this);
if (showLiveness) {
jpbasic.add(livenessCheckable, cbasic);
}
liveness.add(livenessCheckable);
cbasic.gridwidth = GridBagConstraints.REMAINDER;
livenessAllStates = new JRadioButton("All states");
livenessAllStates.addActionListener(this);
if (showLiveness) {
jpbasic.add(livenessAllStates, cbasic);
}
liveness.add(livenessAllStates);
noLiveness.setSelected(livenessSelected == LIVENESS_NONE);
livenessCheckable.setSelected(livenessSelected == LIVENESS_SELECTED);
livenessAllStates.setSelected(livenessSelected == LIVENESS_ALL);
JPanel jpadvanced = new JPanel();
GridBagLayout gridbagadvanced = new GridBagLayout();
GridBagConstraints cadvanced = new GridBagConstraints();
jpadvanced.setLayout(gridbagadvanced);
jpadvanced.setBorder(new javax.swing.border.TitledBorder("Advanced properties"));
cadvanced.anchor = GridBagConstraints.WEST;
cadvanced.gridwidth = 1;
cadvanced.gridheight = 1;
cadvanced.weighty = 1.0;
cadvanced.weightx = 1.0;
cadvanced.fill = GridBagConstraints.HORIZONTAL;
cadvanced.gridwidth = GridBagConstraints.REMAINDER; //end row
//Safety pragmas
cadvanced.gridwidth = 1;
safety = new JCheckBox("Safety pragmas", safetySelected);
safety.addActionListener(this);
jpadvanced.add(safety, cadvanced);
cadvanced.gridwidth = GridBagConstraints.REMAINDER;
checkUncheckAllPragmas = new JButton("Check / uncheck all");
checkUncheckAllPragmas.addActionListener(this);
if (spec.getSafetyPragmas() == null || spec.getSafetyPragmas().isEmpty()) {
safety.setEnabled(false);
safety.setSelected(false);
//checkUncheckAllPragmas.setEnabled(false);
} else {
cadvanced.anchor = GridBagConstraints.EAST;
cadvanced.fill = GridBagConstraints.NONE;
cadvanced.gridwidth = GridBagConstraints.REMAINDER; //end row
jpadvanced.add(checkUncheckAllPragmas, cadvanced);
cadvanced.gridwidth = GridBagConstraints.REMAINDER;
JPanel jpadvancedQ = new JPanel();
GridBagConstraints cadvancedQ = new GridBagConstraints();
GridBagLayout gridbagadvancedQ = new GridBagLayout();
cadvancedQ.anchor = GridBagConstraints.WEST;
cadvancedQ.gridheight = 1;
cadvancedQ.weighty = 1.0;
cadvancedQ.weightx = 1.0;
jpadvancedQ.setLayout(gridbagadvancedQ);
cadvancedQ.fill = GridBagConstraints.BOTH;
for (String s : spec.getSafetyPragmas()) {
cadvancedQ.gridwidth = GridBagConstraints.RELATIVE;
JLabel space = new JLabel(" ");
cadvancedQ.weightx = 0.0;
jpadvancedQ.add(space, cadvancedQ);
cadvancedQ.gridwidth = GridBagConstraints.REMAINDER; //end row
JCheckBox cqb = new JCheckBox(s);
cqb.addActionListener(this);
cadvancedQ.weightx = 1.0;
cqb.setSelected(true);
jpadvancedQ.add(cqb, cadvancedQ);
customChecks.add(cqb);
}
JScrollPane jsp = new JScrollPane(jpadvancedQ, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jsp.setPreferredSize(new Dimension(500, 120));
cadvanced.gridheight = 10;
cadvanced.anchor = GridBagConstraints.WEST;
cadvanced.fill = GridBagConstraints.HORIZONTAL;
cadvanced.gridwidth = GridBagConstraints.REMAINDER; //end row
jpadvanced.add(jsp, cadvanced);
}
cadvanced.gridwidth = GridBagConstraints.REMAINDER;
//Countertrace
cadvanced.gridwidth = 1;
countertraceAUT = new JCheckBox("Generate property AUT graph trace", generateCountertraceAUTSelected);
countertraceAUT.addActionListener(this);
jpadvanced.add(countertraceAUT, cadvanced);
countertrace = new JCheckBox("Generate property text trace", generateCountertraceSelected);
countertrace.addActionListener(this);
jpadvanced.add(countertrace, cadvanced);
cadvanced.gridwidth = GridBagConstraints.REMAINDER;
countertraceField = new JTextField(countertracePath);
jpadvanced.add(countertraceField, cadvanced);
jpopt.add(jp01, c01);
jpopt.add(jpbasic, cbasic);
jpopt.add(jpadvanced, cadvanced);
// RG
saveGraphAUT = new JCheckBox("Reachability Graph Generation", graphSelected);
saveGraphAUT.addActionListener(this);
//saveGraphAUT.addSelectionListener(this);
jpopt.add(saveGraphAUT, copt);
graphPath = new JTextField(graphDir);
jpopt.add(graphPath, copt);
saveGraphDot = new JCheckBox("Save RG in dotty:", graphSelectedDot);
saveGraphDot.addActionListener(this);
//saveGraphDot.setEnebaled(false);
jpopt.add(saveGraphDot, copt);
graphPathDot = new JTextField(graphDirDot);
jpopt.add(graphPathDot, copt);
c.add(jpopt, BorderLayout.NORTH);
jta = new ScrolledJTextArea();
jta.setEditable(false);
jta.setMargin(new Insets(10, 10, 10, 10));
jta.setTabSize(3);
jta.append("Select options and then, click on 'start' to start the model checker\n");
Font f = new Font("Courrier", Font.BOLD, 12);
jta.setFont(f);
jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
c.add(jsp, BorderLayout.CENTER);
start = new JButton("Start", IconManager.imgic53);
stop = new JButton("Stop", IconManager.imgic55);
close = new JButton("Close", IconManager.imgic27);
show = new JButton("RG analysis", IconManager.imgic28);
display = new JButton("Show", IconManager.imgic28);
start.setPreferredSize(new Dimension(100, 30));
stop.setPreferredSize(new Dimension(100, 30));
close.setPreferredSize(new Dimension(120, 30));
show.setPreferredSize(new Dimension(150, 30));
display.setPreferredSize(new Dimension(100, 30));
start.addActionListener(this);
stop.addActionListener(this);
close.addActionListener(this);
show.addActionListener(this);
display.addActionListener(this);
// Information
JPanel jplow = new JPanel(new BorderLayout());
JPanel jpinfo = new JPanel();
GridBagLayout gridbag02 = new GridBagLayout();
GridBagConstraints c02 = new GridBagConstraints();
jpinfo.setLayout(gridbag02);
jpinfo.setBorder(new javax.swing.border.TitledBorder("Graph information"));
jplow.add(jpinfo, BorderLayout.NORTH);
c02.gridheight = 1;
c02.weighty = 1.0;
c02.weightx = 1.0;
c02.fill = GridBagConstraints.HORIZONTAL;
//c02.gridwidth = 1;
//jpinfo.add(new JLabel(""), c02);
c02.gridwidth = GridBagConstraints.REMAINDER; //end row
info = new JLabel();
info.setFont(new Font("Serif", Font.BOLD, 16));
updateInfo();
jpinfo.add(info, c02);
jpinfo.add(new JLabel(" "), c02);
// nb of states, nb of links, nb of pending states, elapsed time, nbOfStatesPerSeconds
c02.gridwidth = 1;
jpinfo.add(new JLabel("Nb of states:"), c02);
//c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfStates = new JLabel("-");
jpinfo.add(nbOfStates, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Nb of transitions:"), c02);
c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfLinks = new JLabel("-");
jpinfo.add(nbOfLinks, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Reachability found:"), c02);
//c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfReachabilities = new JLabel("-");
jpinfo.add(nbOfReachabilities, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Reachability not found:"), c02);
c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfReachabilitiesNotFound = new JLabel("-");
jpinfo.add(nbOfReachabilitiesNotFound, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Nb of deadlock states:"), c02);
c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfDeadlocks = new JLabel("-");
jpinfo.add(nbOfDeadlocks, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Nb of pending states:"), c02);
//c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfPendingStates = new JLabel("-");
jpinfo.add(nbOfPendingStates, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Nb of states/seconds:"), c02);
c02.gridwidth = GridBagConstraints.REMAINDER; //end row
nbOfStatesPerSecond = new JLabel("-");
jpinfo.add(nbOfStatesPerSecond, c02);
c02.gridwidth = 1;
jpinfo.add(new JLabel("Elapsed timed:"), c02);
c02.gridwidth = GridBagConstraints.REMAINDER; //end row
elapsedTime = new JLabel("-");
jpinfo.add(elapsedTime, c02);
JPanel jp2 = new JPanel();
jp2.add(start);
jp2.add(stop);
jp2.add(close);
jp2.add(show);
jp2.add(display);
jplow.add(jp2, BorderLayout.SOUTH);
c.add(jplow, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent evt) {
String command = evt.getActionCommand();
if (command.equals("Start")) {
startProcess();
} else if (command.equals("Stop")) {
stopProcess();
} else if (command.equals("Close")) {
closeDialog();
} else if (evt.getSource() == checkUncheckAllPragmas) {
checkUncheckAllPragmas();
} else if (evt.getSource() == show) {
showGraph();
} else if (evt.getSource() == display) {
displayGraph();
} else if (evt.getSource() == saveGraphAUT) {
setButtons();
} else if (evt.getSource() == saveGraphDot) {
setButtons();
} else if (evt.getSource() == ignoreEmptyTransitions) {
setButtons();
} else if (evt.getSource() == ignoreConcurrenceBetweenInternalActions) {
setButtons();
} else if (evt.getSource() == ignoreInternalStates) {
setButtons();
} else {
setButtons();
}
}
public void closeDialog() {
if (mode == STARTED) {
stopProcess();
}
dispose();
if (timer != null) {
timer.cancel();
timer.purge();
}
}
public void showGraph() {
if (graphAUT != null) {
mgui.showAUTFromString("Last RG", graphAUT);
}
}
public void displayGraph() {
// Make this in a different thread
// And authorize the show only for a small nb of states ...
if (graphAUT != null) {
AUTGraph rg = new AUTGraph();
rg.buildGraph(graphAUT);
rg.display();
}
}
public synchronized void stopProcess() {
if (amc != null) {
amc.stopModelChecking();
}
mode = STOPPED;
setButtons();
go = false;
if (timer != null) {
timer.cancel();
timer.purge();
}
updateValues();
}
public synchronized void startProcess() {
if (mode == STARTED) {
return;
}
t = new Thread(this);
mode = STARTED;
graphMode = NO_GRAPH;
setButtons();
go = true;
t.start();
}
private void testGo() throws InterruptedException {
if (go == false) {
TraceManager.addDev("Interrupted by user");
throw new InterruptedException("Stopped by user");
}
}
public void run() {
// String cmd;
// String list, data;
// int cycle = 0;
// hasError = false;
TraceManager.addDev("Model checker started");
long timeBeg = System.currentTimeMillis();
// File testFile;
try {
reinitValues();
jta.append("Starting the model checker\n");
amc = new AvatarModelChecker(spec);
if (generateDesignSelected) {
TraceManager.addDev("Drawing non modified avatar spec");
if ((mgui != null) && (spec != null)) {
mgui.drawAvatarSpecification(amc.getInitialSpec());
}
}
endDate = null;
previousNbOfStates = 0;
startDate = new Date();
mcm = new ModelCheckerMonitor(this);
timer = new java.util.Timer(true);
timer.scheduleAtFixedRate(mcm, 0, 500);
// Setting options
amc.setCompressionFactor(wordRepresentationSelected << 1);
amc.setSearchType(searchTypeSelected);
amc.setIgnoreEmptyTransitions(ignoreEmptyTransitionsSelected);
amc.setIgnoreConcurrenceBetweenInternalActions(ignoreConcurrenceBetweenInternalActionsSelected);
amc.setIgnoreInternalStates(ignoreInternalStatesSelected);
amc.setCheckNoDeadlocks(checkNoDeadSelected);
amc.setReinitAnalysis(checkReinitSelected);
amc.setInternalActionLoopAnalysis(checkActionLoopSelected);
amc.setCounterExampleTrace(generateCountertraceSelected, generateCountertraceAUTSelected);
// Reachability
int res;
if (reachabilitySelected == REACHABILITY_SELECTED) {
mgui.resetReachability();
res = amc.setReachabilityOfSelected();
jta.append("Reachability of " + res + " selected elements activated\n");
for (SpecificationReachability sr : amc.getReachabilities()) {
handleReachability(sr.ref1, sr.result);
if (sr.ref2 != sr.ref1) {
handleReachability(sr.ref2, sr.result);
}
}
}
if (reachabilitySelected == REACHABILITY_ALL) {
mgui.resetReachability();
res = amc.setReachabilityOfAllStates();
jta.append("Reachability of " + res + " states activated\n");
for (SpecificationReachability sr : amc.getReachabilities()) {
handleReachability(sr.ref1, sr.result);
if (sr.ref2 != sr.ref1) {
handleReachability(sr.ref2, sr.result);
}
}
}
// RG?
if (graphSelected || graphSelectedDot) {
amc.setComputeRG(true);
jta.append("Computation of Reachability Graph activated\n");
}
if (livenessSelected == LIVENESS_SELECTED) {
mgui.resetLiveness();
res = amc.setLivenessOfSelected();
jta.append("Liveness of " + res + " states activated\n");
for (SafetyProperty sp : amc.getLivenesses()) {
handleLiveness(sp.getState(), sp.getPhase());
}
}
if (livenessSelected == LIVENESS_ALL) {
mgui.resetLiveness();
res = amc.setLivenessOfAllStates();
jta.append("Liveness of " + res + " selected elements activated\n");
for (SafetyProperty sp : amc.getLivenesses()) {
handleLiveness(sp.getState(), sp.getPhase());
}
}
if (safetySelected) {
//res = amc.setSafetyAnalysis();
res = 0;
for(JCheckBox cc: customChecks) {
if (cc.isSelected()) {
if (amc.addSafety(cc.getText())) {
res++;
}
}
}
jta.append("Analysis of " + res + " safety pragmas activated\n");
handleSafety(amc.getSafeties());
}
// Limitations
if (stateLimit.isSelected()) {
amc.setStateLimit(true);
try{
Long stateLimitLong = Long.parseLong(stateLimitField.getText());
if (stateLimitLong <= 0) {
jta.append("State Limit field is not valid, insert a positive number\n");
go = false;
}
amc.setStateLimitValue(stateLimitLong.longValue());
} catch (NumberFormatException e) {
jta.append("State Limit field is not valid\n");
go = false;
}
}
if (timeLimit.isSelected()) {
amc.setTimeLimit(true);
try{
Long timeLimitLong = Long.parseLong(timeLimitField.getText());
if (timeLimitLong <= 0) {
jta.append("State Limit field is not valid, insert a positive number\n");
go = false;
}
amc.setTimeLimitValue(timeLimitLong.longValue());
} catch (NumberFormatException e) {
jta.append("Time Limit field is not valid\n");
go = false;
}
}
// Starting model checking
testGo();
if (livenessSelected == LIVENESS_NONE && safetySelected == false && checkNoDeadSelected == false && checkActionLoopSelected == false) {
amc.startModelChecking();
} else {
amc.startModelCheckingProperties();
}
TraceManager.addDev("Model checking done");
//TraceManager.addDev("RG:" + amc.statesToString() + "\n\n");
/*if (generateDesignSelected) {
TraceManager.addDev("Drawing modified avatar spec");
AvatarSpecification reworkedSpec = amc.getReworkedAvatarSpecification();
if ((mgui != null) && (reworkedSpec != null)) {
mgui.drawAvatarSpecification(reworkedSpec);
}
}*/
timer.cancel();
endDate = new Date();
updateValues();
jta.append("\n\nModel checking done\n");
jta.append("Nb of states:" + amc.getNbOfStates() + "\n");
jta.append("Nb of links:" + amc.getNbOfLinks() + "\n");
if (checkNoDeadSelected) {
jta.append("\nNo deadlocks?\n" + "-> " + amc.deadlockToString() + "\n");
}
if (checkReinitSelected) {
jta.append("\nReinitialization?\n" + "-> " + amc.reinitToString() + "\n");
}
if (checkActionLoopSelected) {
boolean result = amc.getInternalActionLoopsResult();
String s;
if (result) {
s = "property is satisfied";
} else {
s = "property is NOT satisfied";
}
jta.append("\nNo internal action loops?\n" + "-> " + s + "\n");
if (!result) {
ArrayList<SpecificationActionLoop> al = amc.getInternalActionLoops();
jta.append("Internal action loops:\n");
for (SpecificationActionLoop sal : al) {
if (sal.getResult()) {
jta.append(sal.toString());
}
}
jta.append("\n");
}
}
if ((reachabilitySelected == REACHABILITY_SELECTED) || (reachabilitySelected == REACHABILITY_ALL)) {
jta.append("\nReachabilities found:\n");
jta.append(amc.reachabilityToString());
// Back annotation on diagrams
for (SpecificationReachability sr : amc.getReachabilities()) {
//TraceManager.addDev("Handing reachability of " + sr);
handleReachability(sr.ref1, sr.result);
if (sr.ref2 != sr.ref1) {
handleReachability(sr.ref2, sr.result);
}
}
}
if (livenessSelected != LIVENESS_NONE) {
jta.append("\nLiveness Analysis:\n");
jta.append(amc.livenessToString());
for (SafetyProperty sp : amc.getLivenesses()) {
handleLiveness(sp.getState(), sp.getPhase());
}
}
if (safetySelected) {
jta.append("\nSafety Analysis:\n");
jta.append(amc.safetyToString());
handleSafety(amc.getSafeties());
}
//TraceManager.addDev(amc.toString());
//TraceManager.addDev(amc.toString());
DateFormat dateFormat = new SimpleDateFormat("_yyyyMMdd_HHmmss");
Date date = new Date();
String dateAndTime = dateFormat.format(date);
if (generateCountertraceSelected || generateCountertraceAUTSelected) {
String file;
if (countertraceField.getText().indexOf("$") != -1) {
file = Conversion.replaceAllChar(countertraceField.getText(), '$', dateAndTime);
} else {
file = countertraceField.getText();
}
if (generateCountertraceSelected) {
String trace = amc.getCounterTrace();
try {
File f = new File(file);
FileUtils.saveFile(file, trace);
jta.append("\nCounterexample trace saved in " + file + "\n");
} catch (Exception e) {
jta.append("\nCounterexample trace could not be saved in " + file + "\n");
}
}
if (generateCountertraceAUTSelected) {
List<CounterexampleQueryReport> autTraces = amc.getAUTTraces();
if (autTraces != null) {
int i = 0;
String autfile = FileUtils.removeFileExtension(file);
for (CounterexampleQueryReport tr : autTraces) {
String filename = autfile + "_" + i + ".aut";
try {
RG rg = new RG(file);
rg.data = tr.getReport();
rg.fileName = filename;
rg.nbOfStates = tr.getNbOfStates();
rg.nbOfTransitions = tr.getNbOfTransitions();
rg.name = tr.getQuery() + "_" + dateAndTime;
mgui.addRG(rg);
File f = new File(filename);
FileUtils.saveFile(filename, tr.getReport());
jta.append("Counterexample graph trace " + tr.getQuery() + " saved in " + filename + "\n");
} catch (Exception e) {
jta.append("Counterexample graph trace "+ tr.getQuery() + " could not be saved in " + filename + "\n");
}
i++;
}
}
}
}
long timeEnd = System.currentTimeMillis();
TraceManager.addDev("Overall time: " + (timeEnd - timeBeg) + " ms");
if (saveGraphAUT.isSelected()) {
graphAUT = amc.toAUT();
graphMode = GRAPH_OK;
//TraceManager.addDev("graph AUT=\n" + graph);
String autfile;
if (graphPath.getText().indexOf("$") != -1) {
autfile = Conversion.replaceAllChar(graphPath.getText(), '$', dateAndTime);
} else {
autfile = graphPath.getText();
}
try {
RG rg = new RG(autfile);
rg.data = graphAUT;
rg.fileName = autfile;
rg.nbOfStates = amc.getNbOfStates();
rg.nbOfTransitions = amc.getNbOfLinks();
File f = new File(autfile);
rg.name = f.getName();
mgui.addRG(rg);
FileUtils.saveFile(autfile, graphAUT);
jta.append("\nGraph saved in " + autfile + "\n");
} catch (Exception e) {
jta.append("\nGraph could not be saved in " + autfile + "\n");
}
}
if (saveGraphDot.isSelected()) {
String dotfile;
if (graphPathDot.getText().indexOf("$") != -1) {
dotfile = Conversion.replaceAllChar(graphPathDot.getText(), '$', dateAndTime);
} else {
dotfile = graphPathDot.getText();
}
try {
String graph = amc.toDOT();
//TraceManager.addDev("graph AUT=\n" + graph);
FileUtils.saveFile(dotfile, graph);
jta.append("\nGraph saved in " + dotfile + "\n");
} catch (Exception e) {
jta.append("\nGraph could not be saved in " + dotfile + "\n");
}
}
} catch (InterruptedException ie) {
jta.append("Interrupted\n");
}
amc = null;
jta.append("\n\nReady to process next command\n");
checkMode();
setButtons();
//
}
protected void handleReachability(Object _o, SpecificationPropertyPhase _res) {
if (_o instanceof AvatarStateMachineElement) {
Object o = ((AvatarStateMachineElement) _o).getReferenceObject();
if (o instanceof TGComponent) {
TGComponent tgc = (TGComponent) (o);
//TraceManager.addDev("Reachability of tgc=" + tgc + " value=" + tgc.getValue() + " class=" + tgc.getClass());
switch (_res) {
case NOTCOMPUTED:
tgc.setReachability(TGComponent.ACCESSIBILITY_UNKNOWN);
break;
case SATISFIED:
tgc.setReachability(TGComponent.ACCESSIBILITY_OK);
break;
case NONSATISFIED:
tgc.setReachability(TGComponent.ACCESSIBILITY_KO);
tgc.setLiveness(TGComponent.ACCESSIBILITY_KO);
break;
}
tgc.getTDiagramPanel().repaint();
}
}
}
protected void handleLiveness(Object _o, SpecificationPropertyPhase _res) {
if (_o instanceof AvatarStateMachineElement) {
Object o = ((AvatarStateMachineElement) _o).getReferenceObject();
if (o instanceof TGComponent) {
TGComponent tgc = (TGComponent) (o);
//TraceManager.addDev("Reachability of tgc=" + tgc + " value=" + tgc.getValue() + " class=" + tgc.getClass());
switch (_res) {
case NOTCOMPUTED:
tgc.setLiveness(TGComponent.ACCESSIBILITY_UNKNOWN);
break;
case SATISFIED:
tgc.setReachability(TGComponent.ACCESSIBILITY_OK);
tgc.setLiveness(TGComponent.ACCESSIBILITY_OK);
break;
case NONSATISFIED:
tgc.setLiveness(TGComponent.ACCESSIBILITY_KO);
break;
}
tgc.getTDiagramPanel().repaint();
}
}
}
protected void handleSafety(ArrayList<SafetyProperty> safeties) {
int status;
if (safeties == null) {
return;
}
for (SafetyProperty sp : safeties) {
if (sp.getPhase() == SpecificationPropertyPhase.SATISFIED) {
status = AvatarBDSafetyPragma.PROVED_TRUE;
} else if (sp.getPhase() == SpecificationPropertyPhase.NONSATISFIED) {
status = AvatarBDSafetyPragma.PROVED_FALSE;
} else {
status = AvatarBDSafetyPragma.PROVED_ERROR;
}
verifMap.put(sp.getRawProperty(), status);
}
mgui.modelBacktracingUPPAAL(verifMap);
}
protected void checkMode() {
mode = NOT_STARTED;
}
protected void setButtons() {
graphSelected = saveGraphAUT.isSelected();
graphPath.setEnabled(saveGraphAUT.isSelected());
graphSelectedDot = saveGraphDot.isSelected();
saveGraphDot.setEnabled(saveGraphAUT.isSelected());
graphPathDot.setEnabled(saveGraphDot.isSelected() && saveGraphAUT.isSelected());
if (generateDesign != null) {
generateDesignSelected = generateDesign.isSelected();
}
ignoreEmptyTransitionsSelected = ignoreEmptyTransitions.isSelected();
ignoreConcurrenceBetweenInternalActionsSelected = ignoreConcurrenceBetweenInternalActions.isSelected();
ignoreInternalStatesSelected = ignoreInternalStates.isSelected();
checkNoDeadSelected = noDeadlocks.isSelected();
checkReinitSelected = reinit.isSelected();
checkActionLoopSelected = actionLoop.isSelected();
wordRepresentationSelected = wordRepresentationBox.getSelectedIndex();
searchTypeSelected = searchTypeBox.getSelectedIndex();
if (noReachability.isSelected()) {
reachabilitySelected = REACHABILITY_NONE;
} else if (reachabilityCheckable.isSelected()) {
reachabilitySelected = REACHABILITY_SELECTED;
} else {
reachabilitySelected = REACHABILITY_ALL;
}
if (noLiveness.isSelected()) {
livenessSelected = LIVENESS_NONE;
} else if (livenessCheckable.isSelected()) {
livenessSelected = LIVENESS_SELECTED;
} else {
livenessSelected = LIVENESS_ALL;
}
safetySelected = safety.isSelected();
if (!customChecks.isEmpty()) {
for(JCheckBox cb: customChecks) {
cb.setEnabled(safetySelected);
}
}
countertrace.setEnabled(safety.isSelected() || noDeadlocks.isSelected() || actionLoop.isSelected());
countertraceAUT.setEnabled(safety.isSelected() || noDeadlocks.isSelected() || actionLoop.isSelected());
countertraceField.setEnabled(countertrace.isSelected() || countertraceAUT.isSelected());
generateCountertraceSelected = countertrace.isSelected();
generateCountertraceAUTSelected = countertraceAUT.isSelected();
stateLimitField.setEnabled(stateLimit.isSelected());
limitStatesSelected = stateLimit.isSelected();
timeLimitField.setEnabled(timeLimit.isSelected());
limitTimeSelected = timeLimit.isSelected();
switch (mode) {
case NOT_STARTED:
if ((reachabilitySelected == REACHABILITY_SELECTED) || (reachabilitySelected == REACHABILITY_ALL) || (livenessSelected == LIVENESS_SELECTED) || (livenessSelected == LIVENESS_ALL) || checkNoDeadSelected || checkReinitSelected || checkActionLoopSelected || graphSelected || graphSelectedDot) {
start.setEnabled(true);
} else {
if (safetySelected) {
boolean sel = false;
for(JCheckBox cb: customChecks) {
if (cb.isSelected()) {
sel = true;
break;
}
}
start.setEnabled(sel);
} else {
start.setEnabled(false);
}
}
stop.setEnabled(false);
close.setEnabled(true);
//setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
getGlassPane().setVisible(false);
break;
case STARTED:
start.setEnabled(false);
stop.setEnabled(true);
close.setEnabled(false);
getGlassPane().setVisible(true);
//setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
break;
case STOPPED:
default:
start.setEnabled(false);
stop.setEnabled(false);
close.setEnabled(true);
getGlassPane().setVisible(false);
break;
}
show.setEnabled(graphMode == GRAPH_OK);
display.setEnabled(graphMode == GRAPH_OK);
}
public boolean hasToContinue() {
return (go == true);
}
public void appendOut(String s) {
jta.append(s);
}
@Override
public void setError() {
// hasError = true;
}
public void updateValues() {
//TraceManager.addDev("Updating values...");
try {
if (amc != null) {
int nbOfStatess = amc.getNbOfStates();
nbOfStates.setText("" + nbOfStatess);
nbOfLinks.setText("" + amc.getNbOfLinks());
// Reachability and deadlocks
int nb = amc.getNbOfReachabilities();
if (nb == -1) {
//nbOfReachabilities.setText("-");
} else {
nbOfReachabilities.setText("" + nb);
}
nb = amc.getNbOfRemainingReachabilities();
nbOfReachabilitiesNotFound.setText("" + nb);
nbOfDeadlocks.setText("" + amc.getNbOfDeadlocks());
nbOfPendingStates.setText("" + amc.getNbOfPendingStates());
Date d;
previousDate = new Date();
if (endDate != null) {
d = endDate;
} else {
d = previousDate;
}
long duration = d.getTime() - startDate.getTime();
long durationMn = TimeUnit.MILLISECONDS.toMinutes(duration);
long durationSec = TimeUnit.MILLISECONDS.toSeconds(duration) - durationMn * 60;
long durationMs = duration - 1000 * (durationSec - durationMn * 60);
//TraceManager.addDev("mn=" + durationMn + " sec=" + durationSec + " ms=" + durationMs + " raw=" + duration);
String t = String.format("%02d min %02d sec %03d msec", durationMn, durationSec, durationMs);
// long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
// long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
//long diffInMs = TimeUnit.MILLISECONDS.toMilliseconds(duration);
elapsedTime.setText(t);
long diff = 0;
if (endDate != null) {
diff = nbOfStatess;
} else {
diff = nbOfStatess - previousNbOfStates;
}
previousNbOfStates = nbOfStatess;
//if (diff == 0) {
nbOfStatesPerSecond.setText("" + (int)(1000.0 * diff / duration));
updateInfo();
//}
}
} catch (Exception e) {
}
}
private void checkUncheckAllPragmas() {
if (customChecks != null) {
int nb = 0;
for(JCheckBox cb: customChecks) {
nb = cb.isSelected() ? nb + 1 : nb ;
}
boolean check = (nb * 2) < customChecks.size();
for(JCheckBox cb: customChecks) {
cb.setSelected(check);
}
setButtons();
}
}
public void reinitValues() {
nbOfStates.setText("-");
nbOfLinks.setText("-");
nbOfReachabilities.setText("-");
nbOfReachabilitiesNotFound.setText("-");
nbOfDeadlocks.setText("-");
nbOfPendingStates.setText("-");
nbOfStatesPerSecond.setText("-");
elapsedTime.setText("-");
}
public int getStateIndex() {
if (amc == null) {
return 0;
}
if ((endDate == null) && (go == true)) {
return 1;
}
return amc.hasBeenStoppedBeforeCompletion() ? 2 : 3;
}
public void updateInfo() {
info.setForeground(COLORS[getStateIndex()]);
info.setText(INFOS[getStateIndex()]);
}
private class ModelCheckerMonitor extends TimerTask {
private JDialogAvatarModelChecker jdamc;
public ModelCheckerMonitor(JDialogAvatarModelChecker _jdamc) {
jdamc = _jdamc;
}
public void run() {
jdamc.updateValues();
}
}
}