PageRenderTime 62ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/br.ufes.inf.nemo.oled/src/edu/mit/csail/sdg/alloy4whole/SimpleGUICustom.java

https://github.com/petrux/OLED
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

  1. package edu.mit.csail.sdg.alloy4whole;
  2. /**
  3. * Alloy Analyzer 4 -- Copyright (c) 2006-2009, Felix Chang
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
  6. * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
  7. * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  13. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  14. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  15. * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. *
  17. */
  18. import static edu.mit.csail.sdg.alloy4.OurUtil.menu;
  19. import static edu.mit.csail.sdg.alloy4.OurUtil.menuItem;
  20. import static java.awt.event.KeyEvent.VK_A;
  21. import static java.awt.event.KeyEvent.VK_ALT;
  22. import static java.awt.event.KeyEvent.VK_E;
  23. import static java.awt.event.KeyEvent.VK_PAGE_DOWN;
  24. import static java.awt.event.KeyEvent.VK_PAGE_UP;
  25. import static java.awt.event.KeyEvent.VK_SHIFT;
  26. import java.awt.BorderLayout;
  27. import java.awt.Color;
  28. import java.awt.Container;
  29. import java.awt.Font;
  30. import java.awt.GraphicsEnvironment;
  31. import java.awt.Toolkit;
  32. import java.awt.event.ComponentEvent;
  33. import java.awt.event.ComponentListener;
  34. import java.io.File;
  35. import java.io.FileInputStream;
  36. import java.io.IOException;
  37. import java.io.InputStream;
  38. import java.io.ObjectInputStream;
  39. import java.lang.reflect.Method;
  40. import java.util.ArrayList;
  41. import java.util.Arrays;
  42. import java.util.Date;
  43. import java.util.LinkedHashMap;
  44. import java.util.List;
  45. import java.util.Locale;
  46. import java.util.Map;
  47. import java.util.Random;
  48. import java.util.Scanner;
  49. import java.util.Set;
  50. import java.util.prefs.Preferences;
  51. import javax.swing.Box;
  52. import javax.swing.Icon;
  53. import javax.swing.JButton;
  54. import javax.swing.JCheckBox;
  55. import javax.swing.JComboBox;
  56. import javax.swing.JEditorPane;
  57. import javax.swing.JFrame;
  58. import javax.swing.JLabel;
  59. import javax.swing.JMenu;
  60. import javax.swing.JMenuBar;
  61. import javax.swing.JMenuItem;
  62. import javax.swing.JPanel;
  63. import javax.swing.JScrollPane;
  64. import javax.swing.JSeparator;
  65. import javax.swing.JSplitPane;
  66. import javax.swing.JTextArea;
  67. import javax.swing.JTextField;
  68. import javax.swing.JToolBar;
  69. import javax.swing.KeyStroke;
  70. import javax.swing.SwingUtilities;
  71. import javax.swing.WindowConstants;
  72. import javax.swing.border.EmptyBorder;
  73. import javax.swing.border.LineBorder;
  74. import javax.swing.event.HyperlinkEvent;
  75. import javax.swing.event.HyperlinkListener;
  76. import javax.swing.text.html.HTMLDocument;
  77. import kodkod.engine.fol2sat.HigherOrderDeclException;
  78. import edu.mit.csail.sdg.alloy4.A4Reporter;
  79. import edu.mit.csail.sdg.alloy4.Computer;
  80. import edu.mit.csail.sdg.alloy4.Err;
  81. import edu.mit.csail.sdg.alloy4.ErrorFatal;
  82. import edu.mit.csail.sdg.alloy4.ErrorType;
  83. import edu.mit.csail.sdg.alloy4.Listener;
  84. import edu.mit.csail.sdg.alloy4.MacUtil;
  85. import edu.mit.csail.sdg.alloy4.OurAntiAlias;
  86. import edu.mit.csail.sdg.alloy4.OurBorder;
  87. import edu.mit.csail.sdg.alloy4.OurCombobox;
  88. import edu.mit.csail.sdg.alloy4.OurDialog;
  89. import edu.mit.csail.sdg.alloy4.OurSyntaxWidget;
  90. import edu.mit.csail.sdg.alloy4.OurTabbedSyntaxWidget;
  91. import edu.mit.csail.sdg.alloy4.OurTree;
  92. import edu.mit.csail.sdg.alloy4.OurUtil;
  93. import edu.mit.csail.sdg.alloy4.Pair;
  94. import edu.mit.csail.sdg.alloy4.Pos;
  95. import edu.mit.csail.sdg.alloy4.Runner;
  96. import edu.mit.csail.sdg.alloy4.Subprocess;
  97. import edu.mit.csail.sdg.alloy4.Util;
  98. import edu.mit.csail.sdg.alloy4.Util.BooleanPref;
  99. import edu.mit.csail.sdg.alloy4.Util.IntPref;
  100. import edu.mit.csail.sdg.alloy4.Util.StringPref;
  101. import edu.mit.csail.sdg.alloy4.Version;
  102. import edu.mit.csail.sdg.alloy4.WorkerEngineCustom;
  103. import edu.mit.csail.sdg.alloy4.WorkerEngineCustom.WorkerCallbackCustom;
  104. import edu.mit.csail.sdg.alloy4.XMLNode;
  105. import edu.mit.csail.sdg.alloy4compiler.ast.Browsable;
  106. import edu.mit.csail.sdg.alloy4compiler.ast.Command;
  107. import edu.mit.csail.sdg.alloy4compiler.ast.Expr;
  108. import edu.mit.csail.sdg.alloy4compiler.ast.ExprVar;
  109. import edu.mit.csail.sdg.alloy4compiler.ast.Module;
  110. import edu.mit.csail.sdg.alloy4compiler.ast.Sig;
  111. import edu.mit.csail.sdg.alloy4compiler.ast.Sig.Field;
  112. import edu.mit.csail.sdg.alloy4compiler.parser.CompUtil;
  113. import edu.mit.csail.sdg.alloy4compiler.sim.SimInstance;
  114. import edu.mit.csail.sdg.alloy4compiler.sim.SimTuple;
  115. import edu.mit.csail.sdg.alloy4compiler.sim.SimTupleset;
  116. import edu.mit.csail.sdg.alloy4compiler.translator.A4Options;
  117. import edu.mit.csail.sdg.alloy4compiler.translator.A4Options.SatSolver;
  118. import edu.mit.csail.sdg.alloy4compiler.translator.A4Solution;
  119. import edu.mit.csail.sdg.alloy4compiler.translator.A4SolutionReader;
  120. import edu.mit.csail.sdg.alloy4compiler.translator.A4Tuple;
  121. import edu.mit.csail.sdg.alloy4compiler.translator.A4TupleSet;
  122. import edu.mit.csail.sdg.alloy4viz.VizGUICustom;
  123. import edu.mit.csail.sdg.alloy4whole.SimpleReporterCustom.SimpleCallback1;
  124. import edu.mit.csail.sdg.alloy4whole.SimpleReporterCustom.SimpleTask1;
  125. import edu.mit.csail.sdg.alloy4whole.SimpleReporterCustom.SimpleTask2;
  126. /** Simple graphical interface for accessing various features of the analyzer.
  127. *
  128. * <p> Except noted below, methods in this class can only be called by the AWT event thread.
  129. *
  130. * <p> The methods that might get called from other threads are:
  131. * <br> (1) the run() method in SatRunner is launched from a fresh thread
  132. * <br> (2) the run() method in the instance watcher (in constructor) is launched from a fresh thread
  133. */
  134. public final class SimpleGUICustom implements ComponentListener, Listener {
  135. /** The latest welcome screen; each time we update the welcome screen, we increment this number. */
  136. private static final int welcomeLevel = 2;
  137. // Verify that the graphics environment is set up
  138. static {
  139. try {
  140. GraphicsEnvironment.getLocalGraphicsEnvironment();
  141. } catch(Throwable ex) {
  142. System.err.println("Unable to start the graphical environment.");
  143. System.err.println("If you're on Mac OS X:");
  144. System.err.println(" Please make sure you are running as the current local user.");
  145. System.err.println("If you're on Linux or FreeBSD:");
  146. System.err.println(" Please make sure your X Windows is configured.");
  147. System.err.println(" You can verify this by typing \"xhost\"; it should not give an error message.");
  148. System.err.flush();
  149. /*System.exit(1);*/
  150. }
  151. }
  152. //======== The Preferences ======================================================================================//
  153. //======== Note: you must make sure each preference has a unique key ============================================//
  154. /** The list of allowable memory sizes. */
  155. private List<Integer> allowedMemorySizes;
  156. /** True if Alloy Analyzer should let warning be nonfatal. */
  157. private static final BooleanPref WarningNonfatal = new BooleanPref("WarningNonfatal");
  158. /** True if Alloy Analyzer should automatically visualize the latest instance. */
  159. private static final BooleanPref AutoVisualize = new BooleanPref("AutoVisualize");
  160. /** True if Alloy Analyzer should insist on antialias. */
  161. private static final BooleanPref AntiAlias = new BooleanPref("AntiAlias");
  162. /** True if Alloy Analyzer should record the raw Kodkod input and output. */
  163. private static final BooleanPref RecordKodkod = new BooleanPref("RecordKodkod");
  164. /** True if Alloy Analyzer should enable the new Implicit This name resolution. */
  165. private static final BooleanPref ImplicitThis = new BooleanPref("ImplicitThis");
  166. /** True if Alloy Analyzer should not report models that overflow. */
  167. private static final BooleanPref NoOverflow = new BooleanPref("NoOverflow");
  168. /** The latest X corrdinate of the Alloy Analyzer's main window. */
  169. private static final IntPref AnalyzerX = new IntPref("AnalyzerX",0,-1,65535);
  170. /** The latest Y corrdinate of the Alloy Analyzer's main window. */
  171. private static final IntPref AnalyzerY = new IntPref("AnalyzerY",0,-1,65535);
  172. /** The latest width of the Alloy Analyzer's main window. */
  173. private static final IntPref AnalyzerWidth = new IntPref("AnalyzerWidth",0,-1,65535);
  174. /** The latest height of the Alloy Analyzer's main window. */
  175. private static final IntPref AnalyzerHeight = new IntPref("AnalyzerHeight",0,-1,65535);
  176. /** The latest font size of the Alloy Analyzer. */
  177. private static final IntPref FontSize = new IntPref("FontSize",9,12,72);
  178. /** The latest font name of the Alloy Analyzer. */
  179. private static final StringPref FontName = new StringPref("FontName","Lucida Grande");
  180. /** The latest tab distance of the Alloy Analyzer. */
  181. private static final IntPref TabSize = new IntPref("TabSize",1,2,16);
  182. /** The latest welcome screen that the user has seen. */
  183. private static final IntPref Welcome = new IntPref("Welcome",0,0,1000);
  184. /** Whether syntax highlighting should be disabled or not. */
  185. private static final BooleanPref SyntaxDisabled = new BooleanPref("SyntaxHighlightingDisabled");
  186. /** The number of recursion unrolls. */
  187. private static final IntPref Unrolls = new IntPref("Unrolls", -1, -1, 3);
  188. /** The skolem depth. */
  189. private static final IntPref SkolemDepth = new IntPref("SkolemDepth3", 0, 1, 4);
  190. /** The unsat core minimization strategy. */
  191. private static final IntPref CoreMinimization = new IntPref("CoreMinimization",0,2,2);
  192. /** The unsat core granularity. */
  193. private static final IntPref CoreGranularity = new IntPref("CoreGranularity",0,0,3);
  194. /** The amount of memory (in M) to allocate for Kodkod and the SAT solvers. */
  195. private static final IntPref SubMemory = new IntPref("SubMemory",16,768,65535);
  196. /** The amount of stack (in K) to allocate for Kodkod and the SAT solvers. */
  197. private static final IntPref SubStack = new IntPref("SubStack",16,8192,65536);
  198. /** The first file in Alloy Analyzer's "open recent" list. */
  199. private static final StringPref Model0 = new StringPref("Model0");
  200. /** The second file in Alloy Analyzer's "open recent" list. */
  201. private static final StringPref Model1 = new StringPref("Model1");
  202. /** The third file in Alloy Analyzer's "open recent" list. */
  203. private static final StringPref Model2 = new StringPref("Model2");
  204. /** The fourth file in Alloy Analyzer's "open recent" list. */
  205. private static final StringPref Model3 = new StringPref("Model3");
  206. /** This enum defines the set of possible message verbosity levels. */
  207. private enum Verbosity {
  208. /** Level 0. */ DEFAULT("0", "low"),
  209. /** Level 1. */ VERBOSE("1", "medium"),
  210. /** Level 2. */ DEBUG("2", "high"),
  211. /** Level 3. */ FULLDEBUG("3", "debug only");
  212. /** Returns true if it is greater than or equal to "other". */
  213. @SuppressWarnings("unused")
  214. public boolean geq(Verbosity other) { return ordinal() >= other.ordinal(); }
  215. /** This is a unique String for this value; it should be kept consistent in future versions. */
  216. private final String id;
  217. /** This is the label that the toString() method will return. */
  218. private final String label;
  219. /** Constructs a new Verbosity value with the given id and label. */
  220. private Verbosity(String id, String label) { this.id=id; this.label=label; }
  221. /** Given an id, return the enum value corresponding to it (if there's no match, then return DEFAULT). */
  222. private static Verbosity parse(String id) {
  223. for(Verbosity vb: values()) if (vb.id.equals(id)) return vb;
  224. return DEFAULT;
  225. }
  226. /** Returns the human-readable label for this enum value. */
  227. @Override public final String toString() { return label; }
  228. /** Saves this value into the Java preference object. */
  229. private void set() { Preferences.userNodeForPackage(Util.class).put("Verbosity",id); }
  230. /** Reads the current value of the Java preference object (if it's not set, then return DEFAULT). */
  231. private static Verbosity get() { return parse(Preferences.userNodeForPackage(Util.class).get("Verbosity","")); }
  232. };
  233. //===================================================================================================//
  234. /** The JFrame for the main window. */
  235. public JFrame frame;
  236. /** The JFrame for the visualizer window. */
  237. private VizGUICustom viz;
  238. /** The "File", "Edit", "Run", "Option", "Window", and "Help" menus. */
  239. private JMenu filemenu, editmenu, runmenu, optmenu, windowmenu, windowmenu2, helpmenu;
  240. /** The toolbar. */
  241. private JToolBar toolbar;
  242. /** The various toolbar buttons. */
  243. private JButton runbutton, stopbutton, showbutton;
  244. /** The Splitpane. */
  245. private JSplitPane splitpane;
  246. /** The JLabel that displays the current line/column position, etc. */
  247. private JLabel status;
  248. /** Whether the editor has the focus, or the log window has the focus. */
  249. private boolean lastFocusIsOnEditor = true;
  250. /** The text editor. */
  251. private OurTabbedSyntaxWidget text;
  252. /** The "message panel" on the right. */
  253. private SwingLogPanelCustom log;
  254. /** The scrollpane containing the "message panel". */
  255. private JScrollPane logpane;
  256. /** The last "find" that the user issued. */
  257. private String lastFind = "";
  258. /** The last find is case-sensitive or not. */
  259. private boolean lastFindCaseSensitive = true;
  260. /** The last find is forward or not. */
  261. private boolean lastFindForward = true;
  262. /** The icon for a "checked" menu item. */
  263. private static final Icon iconYes = OurUtil.loadIcon("images/menu1.gif");
  264. /** The icon for an "unchecked" menu item. */
  265. private static final Icon iconNo = OurUtil.loadIcon("images/menu0.gif");
  266. /** The system-specific file separator (forward-slash on UNIX, back-slash on Windows, etc.) */
  267. private static final String fs = System.getProperty("file.separator");
  268. /** The darker background color (for the MessageLog window and the Toolbar and the Status Bar, etc.) */
  269. private static final Color background = new Color(0.9f, 0.9f, 0.9f);
  270. /** If subrunning==true: 0 means SAT solving; 1 means metamodel; 2 means enumeration. */
  271. private int subrunningTask = 0;
  272. /** The amount of memory (in MB) currently allocated for this.subprocess */
  273. private int subMemoryNow = 0;
  274. /** The amount of stack (in KB) currently allocated for this.subprocess */
  275. private int subStackNow = 0;
  276. /** The list of commands (this field will be cleared to null when the text buffer is edited). */
  277. private List<Command> commands = null;
  278. /** The latest executed command. */
  279. private int latestCommand = 0;
  280. /** The current choices of SAT solver. */
  281. private List<SatSolver> satChoices;
  282. /** The most recent Alloy version (as queried from alloy.mit.edu); -1 if alloy.mit.edu has not replied yet. */
  283. private int latestAlloyVersion = (-1);
  284. /** The most recent Alloy version name (as queried from alloy.mit.edu); "unknown" if alloy.mit.edu has not replied yet. */
  285. private String latestAlloyVersionName = "unknown";
  286. /** If it's not "", then it is the XML filename for the latest satisfying instance or the latest metamodel. */
  287. private String latestInstance = "";
  288. /** If it's not "", then it is the latest instance or metamodel during the most recent click of "Execute". */
  289. private String latestAutoInstance = "";
  290. /** If true, that means the event handlers should return a Runner encapsulating them, rather than perform the actual work. */
  291. private boolean wrap = false;
  292. //===================================================================================================//
  293. /** frame is visible. */
  294. public boolean isVisible=true;
  295. /** theme path. */
  296. public String themePath="";
  297. private boolean initialized=false;
  298. public boolean isInitialized() { return initialized; }
  299. public void setIsInitialized(boolean value) { initialized=value; }
  300. //====== helper methods =================================================//
  301. /** Inserts "filename" into the "recently opened file list". */
  302. private void addHistory(String filename) {
  303. String name0=Model0.get(), name1=Model1.get(), name2=Model2.get();
  304. if (name0.equals(filename)) return; else {Model0.set(filename); Model1.set(name0);}
  305. if (name1.equals(filename)) return; else Model2.set(name1);
  306. if (name2.equals(filename)) return; else Model3.set(name2);
  307. }
  308. /** Sets the flag "lastFocusIsOnEditor" to be true. */
  309. private Runner notifyFocusGained() {
  310. if (wrap) return wrapMe();
  311. lastFocusIsOnEditor=true;
  312. return null;
  313. }
  314. /** Sets the flag "lastFocusIsOnEditor" to be false. */
  315. void notifyFocusLost() { lastFocusIsOnEditor=false; }
  316. /** Updates the status bar at the bottom of the screen. */
  317. private Runner notifyChange() {
  318. if (wrap) return wrapMe();
  319. commands=null;
  320. if (text==null) return null; // If this was called prior to the "text" being fully initialized
  321. OurSyntaxWidget t = text.get();
  322. if (Util.onMac()) frame.getRootPane().putClientProperty("windowModified", Boolean.valueOf(t.modified()));
  323. if (t.isFile()) frame.setTitle(t.getFilename()); else frame.setTitle("Alloy Analyzer "+Version.version());
  324. toolbar.setBorder(new OurBorder(false, false, text.count()<=1, false));
  325. int c = t.getCaret();
  326. int y = t.getLineOfOffset(c)+1;
  327. int x = c - t.getLineStartOffset(y-1)+1;
  328. status.setText("<html>&nbsp; Line "+y+", Column "+x
  329. +(t.modified()?" <b style=\"color:#B43333;\">[modified]</b></html>":"</html>"));
  330. return null;
  331. }
  332. /** Helper method that returns a hopefully very short name for a file name. */
  333. public static String slightlyShorterFilename(String name) {
  334. if (name.toLowerCase(Locale.US).endsWith(".als")) {
  335. int i=name.lastIndexOf('/');
  336. if (i>=0) name=name.substring(i+1);
  337. i=name.lastIndexOf('\\');
  338. if (i>=0) name=name.substring(i+1);
  339. return name.substring(0, name.length()-4);
  340. } else if (name.toLowerCase(Locale.US).endsWith(".xml")) {
  341. int i=name.lastIndexOf('/');
  342. if (i>0) i=name.lastIndexOf('/', i-1);
  343. if (i>=0) name=name.substring(i+1);
  344. i=name.lastIndexOf('\\');
  345. if (i>0) i=name.lastIndexOf('\\', i-1);
  346. if (i>=0) name=name.substring(i+1);
  347. return name.substring(0, name.length()-4);
  348. }
  349. return name;
  350. }
  351. /** Copy the required files from the JAR into a temporary directory. */
  352. private void copyFromJAR() {
  353. // Compute the appropriate platform
  354. String os = System.getProperty("os.name").toLowerCase(Locale.US).replace(' ','-');
  355. if (os.startsWith("mac-")) os="mac"; else if (os.startsWith("windows-")) os="windows";
  356. String arch = System.getProperty("os.arch").toLowerCase(Locale.US).replace(' ','-');
  357. if (arch.equals("powerpc")) arch="ppc-"+os; else arch=arch.replaceAll("\\Ai[3456]86\\z","x86")+"-"+os;
  358. if (os.equals("mac")) arch="x86-mac"; // our pre-compiled binaries are all universal binaries
  359. // Find out the appropriate Alloy directory
  360. final String platformBinary = alloyHome() + fs + "binary";
  361. // Write a few test files
  362. try {
  363. (new File(platformBinary)).mkdirs();
  364. Util.writeAll(platformBinary + fs + "tmp.cnf", "p cnf 3 1\n1 0\n");
  365. } catch(Err er) {
  366. // The error will be caught later by the "berkmin" or "spear" test
  367. }
  368. // Copy the platform-dependent binaries
  369. Util.copy(true, false, platformBinary,
  370. arch+"/libminisat.so", arch+"/libminisatx1.so", arch+"/libminisat.jnilib",
  371. arch+"/libminisatprover.so", arch+"/libminisatproverx1.so", arch+"/libminisatprover.jnilib",
  372. arch+"/libzchaff.so", arch+"/libzchaffx1.so", arch+"/libzchaff.jnilib",
  373. arch+"/berkmin", arch+"/spear");
  374. Util.copy(false, false, platformBinary,
  375. arch+"/minisat.dll", arch+"/minisatprover.dll", arch+"/zchaff.dll",
  376. arch+"/berkmin.exe", arch+"/spear.exe");
  377. // Copy the model files
  378. Util.copy(false, true, alloyHome(),
  379. "models/book/appendixA/addressBook1.als", "models/book/appendixA/addressBook2.als", "models/book/appendixA/barbers.als",
  380. "models/book/appendixA/closure.als", "models/book/appendixA/distribution.als", "models/book/appendixA/phones.als",
  381. "models/book/appendixA/prison.als", "models/book/appendixA/properties.als", "models/book/appendixA/ring.als",
  382. "models/book/appendixA/spanning.als", "models/book/appendixA/tree.als", "models/book/appendixA/tube.als", "models/book/appendixA/undirected.als",
  383. "models/book/appendixE/hotel.thm", "models/book/appendixE/p300-hotel.als", "models/book/appendixE/p303-hotel.als", "models/book/appendixE/p306-hotel.als",
  384. "models/book/chapter2/addressBook1a.als", "models/book/chapter2/addressBook1b.als", "models/book/chapter2/addressBook1c.als",
  385. "models/book/chapter2/addressBook1d.als", "models/book/chapter2/addressBook1e.als", "models/book/chapter2/addressBook1f.als",
  386. "models/book/chapter2/addressBook1g.als", "models/book/chapter2/addressBook1h.als", "models/book/chapter2/addressBook2a.als",
  387. "models/book/chapter2/addressBook2b.als", "models/book/chapter2/addressBook2c.als", "models/book/chapter2/addressBook2d.als",
  388. "models/book/chapter2/addressBook2e.als", "models/book/chapter2/addressBook3a.als", "models/book/chapter2/addressBook3b.als",
  389. "models/book/chapter2/addressBook3c.als", "models/book/chapter2/addressBook3d.als", "models/book/chapter2/theme.thm",
  390. "models/book/chapter4/filesystem.als", "models/book/chapter4/grandpa1.als",
  391. "models/book/chapter4/grandpa2.als", "models/book/chapter4/grandpa3.als", "models/book/chapter4/lights.als",
  392. "models/book/chapter5/addressBook.als", "models/book/chapter5/lists.als", "models/book/chapter5/sets1.als", "models/book/chapter5/sets2.als",
  393. "models/book/chapter6/hotel.thm", "models/book/chapter6/hotel1.als", "models/book/chapter6/hotel2.als",
  394. "models/book/chapter6/hotel3.als", "models/book/chapter6/hotel4.als", "models/book/chapter6/mediaAssets.als",
  395. "models/book/chapter6/memory/abstractMemory.als", "models/book/chapter6/memory/cacheMemory.als",
  396. "models/book/chapter6/memory/checkCache.als", "models/book/chapter6/memory/checkFixedSize.als",
  397. "models/book/chapter6/memory/fixedSizeMemory.als", "models/book/chapter6/memory/fixedSizeMemory_H.als",
  398. "models/book/chapter6/ringElection.thm", "models/book/chapter6/ringElection1.als", "models/book/chapter6/ringElection2.als",
  399. "models/examples/algorithms/dijkstra.als", "models/examples/algorithms/dijkstra.thm",
  400. "models/examples/algorithms/messaging.als", "models/examples/algorithms/messaging.thm",
  401. "models/examples/algorithms/opt_spantree.als", "models/examples/algorithms/opt_spantree.thm",
  402. "models/examples/algorithms/peterson.als",
  403. "models/examples/algorithms/ringlead.als", "models/examples/algorithms/ringlead.thm",
  404. "models/examples/algorithms/s_ringlead.als",
  405. "models/examples/algorithms/stable_mutex_ring.als", "models/examples/algorithms/stable_mutex_ring.thm",
  406. "models/examples/algorithms/stable_orient_ring.als", "models/examples/algorithms/stable_orient_ring.thm",
  407. "models/examples/algorithms/stable_ringlead.als", "models/examples/algorithms/stable_ringlead.thm",
  408. "models/examples/case_studies/INSLabel.als", "models/examples/case_studies/chord.als",
  409. "models/examples/case_studies/chord2.als", "models/examples/case_studies/chordbugmodel.als",
  410. "models/examples/case_studies/com.als", "models/examples/case_studies/firewire.als", "models/examples/case_studies/firewire.thm",
  411. "models/examples/case_studies/ins.als", "models/examples/case_studies/iolus.als",
  412. "models/examples/case_studies/sync.als", "models/examples/case_studies/syncimpl.als",
  413. "models/examples/puzzles/farmer.als", "models/examples/puzzles/farmer.thm",
  414. "models/examples/puzzles/handshake.als", "models/examples/puzzles/handshake.thm",
  415. "models/examples/puzzles/hanoi.als", "models/examples/puzzles/hanoi.thm",
  416. "models/examples/systems/file_system.als", "models/examples/systems/file_system.thm",
  417. "models/examples/systems/javatypes_soundness.als",
  418. "models/examples/systems/lists.als", "models/examples/systems/lists.thm",
  419. "models/examples/systems/marksweepgc.als", "models/examples/systems/views.als",
  420. "models/examples/toys/birthday.als", "models/examples/toys/birthday.thm",
  421. "models/examples/toys/ceilingsAndFloors.als", "models/examples/toys/ceilingsAndFloors.thm",
  422. "models/examples/toys/genealogy.als", "models/examples/toys/genealogy.thm",
  423. "models/examples/toys/grandpa.als", "models/examples/toys/grandpa.thm",
  424. "models/examples/toys/javatypes.als", "models/examples/toys/life.als", "models/examples/toys/life.thm",
  425. "models/examples/toys/numbering.als", "models/examples/toys/railway.als", "models/examples/toys/railway.thm",
  426. "models/examples/toys/trivial.als",
  427. "models/examples/tutorial/farmer.als",
  428. "models/util/boolean.als", "models/util/graph.als", "models/util/integer.als", "models/util/natural.als",
  429. "models/util/ordering.als", "models/util/relation.als", "models/util/seqrel.als", "models/util/sequence.als",
  430. "models/util/sequniv.als", "models/util/ternary.als", "models/util/time.als"
  431. );
  432. // Record the locations
  433. System.setProperty("alloy.theme0", alloyHome() + fs + "models");
  434. System.setProperty("alloy.home", alloyHome());
  435. }
  436. /** Called when this window is resized. */
  437. public void componentResized(ComponentEvent e) {
  438. componentMoved(e);
  439. }
  440. /** Called when this window is moved. */
  441. public void componentMoved(ComponentEvent e) {
  442. AnalyzerWidth.set(frame.getWidth());
  443. AnalyzerHeight.set(frame.getHeight());
  444. AnalyzerX.set(frame.getX());
  445. AnalyzerY.set(frame.getY());
  446. }
  447. /** Called when this window is shown. */
  448. public void componentShown(ComponentEvent e) {}
  449. /** Called when this window is hidden. */
  450. public void componentHidden(ComponentEvent e) {}
  451. /** Wraps the calling method into a Runnable whose run() will call the calling method with (false) as the only argument. */
  452. private Runner wrapMe() {
  453. final String name;
  454. try { throw new Exception(); } catch(Exception ex) { name = ex.getStackTrace()[1].getMethodName(); }
  455. Method[] methods = getClass().getDeclaredMethods();
  456. Method m=null;
  457. for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(name)) { m=methods[i]; break; }
  458. final Method method=m;
  459. return new Runner() {
  460. private static final long serialVersionUID = 0;
  461. public void run() {
  462. try {
  463. method.setAccessible(true);
  464. method.invoke(SimpleGUICustom.this, new Object[]{});
  465. } catch (Throwable ex) {
  466. ex = new IllegalArgumentException("Failed call to "+name+"()", ex);
  467. Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), ex);
  468. }
  469. }
  470. public void run(Object arg) { run(); }
  471. };
  472. }
  473. /** Wraps the calling method into a Runnable whose run() will call the calling method with (false,argument) as the two arguments. */
  474. private Runner wrapMe(final Object argument) {
  475. final String name;
  476. try { throw new Exception(); } catch(Exception ex) { name = ex.getStackTrace()[1].getMethodName(); }
  477. Method[] methods = getClass().getDeclaredMethods();
  478. Method m=null;
  479. for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(name)) { m=methods[i]; break; }
  480. final Method method=m;
  481. return new Runner() {
  482. private static final long serialVersionUID = 0;
  483. public void run(Object arg) {
  484. try {
  485. method.setAccessible(true);
  486. method.invoke(SimpleGUICustom.this, new Object[]{arg});
  487. } catch (Throwable ex) {
  488. ex = new IllegalArgumentException("Failed call to "+name+"("+arg+")", ex);
  489. Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), ex);
  490. }
  491. }
  492. public void run() { run(argument); }
  493. };
  494. }
  495. /** This variable caches the result of alloyHome() function call. */
  496. private static String alloyHome = null;
  497. /** Find a temporary directory to store Alloy files; it's guaranteed to be a canonical absolute path. */
  498. private static synchronized String alloyHome() {
  499. if (alloyHome!=null) return alloyHome;
  500. String temp=System.getProperty("java.io.tmpdir");
  501. if (temp==null || temp.length()==0)
  502. OurDialog.fatal("Error. JVM need to specify a temporary directory using java.io.tmpdir property.");
  503. String username=System.getProperty("user.name");
  504. File tempfile=new File(temp+File.separatorChar+"alloy4tmp40-"+(username==null?"":username));
  505. tempfile.mkdirs();
  506. String ans=Util.canon(tempfile.getPath());
  507. if (!tempfile.isDirectory()) {
  508. OurDialog.fatal("Error. Cannot create the temporary directory "+ans);
  509. }
  510. if (!Util.onWindows()) {
  511. String[] args={"chmod", "700", ans};
  512. try {Runtime.getRuntime().exec(args).waitFor();}
  513. catch (Throwable ex) {} // We only intend to make a best effort.
  514. }
  515. return alloyHome=ans;
  516. }
  517. /** Create an empty temporary directory for use, designate it "deleteOnExit", then return it.
  518. * It is guaranteed to be a canonical absolute path. */
  519. private static String maketemp() {
  520. Random r=new Random(new Date().getTime());
  521. while(true) {
  522. int i=r.nextInt(1000000);
  523. String dest = alloyHome()+File.separatorChar+"tmp"+File.separatorChar+i;
  524. File f=new File(dest);
  525. if (f.mkdirs()) {
  526. f.deleteOnExit();
  527. return Util.canon(dest);
  528. }
  529. }
  530. }
  531. /** Return the number of bytes used by the Temporary Directory (or return -1 if the answer exceeds "long") */
  532. private static long computeTemporarySpaceUsed() {
  533. long ans = iterateTemp(null,false);
  534. if (ans<0) return -1; else return ans;
  535. }
  536. /** Delete every file in the Temporary Directory. */
  537. private static void clearTemporarySpace() {
  538. iterateTemp(null,true);
  539. // Also clear the temp dir from previous versions of Alloy4
  540. String temp=System.getProperty("java.io.tmpdir");
  541. if (temp==null || temp.length()==0) return;
  542. String username=System.getProperty("user.name");
  543. if (username==null) username="";
  544. for(int i=1; i<40; i++) iterateTemp(temp+File.separatorChar+"alloy4tmp"+i+"-"+username, true);
  545. }
  546. /** Helper method for performing either computeTemporarySpaceUsed() or clearTemporarySpace() */
  547. private static long iterateTemp(String filename, boolean delete) {
  548. long ans=0;
  549. if (filename==null) filename = alloyHome()+File.separatorChar+"tmp";
  550. File x = new File(filename);
  551. if (x.isDirectory()) {
  552. for(String subfile:x.list()) {
  553. long tmp=iterateTemp(filename+File.separatorChar+subfile, delete);
  554. if (ans>=0) ans=ans+tmp;
  555. }
  556. }
  557. else if (x.isFile()) {
  558. long tmp=x.length();
  559. if (ans>=0) ans=ans+tmp;
  560. }
  561. if (delete) x.delete();
  562. return ans;
  563. }
  564. //===============================================================================================================//
  565. /** This method refreshes the "file" menu. */
  566. private Runner doRefreshFile() {
  567. if (wrap) return wrapMe();
  568. try {
  569. wrap = true;
  570. filemenu.removeAll();
  571. menuItem(filemenu, "New", 'N', 'N', doNew());
  572. menuItem(filemenu, "Open...", 'O', 'O', doOpen());
  573. if (!Util.onMac())
  574. menuItem(filemenu, "Open Sample Models...", VK_ALT, 'O', doBuiltin());
  575. else
  576. menuItem(filemenu, "Open Sample Models...", doBuiltin());
  577. JMenu recentmenu;
  578. filemenu.add(recentmenu = new JMenu("Open Recent"));
  579. menuItem(filemenu, "Reload all", 'R', 'R', doReloadAll());
  580. menuItem(filemenu, "Save", 'S', 'S', doSave());
  581. if (Util.onMac())
  582. menuItem(filemenu, "Save As...", VK_SHIFT, 'S', doSaveAs());
  583. else
  584. menuItem(filemenu, "Save As...", 'A', doSaveAs());
  585. menuItem(filemenu, "Close", 'W', 'W', doClose());
  586. menuItem(filemenu, "Clear Temporary Directory", doClearTemp());
  587. menuItem(filemenu, "Quit", 'Q', (Util.onMac() ? -1 : 'Q'), doQuit());
  588. boolean found = false;
  589. for(Util.StringPref p: new Util.StringPref[]{ Model0, Model1, Model2, Model3 }) {
  590. String name = p.get();
  591. if (name.length()>0) { found = true; menuItem(recentmenu, name, doOpenFile(name)); }
  592. }
  593. recentmenu.addSeparator();
  594. menuItem(recentmenu, "Clear Menu", doClearRecent());
  595. recentmenu.setEnabled(found);
  596. } finally {
  597. wrap = false;
  598. }
  599. return null;
  600. }
  601. /** This method performs File->New. */
  602. public Runner doNew() {
  603. if (!wrap) { text.newtab(null); notifyChange(); doShow(); }
  604. return wrapMe();
  605. }
  606. /** This method performs File->Open. */
  607. public Runner doOpen() {
  608. if (wrap) return wrapMe();
  609. File file=OurDialog.askFile(true, null, ".als", ".als files");
  610. if (file!=null) {
  611. Util.setCurrentDirectory(file.getParentFile());
  612. doOpenFile(file.getPath());
  613. }
  614. return null;
  615. }
  616. /** This method performs File->OpenBuiltinModels. */
  617. public Runner doBuiltin() {
  618. if (wrap) return wrapMe();
  619. File file=OurDialog.askFile(true, alloyHome() + fs + "models", ".als", ".als files");
  620. if (file!=null) {
  621. doOpenFile(file.getPath());
  622. }
  623. return null;
  624. }
  625. /** This method performs File->ReloadAll. */
  626. public Runner doReloadAll() {
  627. if (!wrap) text.reloadAll();
  628. return wrapMe();
  629. }
  630. /** This method performs File->ClearRecentFiles. */
  631. public Runner doClearRecent() {
  632. if (!wrap) { Model0.set(""); Model1.set(""); Model2.set(""); Model3.set(""); }
  633. return wrapMe();
  634. }
  635. /** This method performs File->Save. */
  636. public Runner doSave() {
  637. if (!wrap) {
  638. String ans = text.save(false);
  639. if (ans==null) return null;
  640. notifyChange();
  641. addHistory(ans);
  642. log.clearError();
  643. }
  644. return wrapMe();
  645. }
  646. /** This method performs File->SaveAs. */
  647. public Runner doSaveAs() {
  648. if (!wrap) {
  649. String ans = text.save(true);
  650. if (ans==null) return null;
  651. notifyChange();
  652. addHistory(ans);
  653. log.clearError();
  654. }
  655. return wrapMe();
  656. }
  657. /** This method clears the temporary files and then reinitialize the temporary directory. */
  658. public Runner doClearTemp() {
  659. if (!wrap) {
  660. clearTemporarySpace();
  661. copyFromJAR();
  662. log.logBold("Temporary directory has been cleared.\n\n");
  663. log.logDivider();
  664. log.flush();
  665. }
  666. return wrapMe();
  667. }
  668. /** This method performs File->Close. */
  669. public Runner doClose() {
  670. if (!wrap) text.close();
  671. return wrapMe();
  672. }
  673. /** This method performs File->Quit. */
  674. public Runner doQuit() {
  675. if (!wrap) if (text.closeAll()) {
  676. try { WorkerEngineCustom.stop(); } finally { }
  677. }
  678. return wrapMe();
  679. }
  680. //===============================================================================================================//
  681. /** This method refreshes the "edit" menu. */
  682. private Runner doRefreshEdit() {
  683. if (wrap) return wrapMe();
  684. try {
  685. wrap = true;
  686. boolean canUndo = text.get().canUndo();
  687. boolean canRedo = text.get().canRedo();
  688. editmenu.removeAll();
  689. menuItem(editmenu, "Undo", 'Z', 'Z', doUndo(), canUndo);
  690. if (Util.onMac())
  691. menuItem(editmenu, "Redo", VK_SHIFT, 'Z', doRedo(), canRedo);
  692. else
  693. menuItem(editmenu, "Redo", 'Y', 'Y', doRedo(), canRedo);
  694. editmenu.addSeparator();
  695. menuItem(editmenu, "Cut", 'X', 'X', doCut());
  696. menuItem(editmenu, "Copy", 'C', 'C', doCopy());
  697. menuItem(editmenu, "Paste", 'V', 'V', doPaste());
  698. editmenu.addSeparator();
  699. menuItem(editmenu, "Go To..." , 'T', 'T', doGoto());
  700. menuItem(editmenu, "Previous File" , VK_PAGE_UP, VK_PAGE_UP, doGotoPrevFile(), text.count()>1);
  701. menuItem(editmenu, "Next File" , VK_PAGE_DOWN, VK_PAGE_DOWN, doGotoNextFile(), text.count()>1);
  702. editmenu.addSeparator();
  703. menuItem(editmenu, "Find...", 'F', 'F', doFind());
  704. menuItem(editmenu, "Find Next", 'G', 'G', doFindNext());
  705. } finally {
  706. wrap = false;
  707. }
  708. return null;
  709. }
  710. /** This method performs Edit->Undo. */
  711. public Runner doUndo() {
  712. if (!wrap) text.get().undo();
  713. return wrapMe();
  714. }
  715. /** This method performs Edit->Redo. */
  716. public Runner doRedo() {
  717. if (!wrap) text.get().redo();
  718. return wrapMe();
  719. }
  720. /** This method performs Edit->Copy. */
  721. public Runner doCopy() {
  722. if (!wrap) { if (lastFocusIsOnEditor) text.get().copy(); else log.copy(); }
  723. return wrapMe();
  724. }
  725. /** This method performs Edit->Cut. */
  726. public Runner doCut() {
  727. if (!wrap && lastFocusIsOnEditor) text.get().cut();
  728. return wrapMe();
  729. }
  730. /** This method performs Edit->Paste. */
  731. public Runner doPaste() {
  732. if (!wrap && lastFocusIsOnEditor) text.get().paste();
  733. return wrapMe();
  734. }
  735. /** This method performs Edit->Find. */
  736. public Runner doFind() {
  737. if (wrap) return wrapMe();
  738. JTextField x = OurUtil.textfield(lastFind,30);
  739. x.selectAll();
  740. JCheckBox c = new JCheckBox("Case Sensitive?",lastFindCaseSensitive);
  741. c.setMnemonic('c');
  742. JCheckBox b = new JCheckBox("Search Backward?",!lastFindForward);
  743. b.setMnemonic('b');
  744. if (!OurDialog.getInput("Find", "Text:", x, " ", c, b)) return null;
  745. if (x.getText().length() == 0) return null;
  746. lastFind = x.getText();
  747. lastFindCaseSensitive = c.getModel().isSelected();
  748. lastFindForward = !b.getModel().isSelected();
  749. doFindNext();
  750. return null;
  751. }
  752. /** This method performs Edit->FindNext. */
  753. public Runner doFindNext() {
  754. if (wrap) return wrapMe();
  755. if (lastFind.length()==0) return null;
  756. OurSyntaxWidget t = text.get();
  757. String all = t.getText();
  758. int i = Util.indexOf(all, lastFind, t.getCaret()+(lastFindForward?0:-1),lastFindForward,lastFindCaseSensitive);
  759. if (i<0) {
  760. i=Util.indexOf(all, lastFind, lastFindForward?0:(all.length()-1), lastFindForward, lastFindCaseSensitive);
  761. if (i<0) { log.logRed("The specified search string cannot be found."); return null; }
  762. log.logRed("Search wrapped.");
  763. } else {
  764. log.clearError();
  765. }
  766. if (lastFindForward) t.moveCaret(i, i+lastFind.length()); else t.moveCaret(i+lastFind.length(), i);
  767. t.requestFocusInWindow();
  768. return null;
  769. }
  770. /** This method performs Edit->Goto. */
  771. public Runner doGoto() {
  772. if (wrap) return wrapMe();
  773. JTextField y = OurUtil.textfield("", 10);
  774. JTextField x = OurUtil.textfield("", 10);
  775. if (!OurDialog.getInput("Go To", "Line Number:", y, "Column Number (optional):", x)) return null;
  776. try {
  777. OurSyntaxWidget t = text.get();
  778. int xx = 1, yy = Integer.parseInt(y.getText()), lineCount = t.getLineCount();
  779. if (yy<1) return null;
  780. if (yy>lineCount) {log.logRed("This file only has "+lineCount+" line(s)."); return null;}
  781. if (x.getText().length()!=0) xx=Integer.parseInt(x.getText());
  782. if (xx<1) {log.logRed("If the column number is specified, it must be 1 or greater."); return null;}
  783. int caret = t.getLineStartOffset(yy-1);
  784. int len = (yy==lineCount ? t.getText().length()+1 : t.getLineStartOffset(yy)) - caret;
  785. if (xx>len) xx=len;
  786. if (xx<1) xx=1;
  787. t.moveCaret(caret+xx-1, caret+xx-1);
  788. t.requestFocusInWindow();
  789. } catch(NumberFormatException ex) {
  790. log.logRed("The number must be 1 or greater.");
  791. } catch(Throwable ex) {
  792. // This error is not important
  793. }
  794. return null;
  795. }
  796. /** This method performs Edit->GotoPrevFile. */
  797. public Runner doGotoPrevFile() {
  798. if (wrap) return wrapMe(); else {text.prev(); return null;}
  799. }
  800. /** This method performs Edit->GotoNextFile. */
  801. public Runner doGotoNextFile() {
  802. if (wrap) return wrapMe(); else {text.next(); return null;}
  803. }
  804. //===============================================================================================================//
  805. /** This method refreshes the "run" menu. */
  806. public Runner doRefreshRun() {
  807. if (wrap) return wrapMe();
  808. KeyStroke ac = KeyStroke.getKeyStroke(VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
  809. try {
  810. wrap = true;
  811. runmenu.removeAll();
  812. menuItem(runmenu, "Execute Latest Command", 'E', 'E', doExecuteLatest());
  813. runmenu.add(new JSeparator());
  814. menuItem(runmenu, "Show Latest Instance", 'L', 'L', doShowLatest(), latestInstance.length()>0);
  815. menuItem(runmenu, "Show Metamodel", 'M', 'M', doShowMetaModel());
  816. if (Version.experimental) menuItem(runmenu, "Show Parse Tree", 'P', doShowParseTree());
  817. menuItem(runmenu, "Open Evaluator", 'V', doLoadEvaluator());
  818. } finally {
  819. wrap = false;
  820. }
  821. List<Command> cp = commands;
  822. if (cp==null) {
  823. try {
  824. cp=CompUtil.parseOneModule_fromString(text.get().getText());
  825. }
  826. catch(Err e) {
  827. commands = null;
  828. runmenu.getItem(0).setEnabled(false);
  829. runmenu.getItem(3).setEnabled(false);
  830. text.shade(new Pos(text.get().getFilename(), e.pos.x, e.pos.y, e.pos.x2, e.pos.y2));
  831. if ("yes".equals(System.getProperty("debug")) && Verbosity.get()==Verbosity.FULLDEBUG)
  832. log.logRed("Fatal Exception!" + e.dump() + "\n\n");
  833. else
  834. log.logRed(e.toString()+"\n\n");
  835. return null;
  836. }
  837. catch(Throwable e) {
  838. commands = null;
  839. runmenu.getItem(0).setEnabled(false);
  840. runmenu.getItem(3).setEnabled(false);
  841. log.logRed("Cannot parse the model.\n"+e.toString()+"\n\n");
  842. return null;
  843. }
  844. commands=cp;
  845. }
  846. text.clearShade();
  847. log.clearError(); // To clear any residual error message
  848. if (cp==null) { runmenu.getItem(0).setEnabled(false); runmenu.getItem(3).setEnabled(false); return null; }
  849. if (cp.size()==0) { runmenu.getItem(0).setEnabled(false); return null; }
  850. if (latestCommand>=cp.size()) latestCommand=cp.size()-1;
  851. runmenu.remove(0);
  852. try {
  853. wrap = true;
  854. for(int i=0; i<cp.size(); i++) {
  855. JMenuItem y = new JMenuItem(cp.get(i).toString(), null);
  856. y.addActionListener(doRun(i));
  857. if (i==latestCommand) { y.setMnemonic(VK_E); y.setAccelerator(ac); }
  858. runmenu.add(y,i);
  859. }
  860. if (cp.size()>=2) {
  861. JMenuItem y = new JMenuItem("Execute All", null);
  862. y.setMnemonic(VK_A);
  863. y.addActionListener(doRun(-1));
  864. runmenu.add(y,0);
  865. runmenu.add(new JSeparator(),1);
  866. }
  867. } finally {
  868. wrap = false;
  869. }
  870. return null;
  871. }
  872. /** This method executes a particular RUN or CHECK command. */
  873. public Runner doRun(Integer commandIndex) {
  874. if (wrap) return wrapMe(commandIndex);
  875. final int index = commandIndex;
  876. if (WorkerEngineCustom.isBusy()) return null;
  877. if (index==(-2)) subrunningTask=1; else subrunningTask=0;
  878. latestAutoInstance="";
  879. if (index>=0) latestCommand=index;
  880. if (index==-1 && commands!=null) {
  881. latestCommand=commands.size()-1;
  882. if (latestCommand<0) latestCommand=0;
  883. }
  884. // To update the accelerator to point to the command actually chosen
  885. doRefreshRun();
  886. OurUtil.enableAll(runmenu);
  887. if (commands==null) return null;
  888. if (commands.size()==0 && index!=-2 && index!=-3) { log.logRed("There are no commands to execute.\n\n"); return null; }
  889. int i=index;
  890. if (i>=commands.size()) i=commands.size()-1;
  891. SimpleCallback1 cb = new SimpleCallback1(this, null, log, Verbosity.get().ordinal(), latestAlloyVersionName, latestAlloyVersion);
  892. SimpleTask1 task = new SimpleTask1();
  893. A4Options opt = new A4Options();
  894. opt.tempDirectory = alloyHome() + fs + "tmp";
  895. opt.solverDirectory = alloyHome() + fs + "binary";
  896. opt.recordKodkod = RecordKodkod.get();
  897. opt.noOverflow = NoOverflow.get();
  898. opt.unrolls = Version.experimental ? Unrolls.get() : (-1);
  899. opt.skolemDepth = SkolemDepth.get();
  900. opt.coreMinimization = CoreMinimization.get();
  901. opt.coreGranularity = CoreGranularity.get();
  902. opt.originalFilename = Util.canon(text.get().getFilename());
  903. opt.solver = SatSolver.get();
  904. task.bundleIndex = i;
  905. task.bundleWarningNonFatal = WarningNonfatal.get();
  906. task.map = text.takeSnapshot();
  907. task.options = opt.dup();
  908. task.resolutionMode = (Version.experimental && ImplicitThis.get()) ? 2 : 1;
  909. task.tempdir = maketemp();
  910. try {
  911. runmenu.setEnabled(false);
  912. runbutton.setVisible(false);
  913. showbutton.setEnabled(false);
  914. stopbutton.setVisible(true);
  915. int newmem = SubMemory.get(), newstack = SubStack.get();
  916. if (newmem != subMemoryNow || newstack != subStackNow) WorkerEngineCustom.stop();
  917. if ("yes".equals(System.getProperty("debug")) && Verbosity.get()==Verbosity.FULLDEBUG)
  918. WorkerEngineCustom.runLocally(task, cb);
  919. else
  920. WorkerEngineCustom.run(task, newmem, newstack, alloyHome() + fs + "binary", "", cb);
  921. subMemoryNow = newmem;
  922. subStackNow = newstack;
  923. } catch(Throwable ex) {
  924. WorkerEngineCustom.stop();
  925. log.logBold("Fatal Error: Solver failed due to unknown reason.\n" +
  926. "One possible cause is that, in the Options menu, your specified\n" +
  927. "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