/br.ufes.inf.nemo.oled/src/edu/mit/csail/sdg/alloy4whole/SimpleGUICustom.java
Java | 2102 lines | 1587 code | 204 blank | 311 comment | 332 complexity | 4a33cd158b6068263ff03ae82327f508 MD5 | raw file
Possible License(s): BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- package edu.mit.csail.sdg.alloy4whole;
-
- /**
- * Alloy Analyzer 4 -- Copyright (c) 2006-2009, Felix Chang
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
- import static edu.mit.csail.sdg.alloy4.OurUtil.menu;
- import static edu.mit.csail.sdg.alloy4.OurUtil.menuItem;
- import static java.awt.event.KeyEvent.VK_A;
- import static java.awt.event.KeyEvent.VK_ALT;
- import static java.awt.event.KeyEvent.VK_E;
- import static java.awt.event.KeyEvent.VK_PAGE_DOWN;
- import static java.awt.event.KeyEvent.VK_PAGE_UP;
- import static java.awt.event.KeyEvent.VK_SHIFT;
-
- import java.awt.BorderLayout;
- import java.awt.Color;
- import java.awt.Container;
- import java.awt.Font;
- import java.awt.GraphicsEnvironment;
- import java.awt.Toolkit;
- import java.awt.event.ComponentEvent;
- import java.awt.event.ComponentListener;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.ObjectInputStream;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Random;
- import java.util.Scanner;
- import java.util.Set;
- import java.util.prefs.Preferences;
-
- import javax.swing.Box;
- import javax.swing.Icon;
- import javax.swing.JButton;
- import javax.swing.JCheckBox;
- import javax.swing.JComboBox;
- import javax.swing.JEditorPane;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JMenu;
- import javax.swing.JMenuBar;
- import javax.swing.JMenuItem;
- import javax.swing.JPanel;
- import javax.swing.JScrollPane;
- import javax.swing.JSeparator;
- import javax.swing.JSplitPane;
- import javax.swing.JTextArea;
- import javax.swing.JTextField;
- import javax.swing.JToolBar;
- import javax.swing.KeyStroke;
- import javax.swing.SwingUtilities;
- import javax.swing.WindowConstants;
- import javax.swing.border.EmptyBorder;
- import javax.swing.border.LineBorder;
- import javax.swing.event.HyperlinkEvent;
- import javax.swing.event.HyperlinkListener;
- import javax.swing.text.html.HTMLDocument;
-
- import kodkod.engine.fol2sat.HigherOrderDeclException;
- import edu.mit.csail.sdg.alloy4.A4Reporter;
- import edu.mit.csail.sdg.alloy4.Computer;
- import edu.mit.csail.sdg.alloy4.Err;
- import edu.mit.csail.sdg.alloy4.ErrorFatal;
- import edu.mit.csail.sdg.alloy4.ErrorType;
- import edu.mit.csail.sdg.alloy4.Listener;
- import edu.mit.csail.sdg.alloy4.MacUtil;
- import edu.mit.csail.sdg.alloy4.OurAntiAlias;
- import edu.mit.csail.sdg.alloy4.OurBorder;
- import edu.mit.csail.sdg.alloy4.OurCombobox;
- import edu.mit.csail.sdg.alloy4.OurDialog;
- import edu.mit.csail.sdg.alloy4.OurSyntaxWidget;
- import edu.mit.csail.sdg.alloy4.OurTabbedSyntaxWidget;
- import edu.mit.csail.sdg.alloy4.OurTree;
- import edu.mit.csail.sdg.alloy4.OurUtil;
- import edu.mit.csail.sdg.alloy4.Pair;
- import edu.mit.csail.sdg.alloy4.Pos;
- import edu.mit.csail.sdg.alloy4.Runner;
- import edu.mit.csail.sdg.alloy4.Subprocess;
- import edu.mit.csail.sdg.alloy4.Util;
- import edu.mit.csail.sdg.alloy4.Util.BooleanPref;
- import edu.mit.csail.sdg.alloy4.Util.IntPref;
- import edu.mit.csail.sdg.alloy4.Util.StringPref;
- import edu.mit.csail.sdg.alloy4.Version;
- import edu.mit.csail.sdg.alloy4.WorkerEngineCustom;
- import edu.mit.csail.sdg.alloy4.WorkerEngineCustom.WorkerCallbackCustom;
- import edu.mit.csail.sdg.alloy4.XMLNode;
- import edu.mit.csail.sdg.alloy4compiler.ast.Browsable;
- import edu.mit.csail.sdg.alloy4compiler.ast.Command;
- import edu.mit.csail.sdg.alloy4compiler.ast.Expr;
- import edu.mit.csail.sdg.alloy4compiler.ast.ExprVar;
- import edu.mit.csail.sdg.alloy4compiler.ast.Module;
- import edu.mit.csail.sdg.alloy4compiler.ast.Sig;
- import edu.mit.csail.sdg.alloy4compiler.ast.Sig.Field;
- import edu.mit.csail.sdg.alloy4compiler.parser.CompUtil;
- import edu.mit.csail.sdg.alloy4compiler.sim.SimInstance;
- import edu.mit.csail.sdg.alloy4compiler.sim.SimTuple;
- import edu.mit.csail.sdg.alloy4compiler.sim.SimTupleset;
- import edu.mit.csail.sdg.alloy4compiler.translator.A4Options;
- import edu.mit.csail.sdg.alloy4compiler.translator.A4Options.SatSolver;
- import edu.mit.csail.sdg.alloy4compiler.translator.A4Solution;
- import edu.mit.csail.sdg.alloy4compiler.translator.A4SolutionReader;
- import edu.mit.csail.sdg.alloy4compiler.translator.A4Tuple;
- import edu.mit.csail.sdg.alloy4compiler.translator.A4TupleSet;
- import edu.mit.csail.sdg.alloy4viz.VizGUICustom;
- import edu.mit.csail.sdg.alloy4whole.SimpleReporterCustom.SimpleCallback1;
- import edu.mit.csail.sdg.alloy4whole.SimpleReporterCustom.SimpleTask1;
- import edu.mit.csail.sdg.alloy4whole.SimpleReporterCustom.SimpleTask2;
-
- /** Simple graphical interface for accessing various features of the analyzer.
- *
- * <p> Except noted below, methods in this class can only be called by the AWT event thread.
- *
- * <p> The methods that might get called from other threads are:
- * <br> (1) the run() method in SatRunner is launched from a fresh thread
- * <br> (2) the run() method in the instance watcher (in constructor) is launched from a fresh thread
- */
-
- public final class SimpleGUICustom implements ComponentListener, Listener {
-
- /** The latest welcome screen; each time we update the welcome screen, we increment this number. */
- private static final int welcomeLevel = 2;
-
- // Verify that the graphics environment is set up
- static {
- try {
- GraphicsEnvironment.getLocalGraphicsEnvironment();
- } catch(Throwable ex) {
- System.err.println("Unable to start the graphical environment.");
- System.err.println("If you're on Mac OS X:");
- System.err.println(" Please make sure you are running as the current local user.");
- System.err.println("If you're on Linux or FreeBSD:");
- System.err.println(" Please make sure your X Windows is configured.");
- System.err.println(" You can verify this by typing \"xhost\"; it should not give an error message.");
- System.err.flush();
- /*System.exit(1);*/
- }
- }
-
- //======== The Preferences ======================================================================================//
- //======== Note: you must make sure each preference has a unique key ============================================//
-
- /** The list of allowable memory sizes. */
- private List<Integer> allowedMemorySizes;
-
- /** True if Alloy Analyzer should let warning be nonfatal. */
- private static final BooleanPref WarningNonfatal = new BooleanPref("WarningNonfatal");
-
- /** True if Alloy Analyzer should automatically visualize the latest instance. */
- private static final BooleanPref AutoVisualize = new BooleanPref("AutoVisualize");
-
- /** True if Alloy Analyzer should insist on antialias. */
- private static final BooleanPref AntiAlias = new BooleanPref("AntiAlias");
-
- /** True if Alloy Analyzer should record the raw Kodkod input and output. */
- private static final BooleanPref RecordKodkod = new BooleanPref("RecordKodkod");
-
- /** True if Alloy Analyzer should enable the new Implicit This name resolution. */
- private static final BooleanPref ImplicitThis = new BooleanPref("ImplicitThis");
-
- /** True if Alloy Analyzer should not report models that overflow. */
- private static final BooleanPref NoOverflow = new BooleanPref("NoOverflow");
-
- /** The latest X corrdinate of the Alloy Analyzer's main window. */
- private static final IntPref AnalyzerX = new IntPref("AnalyzerX",0,-1,65535);
-
- /** The latest Y corrdinate of the Alloy Analyzer's main window. */
- private static final IntPref AnalyzerY = new IntPref("AnalyzerY",0,-1,65535);
-
- /** The latest width of the Alloy Analyzer's main window. */
- private static final IntPref AnalyzerWidth = new IntPref("AnalyzerWidth",0,-1,65535);
-
- /** The latest height of the Alloy Analyzer's main window. */
- private static final IntPref AnalyzerHeight = new IntPref("AnalyzerHeight",0,-1,65535);
-
- /** The latest font size of the Alloy Analyzer. */
- private static final IntPref FontSize = new IntPref("FontSize",9,12,72);
-
- /** The latest font name of the Alloy Analyzer. */
- private static final StringPref FontName = new StringPref("FontName","Lucida Grande");
-
- /** The latest tab distance of the Alloy Analyzer. */
- private static final IntPref TabSize = new IntPref("TabSize",1,2,16);
-
- /** The latest welcome screen that the user has seen. */
- private static final IntPref Welcome = new IntPref("Welcome",0,0,1000);
-
- /** Whether syntax highlighting should be disabled or not. */
- private static final BooleanPref SyntaxDisabled = new BooleanPref("SyntaxHighlightingDisabled");
-
- /** The number of recursion unrolls. */
- private static final IntPref Unrolls = new IntPref("Unrolls", -1, -1, 3);
-
- /** The skolem depth. */
- private static final IntPref SkolemDepth = new IntPref("SkolemDepth3", 0, 1, 4);
-
- /** The unsat core minimization strategy. */
- private static final IntPref CoreMinimization = new IntPref("CoreMinimization",0,2,2);
-
- /** The unsat core granularity. */
- private static final IntPref CoreGranularity = new IntPref("CoreGranularity",0,0,3);
-
- /** The amount of memory (in M) to allocate for Kodkod and the SAT solvers. */
- private static final IntPref SubMemory = new IntPref("SubMemory",16,768,65535);
-
- /** The amount of stack (in K) to allocate for Kodkod and the SAT solvers. */
- private static final IntPref SubStack = new IntPref("SubStack",16,8192,65536);
-
- /** The first file in Alloy Analyzer's "open recent" list. */
- private static final StringPref Model0 = new StringPref("Model0");
-
- /** The second file in Alloy Analyzer's "open recent" list. */
- private static final StringPref Model1 = new StringPref("Model1");
-
- /** The third file in Alloy Analyzer's "open recent" list. */
- private static final StringPref Model2 = new StringPref("Model2");
-
- /** The fourth file in Alloy Analyzer's "open recent" list. */
- private static final StringPref Model3 = new StringPref("Model3");
-
- /** This enum defines the set of possible message verbosity levels. */
- private enum Verbosity {
- /** Level 0. */ DEFAULT("0", "low"),
- /** Level 1. */ VERBOSE("1", "medium"),
- /** Level 2. */ DEBUG("2", "high"),
- /** Level 3. */ FULLDEBUG("3", "debug only");
- /** Returns true if it is greater than or equal to "other". */
- @SuppressWarnings("unused")
- public boolean geq(Verbosity other) { return ordinal() >= other.ordinal(); }
- /** This is a unique String for this value; it should be kept consistent in future versions. */
- private final String id;
- /** This is the label that the toString() method will return. */
- private final String label;
- /** Constructs a new Verbosity value with the given id and label. */
- private Verbosity(String id, String label) { this.id=id; this.label=label; }
- /** Given an id, return the enum value corresponding to it (if there's no match, then return DEFAULT). */
- private static Verbosity parse(String id) {
- for(Verbosity vb: values()) if (vb.id.equals(id)) return vb;
- return DEFAULT;
- }
- /** Returns the human-readable label for this enum value. */
- @Override public final String toString() { return label; }
- /** Saves this value into the Java preference object. */
- private void set() { Preferences.userNodeForPackage(Util.class).put("Verbosity",id); }
- /** Reads the current value of the Java preference object (if it's not set, then return DEFAULT). */
- private static Verbosity get() { return parse(Preferences.userNodeForPackage(Util.class).get("Verbosity","")); }
- };
-
- //===================================================================================================//
-
- /** The JFrame for the main window. */
- public JFrame frame;
-
- /** The JFrame for the visualizer window. */
- private VizGUICustom viz;
-
- /** The "File", "Edit", "Run", "Option", "Window", and "Help" menus. */
- private JMenu filemenu, editmenu, runmenu, optmenu, windowmenu, windowmenu2, helpmenu;
-
- /** The toolbar. */
- private JToolBar toolbar;
-
- /** The various toolbar buttons. */
- private JButton runbutton, stopbutton, showbutton;
-
- /** The Splitpane. */
- private JSplitPane splitpane;
-
- /** The JLabel that displays the current line/column position, etc. */
- private JLabel status;
-
- /** Whether the editor has the focus, or the log window has the focus. */
- private boolean lastFocusIsOnEditor = true;
-
- /** The text editor. */
- private OurTabbedSyntaxWidget text;
-
- /** The "message panel" on the right. */
- private SwingLogPanelCustom log;
-
- /** The scrollpane containing the "message panel". */
- private JScrollPane logpane;
-
- /** The last "find" that the user issued. */
- private String lastFind = "";
-
- /** The last find is case-sensitive or not. */
- private boolean lastFindCaseSensitive = true;
-
- /** The last find is forward or not. */
- private boolean lastFindForward = true;
-
- /** The icon for a "checked" menu item. */
- private static final Icon iconYes = OurUtil.loadIcon("images/menu1.gif");
-
- /** The icon for an "unchecked" menu item. */
- private static final Icon iconNo = OurUtil.loadIcon("images/menu0.gif");
-
- /** The system-specific file separator (forward-slash on UNIX, back-slash on Windows, etc.) */
- private static final String fs = System.getProperty("file.separator");
-
- /** The darker background color (for the MessageLog window and the Toolbar and the Status Bar, etc.) */
- private static final Color background = new Color(0.9f, 0.9f, 0.9f);
-
- /** If subrunning==true: 0 means SAT solving; 1 means metamodel; 2 means enumeration. */
- private int subrunningTask = 0;
-
- /** The amount of memory (in MB) currently allocated for this.subprocess */
- private int subMemoryNow = 0;
-
- /** The amount of stack (in KB) currently allocated for this.subprocess */
- private int subStackNow = 0;
-
- /** The list of commands (this field will be cleared to null when the text buffer is edited). */
- private List<Command> commands = null;
-
- /** The latest executed command. */
- private int latestCommand = 0;
-
- /** The current choices of SAT solver. */
- private List<SatSolver> satChoices;
-
- /** The most recent Alloy version (as queried from alloy.mit.edu); -1 if alloy.mit.edu has not replied yet. */
- private int latestAlloyVersion = (-1);
-
- /** The most recent Alloy version name (as queried from alloy.mit.edu); "unknown" if alloy.mit.edu has not replied yet. */
- private String latestAlloyVersionName = "unknown";
-
- /** If it's not "", then it is the XML filename for the latest satisfying instance or the latest metamodel. */
- private String latestInstance = "";
-
- /** If it's not "", then it is the latest instance or metamodel during the most recent click of "Execute". */
- private String latestAutoInstance = "";
-
- /** If true, that means the event handlers should return a Runner encapsulating them, rather than perform the actual work. */
- private boolean wrap = false;
-
- //===================================================================================================//
-
- /** frame is visible. */
- public boolean isVisible=true;
-
- /** theme path. */
- public String themePath="";
-
- private boolean initialized=false;
- public boolean isInitialized() { return initialized; }
- public void setIsInitialized(boolean value) { initialized=value; }
-
- //====== helper methods =================================================//
-
- /** Inserts "filename" into the "recently opened file list". */
- private void addHistory(String filename) {
- String name0=Model0.get(), name1=Model1.get(), name2=Model2.get();
- if (name0.equals(filename)) return; else {Model0.set(filename); Model1.set(name0);}
- if (name1.equals(filename)) return; else Model2.set(name1);
- if (name2.equals(filename)) return; else Model3.set(name2);
- }
-
- /** Sets the flag "lastFocusIsOnEditor" to be true. */
- private Runner notifyFocusGained() {
- if (wrap) return wrapMe();
- lastFocusIsOnEditor=true;
- return null;
- }
-
- /** Sets the flag "lastFocusIsOnEditor" to be false. */
- void notifyFocusLost() { lastFocusIsOnEditor=false; }
-
- /** Updates the status bar at the bottom of the screen. */
- private Runner notifyChange() {
- if (wrap) return wrapMe();
- commands=null;
- if (text==null) return null; // If this was called prior to the "text" being fully initialized
- OurSyntaxWidget t = text.get();
- if (Util.onMac()) frame.getRootPane().putClientProperty("windowModified", Boolean.valueOf(t.modified()));
- if (t.isFile()) frame.setTitle(t.getFilename()); else frame.setTitle("Alloy Analyzer "+Version.version());
- toolbar.setBorder(new OurBorder(false, false, text.count()<=1, false));
- int c = t.getCaret();
- int y = t.getLineOfOffset(c)+1;
- int x = c - t.getLineStartOffset(y-1)+1;
- status.setText("<html> Line "+y+", Column "+x
- +(t.modified()?" <b style=\"color:#B43333;\">[modified]</b></html>":"</html>"));
- return null;
- }
-
- /** Helper method that returns a hopefully very short name for a file name. */
- public static String slightlyShorterFilename(String name) {
- if (name.toLowerCase(Locale.US).endsWith(".als")) {
- int i=name.lastIndexOf('/');
- if (i>=0) name=name.substring(i+1);
- i=name.lastIndexOf('\\');
- if (i>=0) name=name.substring(i+1);
- return name.substring(0, name.length()-4);
- } else if (name.toLowerCase(Locale.US).endsWith(".xml")) {
- int i=name.lastIndexOf('/');
- if (i>0) i=name.lastIndexOf('/', i-1);
- if (i>=0) name=name.substring(i+1);
- i=name.lastIndexOf('\\');
- if (i>0) i=name.lastIndexOf('\\', i-1);
- if (i>=0) name=name.substring(i+1);
- return name.substring(0, name.length()-4);
- }
- return name;
- }
-
- /** Copy the required files from the JAR into a temporary directory. */
- private void copyFromJAR() {
- // Compute the appropriate platform
- String os = System.getProperty("os.name").toLowerCase(Locale.US).replace(' ','-');
- if (os.startsWith("mac-")) os="mac"; else if (os.startsWith("windows-")) os="windows";
- String arch = System.getProperty("os.arch").toLowerCase(Locale.US).replace(' ','-');
- if (arch.equals("powerpc")) arch="ppc-"+os; else arch=arch.replaceAll("\\Ai[3456]86\\z","x86")+"-"+os;
- if (os.equals("mac")) arch="x86-mac"; // our pre-compiled binaries are all universal binaries
- // Find out the appropriate Alloy directory
- final String platformBinary = alloyHome() + fs + "binary";
- // Write a few test files
- try {
- (new File(platformBinary)).mkdirs();
- Util.writeAll(platformBinary + fs + "tmp.cnf", "p cnf 3 1\n1 0\n");
- } catch(Err er) {
- // The error will be caught later by the "berkmin" or "spear" test
- }
- // Copy the platform-dependent binaries
- Util.copy(true, false, platformBinary,
- arch+"/libminisat.so", arch+"/libminisatx1.so", arch+"/libminisat.jnilib",
- arch+"/libminisatprover.so", arch+"/libminisatproverx1.so", arch+"/libminisatprover.jnilib",
- arch+"/libzchaff.so", arch+"/libzchaffx1.so", arch+"/libzchaff.jnilib",
- arch+"/berkmin", arch+"/spear");
- Util.copy(false, false, platformBinary,
- arch+"/minisat.dll", arch+"/minisatprover.dll", arch+"/zchaff.dll",
- arch+"/berkmin.exe", arch+"/spear.exe");
- // Copy the model files
- Util.copy(false, true, alloyHome(),
- "models/book/appendixA/addressBook1.als", "models/book/appendixA/addressBook2.als", "models/book/appendixA/barbers.als",
- "models/book/appendixA/closure.als", "models/book/appendixA/distribution.als", "models/book/appendixA/phones.als",
- "models/book/appendixA/prison.als", "models/book/appendixA/properties.als", "models/book/appendixA/ring.als",
- "models/book/appendixA/spanning.als", "models/book/appendixA/tree.als", "models/book/appendixA/tube.als", "models/book/appendixA/undirected.als",
- "models/book/appendixE/hotel.thm", "models/book/appendixE/p300-hotel.als", "models/book/appendixE/p303-hotel.als", "models/book/appendixE/p306-hotel.als",
- "models/book/chapter2/addressBook1a.als", "models/book/chapter2/addressBook1b.als", "models/book/chapter2/addressBook1c.als",
- "models/book/chapter2/addressBook1d.als", "models/book/chapter2/addressBook1e.als", "models/book/chapter2/addressBook1f.als",
- "models/book/chapter2/addressBook1g.als", "models/book/chapter2/addressBook1h.als", "models/book/chapter2/addressBook2a.als",
- "models/book/chapter2/addressBook2b.als", "models/book/chapter2/addressBook2c.als", "models/book/chapter2/addressBook2d.als",
- "models/book/chapter2/addressBook2e.als", "models/book/chapter2/addressBook3a.als", "models/book/chapter2/addressBook3b.als",
- "models/book/chapter2/addressBook3c.als", "models/book/chapter2/addressBook3d.als", "models/book/chapter2/theme.thm",
- "models/book/chapter4/filesystem.als", "models/book/chapter4/grandpa1.als",
- "models/book/chapter4/grandpa2.als", "models/book/chapter4/grandpa3.als", "models/book/chapter4/lights.als",
- "models/book/chapter5/addressBook.als", "models/book/chapter5/lists.als", "models/book/chapter5/sets1.als", "models/book/chapter5/sets2.als",
- "models/book/chapter6/hotel.thm", "models/book/chapter6/hotel1.als", "models/book/chapter6/hotel2.als",
- "models/book/chapter6/hotel3.als", "models/book/chapter6/hotel4.als", "models/book/chapter6/mediaAssets.als",
- "models/book/chapter6/memory/abstractMemory.als", "models/book/chapter6/memory/cacheMemory.als",
- "models/book/chapter6/memory/checkCache.als", "models/book/chapter6/memory/checkFixedSize.als",
- "models/book/chapter6/memory/fixedSizeMemory.als", "models/book/chapter6/memory/fixedSizeMemory_H.als",
- "models/book/chapter6/ringElection.thm", "models/book/chapter6/ringElection1.als", "models/book/chapter6/ringElection2.als",
- "models/examples/algorithms/dijkstra.als", "models/examples/algorithms/dijkstra.thm",
- "models/examples/algorithms/messaging.als", "models/examples/algorithms/messaging.thm",
- "models/examples/algorithms/opt_spantree.als", "models/examples/algorithms/opt_spantree.thm",
- "models/examples/algorithms/peterson.als",
- "models/examples/algorithms/ringlead.als", "models/examples/algorithms/ringlead.thm",
- "models/examples/algorithms/s_ringlead.als",
- "models/examples/algorithms/stable_mutex_ring.als", "models/examples/algorithms/stable_mutex_ring.thm",
- "models/examples/algorithms/stable_orient_ring.als", "models/examples/algorithms/stable_orient_ring.thm",
- "models/examples/algorithms/stable_ringlead.als", "models/examples/algorithms/stable_ringlead.thm",
- "models/examples/case_studies/INSLabel.als", "models/examples/case_studies/chord.als",
- "models/examples/case_studies/chord2.als", "models/examples/case_studies/chordbugmodel.als",
- "models/examples/case_studies/com.als", "models/examples/case_studies/firewire.als", "models/examples/case_studies/firewire.thm",
- "models/examples/case_studies/ins.als", "models/examples/case_studies/iolus.als",
- "models/examples/case_studies/sync.als", "models/examples/case_studies/syncimpl.als",
- "models/examples/puzzles/farmer.als", "models/examples/puzzles/farmer.thm",
- "models/examples/puzzles/handshake.als", "models/examples/puzzles/handshake.thm",
- "models/examples/puzzles/hanoi.als", "models/examples/puzzles/hanoi.thm",
- "models/examples/systems/file_system.als", "models/examples/systems/file_system.thm",
- "models/examples/systems/javatypes_soundness.als",
- "models/examples/systems/lists.als", "models/examples/systems/lists.thm",
- "models/examples/systems/marksweepgc.als", "models/examples/systems/views.als",
- "models/examples/toys/birthday.als", "models/examples/toys/birthday.thm",
- "models/examples/toys/ceilingsAndFloors.als", "models/examples/toys/ceilingsAndFloors.thm",
- "models/examples/toys/genealogy.als", "models/examples/toys/genealogy.thm",
- "models/examples/toys/grandpa.als", "models/examples/toys/grandpa.thm",
- "models/examples/toys/javatypes.als", "models/examples/toys/life.als", "models/examples/toys/life.thm",
- "models/examples/toys/numbering.als", "models/examples/toys/railway.als", "models/examples/toys/railway.thm",
- "models/examples/toys/trivial.als",
- "models/examples/tutorial/farmer.als",
- "models/util/boolean.als", "models/util/graph.als", "models/util/integer.als", "models/util/natural.als",
- "models/util/ordering.als", "models/util/relation.als", "models/util/seqrel.als", "models/util/sequence.als",
- "models/util/sequniv.als", "models/util/ternary.als", "models/util/time.als"
- );
- // Record the locations
- System.setProperty("alloy.theme0", alloyHome() + fs + "models");
- System.setProperty("alloy.home", alloyHome());
- }
-
- /** Called when this window is resized. */
- public void componentResized(ComponentEvent e) {
- componentMoved(e);
- }
-
- /** Called when this window is moved. */
- public void componentMoved(ComponentEvent e) {
- AnalyzerWidth.set(frame.getWidth());
- AnalyzerHeight.set(frame.getHeight());
- AnalyzerX.set(frame.getX());
- AnalyzerY.set(frame.getY());
- }
-
- /** Called when this window is shown. */
- public void componentShown(ComponentEvent e) {}
-
- /** Called when this window is hidden. */
- public void componentHidden(ComponentEvent e) {}
-
- /** Wraps the calling method into a Runnable whose run() will call the calling method with (false) as the only argument. */
- private Runner wrapMe() {
- final String name;
- try { throw new Exception(); } catch(Exception ex) { name = ex.getStackTrace()[1].getMethodName(); }
- Method[] methods = getClass().getDeclaredMethods();
- Method m=null;
- for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(name)) { m=methods[i]; break; }
- final Method method=m;
- return new Runner() {
- private static final long serialVersionUID = 0;
- public void run() {
- try {
- method.setAccessible(true);
- method.invoke(SimpleGUICustom.this, new Object[]{});
- } catch (Throwable ex) {
- ex = new IllegalArgumentException("Failed call to "+name+"()", ex);
- Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), ex);
- }
- }
- public void run(Object arg) { run(); }
- };
- }
-
- /** Wraps the calling method into a Runnable whose run() will call the calling method with (false,argument) as the two arguments. */
- private Runner wrapMe(final Object argument) {
- final String name;
- try { throw new Exception(); } catch(Exception ex) { name = ex.getStackTrace()[1].getMethodName(); }
- Method[] methods = getClass().getDeclaredMethods();
- Method m=null;
- for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(name)) { m=methods[i]; break; }
- final Method method=m;
- return new Runner() {
- private static final long serialVersionUID = 0;
- public void run(Object arg) {
- try {
- method.setAccessible(true);
- method.invoke(SimpleGUICustom.this, new Object[]{arg});
- } catch (Throwable ex) {
- ex = new IllegalArgumentException("Failed call to "+name+"("+arg+")", ex);
- Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), ex);
- }
- }
- public void run() { run(argument); }
- };
- }
-
- /** This variable caches the result of alloyHome() function call. */
- private static String alloyHome = null;
-
- /** Find a temporary directory to store Alloy files; it's guaranteed to be a canonical absolute path. */
- private static synchronized String alloyHome() {
- if (alloyHome!=null) return alloyHome;
- String temp=System.getProperty("java.io.tmpdir");
- if (temp==null || temp.length()==0)
- OurDialog.fatal("Error. JVM need to specify a temporary directory using java.io.tmpdir property.");
- String username=System.getProperty("user.name");
- File tempfile=new File(temp+File.separatorChar+"alloy4tmp40-"+(username==null?"":username));
- tempfile.mkdirs();
- String ans=Util.canon(tempfile.getPath());
- if (!tempfile.isDirectory()) {
- OurDialog.fatal("Error. Cannot create the temporary directory "+ans);
- }
- if (!Util.onWindows()) {
- String[] args={"chmod", "700", ans};
- try {Runtime.getRuntime().exec(args).waitFor();}
- catch (Throwable ex) {} // We only intend to make a best effort.
- }
- return alloyHome=ans;
- }
-
- /** Create an empty temporary directory for use, designate it "deleteOnExit", then return it.
- * It is guaranteed to be a canonical absolute path. */
- private static String maketemp() {
- Random r=new Random(new Date().getTime());
- while(true) {
- int i=r.nextInt(1000000);
- String dest = alloyHome()+File.separatorChar+"tmp"+File.separatorChar+i;
- File f=new File(dest);
- if (f.mkdirs()) {
- f.deleteOnExit();
- return Util.canon(dest);
- }
- }
- }
-
- /** Return the number of bytes used by the Temporary Directory (or return -1 if the answer exceeds "long") */
- private static long computeTemporarySpaceUsed() {
- long ans = iterateTemp(null,false);
- if (ans<0) return -1; else return ans;
- }
-
- /** Delete every file in the Temporary Directory. */
- private static void clearTemporarySpace() {
- iterateTemp(null,true);
- // Also clear the temp dir from previous versions of Alloy4
- String temp=System.getProperty("java.io.tmpdir");
- if (temp==null || temp.length()==0) return;
- String username=System.getProperty("user.name");
- if (username==null) username="";
- for(int i=1; i<40; i++) iterateTemp(temp+File.separatorChar+"alloy4tmp"+i+"-"+username, true);
- }
-
- /** Helper method for performing either computeTemporarySpaceUsed() or clearTemporarySpace() */
- private static long iterateTemp(String filename, boolean delete) {
- long ans=0;
- if (filename==null) filename = alloyHome()+File.separatorChar+"tmp";
- File x = new File(filename);
- if (x.isDirectory()) {
- for(String subfile:x.list()) {
- long tmp=iterateTemp(filename+File.separatorChar+subfile, delete);
- if (ans>=0) ans=ans+tmp;
- }
- }
- else if (x.isFile()) {
- long tmp=x.length();
- if (ans>=0) ans=ans+tmp;
- }
- if (delete) x.delete();
- return ans;
- }
-
- //===============================================================================================================//
-
- /** This method refreshes the "file" menu. */
- private Runner doRefreshFile() {
- if (wrap) return wrapMe();
- try {
- wrap = true;
- filemenu.removeAll();
- menuItem(filemenu, "New", 'N', 'N', doNew());
- menuItem(filemenu, "Open...", 'O', 'O', doOpen());
- if (!Util.onMac())
- menuItem(filemenu, "Open Sample Models...", VK_ALT, 'O', doBuiltin());
- else
- menuItem(filemenu, "Open Sample Models...", doBuiltin());
- JMenu recentmenu;
- filemenu.add(recentmenu = new JMenu("Open Recent"));
- menuItem(filemenu, "Reload all", 'R', 'R', doReloadAll());
- menuItem(filemenu, "Save", 'S', 'S', doSave());
- if (Util.onMac())
- menuItem(filemenu, "Save As...", VK_SHIFT, 'S', doSaveAs());
- else
- menuItem(filemenu, "Save As...", 'A', doSaveAs());
- menuItem(filemenu, "Close", 'W', 'W', doClose());
- menuItem(filemenu, "Clear Temporary Directory", doClearTemp());
- menuItem(filemenu, "Quit", 'Q', (Util.onMac() ? -1 : 'Q'), doQuit());
- boolean found = false;
- for(Util.StringPref p: new Util.StringPref[]{ Model0, Model1, Model2, Model3 }) {
- String name = p.get();
- if (name.length()>0) { found = true; menuItem(recentmenu, name, doOpenFile(name)); }
- }
- recentmenu.addSeparator();
- menuItem(recentmenu, "Clear Menu", doClearRecent());
- recentmenu.setEnabled(found);
- } finally {
- wrap = false;
- }
- return null;
- }
-
- /** This method performs File->New. */
- public Runner doNew() {
- if (!wrap) { text.newtab(null); notifyChange(); doShow(); }
- return wrapMe();
- }
-
- /** This method performs File->Open. */
- public Runner doOpen() {
- if (wrap) return wrapMe();
- File file=OurDialog.askFile(true, null, ".als", ".als files");
- if (file!=null) {
- Util.setCurrentDirectory(file.getParentFile());
- doOpenFile(file.getPath());
- }
- return null;
- }
-
- /** This method performs File->OpenBuiltinModels. */
- public Runner doBuiltin() {
- if (wrap) return wrapMe();
- File file=OurDialog.askFile(true, alloyHome() + fs + "models", ".als", ".als files");
- if (file!=null) {
- doOpenFile(file.getPath());
- }
- return null;
- }
-
- /** This method performs File->ReloadAll. */
- public Runner doReloadAll() {
- if (!wrap) text.reloadAll();
- return wrapMe();
- }
-
- /** This method performs File->ClearRecentFiles. */
- public Runner doClearRecent() {
- if (!wrap) { Model0.set(""); Model1.set(""); Model2.set(""); Model3.set(""); }
- return wrapMe();
- }
-
- /** This method performs File->Save. */
- public Runner doSave() {
- if (!wrap) {
- String ans = text.save(false);
- if (ans==null) return null;
- notifyChange();
- addHistory(ans);
- log.clearError();
- }
- return wrapMe();
- }
-
- /** This method performs File->SaveAs. */
- public Runner doSaveAs() {
- if (!wrap) {
- String ans = text.save(true);
- if (ans==null) return null;
- notifyChange();
- addHistory(ans);
- log.clearError();
- }
- return wrapMe();
- }
-
- /** This method clears the temporary files and then reinitialize the temporary directory. */
- public Runner doClearTemp() {
- if (!wrap) {
- clearTemporarySpace();
- copyFromJAR();
- log.logBold("Temporary directory has been cleared.\n\n");
- log.logDivider();
- log.flush();
- }
- return wrapMe();
- }
-
- /** This method performs File->Close. */
- public Runner doClose() {
- if (!wrap) text.close();
- return wrapMe();
- }
-
- /** This method performs File->Quit. */
- public Runner doQuit() {
- if (!wrap) if (text.closeAll()) {
- try { WorkerEngineCustom.stop(); } finally { }
- }
- return wrapMe();
- }
-
- //===============================================================================================================//
-
- /** This method refreshes the "edit" menu. */
- private Runner doRefreshEdit() {
- if (wrap) return wrapMe();
- try {
- wrap = true;
- boolean canUndo = text.get().canUndo();
- boolean canRedo = text.get().canRedo();
- editmenu.removeAll();
- menuItem(editmenu, "Undo", 'Z', 'Z', doUndo(), canUndo);
- if (Util.onMac())
- menuItem(editmenu, "Redo", VK_SHIFT, 'Z', doRedo(), canRedo);
- else
- menuItem(editmenu, "Redo", 'Y', 'Y', doRedo(), canRedo);
- editmenu.addSeparator();
- menuItem(editmenu, "Cut", 'X', 'X', doCut());
- menuItem(editmenu, "Copy", 'C', 'C', doCopy());
- menuItem(editmenu, "Paste", 'V', 'V', doPaste());
- editmenu.addSeparator();
- menuItem(editmenu, "Go To..." , 'T', 'T', doGoto());
- menuItem(editmenu, "Previous File" , VK_PAGE_UP, VK_PAGE_UP, doGotoPrevFile(), text.count()>1);
- menuItem(editmenu, "Next File" , VK_PAGE_DOWN, VK_PAGE_DOWN, doGotoNextFile(), text.count()>1);
- editmenu.addSeparator();
- menuItem(editmenu, "Find...", 'F', 'F', doFind());
- menuItem(editmenu, "Find Next", 'G', 'G', doFindNext());
- } finally {
- wrap = false;
- }
- return null;
- }
-
- /** This method performs Edit->Undo. */
- public Runner doUndo() {
- if (!wrap) text.get().undo();
- return wrapMe();
- }
-
- /** This method performs Edit->Redo. */
- public Runner doRedo() {
- if (!wrap) text.get().redo();
- return wrapMe();
- }
-
- /** This method performs Edit->Copy. */
- public Runner doCopy() {
- if (!wrap) { if (lastFocusIsOnEditor) text.get().copy(); else log.copy(); }
- return wrapMe();
- }
-
- /** This method performs Edit->Cut. */
- public Runner doCut() {
- if (!wrap && lastFocusIsOnEditor) text.get().cut();
- return wrapMe();
- }
-
- /** This method performs Edit->Paste. */
- public Runner doPaste() {
- if (!wrap && lastFocusIsOnEditor) text.get().paste();
- return wrapMe();
- }
-
- /** This method performs Edit->Find. */
- public Runner doFind() {
- if (wrap) return wrapMe();
- JTextField x = OurUtil.textfield(lastFind,30);
- x.selectAll();
- JCheckBox c = new JCheckBox("Case Sensitive?",lastFindCaseSensitive);
- c.setMnemonic('c');
- JCheckBox b = new JCheckBox("Search Backward?",!lastFindForward);
- b.setMnemonic('b');
- if (!OurDialog.getInput("Find", "Text:", x, " ", c, b)) return null;
- if (x.getText().length() == 0) return null;
- lastFind = x.getText();
- lastFindCaseSensitive = c.getModel().isSelected();
- lastFindForward = !b.getModel().isSelected();
- doFindNext();
- return null;
- }
-
- /** This method performs Edit->FindNext. */
- public Runner doFindNext() {
- if (wrap) return wrapMe();
- if (lastFind.length()==0) return null;
- OurSyntaxWidget t = text.get();
- String all = t.getText();
- int i = Util.indexOf(all, lastFind, t.getCaret()+(lastFindForward?0:-1),lastFindForward,lastFindCaseSensitive);
- if (i<0) {
- i=Util.indexOf(all, lastFind, lastFindForward?0:(all.length()-1), lastFindForward, lastFindCaseSensitive);
- if (i<0) { log.logRed("The specified search string cannot be found."); return null; }
- log.logRed("Search wrapped.");
- } else {
- log.clearError();
- }
- if (lastFindForward) t.moveCaret(i, i+lastFind.length()); else t.moveCaret(i+lastFind.length(), i);
- t.requestFocusInWindow();
- return null;
- }
-
- /** This method performs Edit->Goto. */
- public Runner doGoto() {
- if (wrap) return wrapMe();
- JTextField y = OurUtil.textfield("", 10);
- JTextField x = OurUtil.textfield("", 10);
- if (!OurDialog.getInput("Go To", "Line Number:", y, "Column Number (optional):", x)) return null;
- try {
- OurSyntaxWidget t = text.get();
- int xx = 1, yy = Integer.parseInt(y.getText()), lineCount = t.getLineCount();
- if (yy<1) return null;
- if (yy>lineCount) {log.logRed("This file only has "+lineCount+" line(s)."); return null;}
- if (x.getText().length()!=0) xx=Integer.parseInt(x.getText());
- if (xx<1) {log.logRed("If the column number is specified, it must be 1 or greater."); return null;}
- int caret = t.getLineStartOffset(yy-1);
- int len = (yy==lineCount ? t.getText().length()+1 : t.getLineStartOffset(yy)) - caret;
- if (xx>len) xx=len;
- if (xx<1) xx=1;
- t.moveCaret(caret+xx-1, caret+xx-1);
- t.requestFocusInWindow();
- } catch(NumberFormatException ex) {
- log.logRed("The number must be 1 or greater.");
- } catch(Throwable ex) {
- // This error is not important
- }
- return null;
- }
-
- /** This method performs Edit->GotoPrevFile. */
- public Runner doGotoPrevFile() {
- if (wrap) return wrapMe(); else {text.prev(); return null;}
- }
-
- /** This method performs Edit->GotoNextFile. */
- public Runner doGotoNextFile() {
- if (wrap) return wrapMe(); else {text.next(); return null;}
- }
-
- //===============================================================================================================//
-
- /** This method refreshes the "run" menu. */
- public Runner doRefreshRun() {
- if (wrap) return wrapMe();
- KeyStroke ac = KeyStroke.getKeyStroke(VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
- try {
- wrap = true;
- runmenu.removeAll();
- menuItem(runmenu, "Execute Latest Command", 'E', 'E', doExecuteLatest());
- runmenu.add(new JSeparator());
- menuItem(runmenu, "Show Latest Instance", 'L', 'L', doShowLatest(), latestInstance.length()>0);
- menuItem(runmenu, "Show Metamodel", 'M', 'M', doShowMetaModel());
- if (Version.experimental) menuItem(runmenu, "Show Parse Tree", 'P', doShowParseTree());
- menuItem(runmenu, "Open Evaluator", 'V', doLoadEvaluator());
- } finally {
- wrap = false;
- }
- List<Command> cp = commands;
- if (cp==null) {
- try {
- cp=CompUtil.parseOneModule_fromString(text.get().getText());
- }
- catch(Err e) {
- commands = null;
- runmenu.getItem(0).setEnabled(false);
- runmenu.getItem(3).setEnabled(false);
- text.shade(new Pos(text.get().getFilename(), e.pos.x, e.pos.y, e.pos.x2, e.pos.y2));
- if ("yes".equals(System.getProperty("debug")) && Verbosity.get()==Verbosity.FULLDEBUG)
- log.logRed("Fatal Exception!" + e.dump() + "\n\n");
- else
- log.logRed(e.toString()+"\n\n");
- return null;
- }
- catch(Throwable e) {
- commands = null;
- runmenu.getItem(0).setEnabled(false);
- runmenu.getItem(3).setEnabled(false);
- log.logRed("Cannot parse the model.\n"+e.toString()+"\n\n");
- return null;
- }
- commands=cp;
- }
- text.clearShade();
- log.clearError(); // To clear any residual error message
- if (cp==null) { runmenu.getItem(0).setEnabled(false); runmenu.getItem(3).setEnabled(false); return null; }
- if (cp.size()==0) { runmenu.getItem(0).setEnabled(false); return null; }
- if (latestCommand>=cp.size()) latestCommand=cp.size()-1;
- runmenu.remove(0);
- try {
- wrap = true;
- for(int i=0; i<cp.size(); i++) {
- JMenuItem y = new JMenuItem(cp.get(i).toString(), null);
- y.addActionListener(doRun(i));
- if (i==latestCommand) { y.setMnemonic(VK_E); y.setAccelerator(ac); }
- runmenu.add(y,i);
- }
- if (cp.size()>=2) {
- JMenuItem y = new JMenuItem("Execute All", null);
- y.setMnemonic(VK_A);
- y.addActionListener(doRun(-1));
- runmenu.add(y,0);
- runmenu.add(new JSeparator(),1);
- }
- } finally {
- wrap = false;
- }
- return null;
- }
-
- /** This method executes a particular RUN or CHECK command. */
- public Runner doRun(Integer commandIndex) {
-
- if (wrap) return wrapMe(commandIndex);
- final int index = commandIndex;
- if (WorkerEngineCustom.isBusy()) return null;
- if (index==(-2)) subrunningTask=1; else subrunningTask=0;
- latestAutoInstance="";
- if (index>=0) latestCommand=index;
- if (index==-1 && commands!=null) {
- latestCommand=commands.size()-1;
- if (latestCommand<0) latestCommand=0;
- }
- // To update the accelerator to point to the command actually chosen
- doRefreshRun();
- OurUtil.enableAll(runmenu);
- if (commands==null) return null;
- if (commands.size()==0 && index!=-2 && index!=-3) { log.logRed("There are no commands to execute.\n\n"); return null; }
- int i=index;
- if (i>=commands.size()) i=commands.size()-1;
- SimpleCallback1 cb = new SimpleCallback1(this, null, log, Verbosity.get().ordinal(), latestAlloyVersionName, latestAlloyVersion);
- SimpleTask1 task = new SimpleTask1();
- A4Options opt = new A4Options();
- opt.tempDirectory = alloyHome() + fs + "tmp";
- opt.solverDirectory = alloyHome() + fs + "binary";
- opt.recordKodkod = RecordKodkod.get();
- opt.noOverflow = NoOverflow.get();
- opt.unrolls = Version.experimental ? Unrolls.get() : (-1);
- opt.skolemDepth = SkolemDepth.get();
- opt.coreMinimization = CoreMinimization.get();
- opt.coreGranularity = CoreGranularity.get();
- opt.originalFilename = Util.canon(text.get().getFilename());
- opt.solver = SatSolver.get();
- task.bundleIndex = i;
- task.bundleWarningNonFatal = WarningNonfatal.get();
- task.map = text.takeSnapshot();
- task.options = opt.dup();
- task.resolutionMode = (Version.experimental && ImplicitThis.get()) ? 2 : 1;
- task.tempdir = maketemp();
- try {
- runmenu.setEnabled(false);
- runbutton.setVisible(false);
- showbutton.setEnabled(false);
- stopbutton.setVisible(true);
- int newmem = SubMemory.get(), newstack = SubStack.get();
- if (newmem != subMemoryNow || newstack != subStackNow) WorkerEngineCustom.stop();
- if ("yes".equals(System.getProperty("debug")) && Verbosity.get()==Verbosity.FULLDEBUG)
- WorkerEngineCustom.runLocally(task, cb);
- else
- WorkerEngineCustom.run(task, newmem, newstack, alloyHome() + fs + "binary", "", cb);
- subMemoryNow = newmem;
- subStackNow = newstack;
- } catch(Throwable ex) {
- WorkerEngineCustom.stop();
- log.logBold("Fatal Error: Solver failed due to unknown reason.\n" +
- "One possible cause is that, in the Options menu, your specified\n" +
- "memory size is larger than the amount allowed by your OS.\n" +
- …
Large files files are truncated, but you can click here to view the full file