Minsky: 3.17.0
minsky.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2012
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef MINSKY_H
21 #define MINSKY_H
22 
23 #include "stringKeyMap.h"
24 #include "intrusiveMap.h"
25 #include "bookmark.h"
26 #include "cairoItems.h"
27 #include "canvas.h"
28 #include "clipboard.h"
29 #include "dimension.h"
30 #include "evalOp.h"
31 #include "equationDisplay.h"
32 #include "equations.h"
33 #include "fontDisplay.h"
34 #include "godleyIcon.h"
35 #include "intrusiveMap.h"
36 #include "latexMarkup.h"
37 #include "variableValues.h"
38 #include "canvas.h"
39 #include "lock.h"
40 #include "operation.h"
41 #include "pannableTab.h"
42 #include "phillipsDiagram.h"
43 #include "plotWidget.h"
44 #include "progress.h"
45 #include "pubTab.h"
46 #include "ravelWrap.h"
47 #include "rungeKutta.h"
48 #include "saver.h"
49 #include "stringKeyMap.h"
50 #include "variablePane.h"
51 #include "version.h"
52 
53 #include <vector>
54 #include <string>
55 #include <set>
56 #include <deque>
57 #include <cstdio>
58 
59 namespace minsky
60 {
61  using namespace std;
62  using classdesc::shared_ptr;
63  using namespace civita;
64  using namespace boost::posix_time;
65 
66  struct CallableFunction;
67  class VariableInstanceList;
68 
69  class SaveThread;
70 
71  // a place to put working variables of the Minsky class that needn't
72  // be serialised.
74  {
75  shared_ptr<ofstream> outputDataFile;
76  unique_ptr<BackgroundSaver> autoSaver;
77 
78  enum StateFlags {is_edited=1, reset_needed=2, fullEqnDisplay_needed=4};
79  int flags=reset_needed;
80 
82  static constexpr std::chrono::milliseconds resetNowThreshold{500};
85  static constexpr std::chrono::milliseconds resetPostponedThreshold{1500};
86  std::chrono::time_point<std::chrono::system_clock> resetAt=std::chrono::time_point<std::chrono::system_clock>::max();
87  std::chrono::milliseconds resetDuration;
88 
90  int busyCursorStack=0;
91 
92  std::vector<int> flagStack;
93 
95 
96  // make copy operations just dummies, as assignment of Minsky's
97  // doesn't need to change this
98  MinskyExclude(): historyPtr(0) {}
99  MinskyExclude(const MinskyExclude&): historyPtr(0) {}
100  MinskyExclude& operator=(const MinskyExclude&) {return *this;}
101 
103  std::set<RenderNativeWindow*> nativeWindowsToRedraw;
104 
105  protected:
107  /*
108  TODO: it should be sufficient to add move semantics to pack_t,
109  but for some reason copy semantics are required, requiring the
110  use of shared_ptr
111  */
112  std::deque<classdesc::pack_t> history;
113  std::size_t historyPtr;
114  bool undone=false; //< flag indicating undo() was previous command
115  };
116 
118 
119  class Minsky: public Exclude<MinskyExclude>, public RungeKutta
120  {
122 
125  std::string diagnoseNonFinite() const;
126 
128  void logVariables() const;
129 
130  Exclude<ptime> lastRedraw;
131 
132  bool m_multipleEquities=false;
133 
135  void balanceColumns(const GodleyIcon& srcGodley, int srcCol, GodleyIcon& destGodley, int destCol) const;
136 
138  void removeItems(Wire& wire);
139 
140  public:
144  std::vector<PubTab> publicationTabs;
145 
146  void addNewPublicationTab(const std::string& name) {publicationTabs.emplace_back(name);}
148  if (canvas.item && i<publicationTabs.size())
149  publicationTabs[i].items.emplace_back(canvas.item);
150  }
151 
152  // Allow multiple equity columns.
153  bool multipleEquities() const {return m_multipleEquities;}
154  bool multipleEquities(const bool& m);
155 
157  bool edited() const {return flags & is_edited;}
159  bool reset_flag() const {return flags & reset_needed;}
161  void markEdited() {
162  flags |= is_edited | fullEqnDisplay_needed;
163  if (!running) flags|=reset_needed; // don't reset when running
164  variablePane.update();
165  canvas.requestRedraw();
166  canvas.model.updateTimestamp();
167  }
168  void requestReset();
170  void requestRedraw();
171 
173  void pushFlags() {flagStack.push_back(flags);}
174  void popFlags() {
175  if (!flagStack.empty()) {
176  flags=flagStack.back();
177  flagStack.pop_back();
178  }
179  }
181 
182  bool resetIfFlagged() override {
183  if (reset_flag())
184  reset();
185  return reset_flag();
186  }
187 
189  Dimensions dimensions;
190  Conversions conversions;
192  std::map<Units, double> maxValue;
193  std::map<Units, double> maxFlowValue; // max flow values along wires
195  void populateMissingDimensions();
198  void populateMissingDimensionsFromVariable(const VariableValue&, bool& incompatibleMessageDisplayed);
200  {bool dummy; populateMissingDimensionsFromVariable(v,dummy);}
201  void renameDimension(const std::string& oldName, const std::string& newName);
202 
203  void setGodleyIconResource(const string& s)
205  void setGroupIconResource(const string& s)
207  void setLockIconResource(const string& locked, const string& unlocked) {
210  }
211  void setRavelIconResource(const string& s)
214 
217  // @param ac type of column we wish matches for
218  std::set<string> matchingTableColumns(const GodleyIcon& currTable, GodleyAssetClass::AssetClass ac);
219 
221  void importDuplicateColumn(GodleyTable& srcTable, int srcCol);
222 
224  void balanceDuplicateColumns(const GodleyIcon& srcTable, int srcCol);
225 
226  std::vector<std::string> allGodleyFlowVars() const;
227 
228  // reset m_edited as the GodleyIcon constructor calls markEdited
230  equationDisplay(*this) {
231  lastRedraw=boost::posix_time::microsec_clock::local_time();
232  model->iHeight(std::numeric_limits<float>::max());
233  model->iWidth(std::numeric_limits<float>::max());
234  model->self=model;
235  publicationTabs.emplace_back("Publication");
236  }
237  ~Minsky();
238 
239  // needs to be declared after variableValues
240  Exclude<std::map<std::string, std::shared_ptr<CallableFunction>>> userFunctions;
241 
242  GroupPtr model{new Group};
243  Canvas canvas{model};
244 
245  void clearAllMaps(bool clearHistory);
246  void clearAllMaps() {clearAllMaps(true);}
247  // for TCL use
248  void clearAllMapsTCL() {clearAllMaps(true);}
249 
251  VariablePtr definingVar(const std::string& valueId) const;
252 
253  static void saveGroupAsFile(const Group&, const string& fileName);
254  void saveCanvasItemAsFile(const string& fileName) const
255  {if (auto g=dynamic_cast<Group*>(canvas.item.get())) saveGroupAsFile(*g,fileName);}
256 
257  void initGodleys();
258 
260  void cut();
262  void copy() const;
265  void paste();
267  bool clipboardEmpty() const {return clipboard.getClipboard().empty();}
268  void saveSelectionAsFile(const string& fileName) const {saveGroupAsFile(canvas.selection,fileName);}
269 
270  void insertGroupFromFile(const string& file);
271 
272  void makeVariablesConsistent();
273 
274  void imposeDimensions();
275 
276  // runs over all ports and variables removing those not in use
277  void garbageCollect();
278 
281  bool cycleCheck() const;
282 
285  void openLogFile(const string&);
287  void closeLogFile() {outputDataFile.reset();}
289  std::set<string> logVarList;
291  bool loggingEnabled() const {return outputDataFile.get();}
292 
295  void constructEquations();
297  void dimensionalAnalysis() const;
299  void deleteAllUnits();
300 
304  bool checkEquationOrder() const;
305 
306 
307  double lastT{0};
308  double deltaT() const {return t-lastT;}
309  void reset();
310  std::vector<double> step();
311 
312  int numBackups=1;
313  void save(const std::string& filename);
316  void load(const std::string& filename);
317 
318  static void exportSchema(const std::string& filename, int schemaLevel=1);
319 
321  void displayErrorItem(const Item& op) const;
322 
323  static const std::string minskyVersion;
324  static std::string ecolabVersion() {return VERSION;}
325  static std::string ravelVersion() {
326  if (ravelCAPI::Ravel::available())
327  {
328  int d=ravelCAPI::Ravel::daysUntilExpired();
329  return ravelCAPI::Ravel::version() + ": "+((d>=0)?("Expires in "+std::to_string(d)+" day"+(d!=1?"s":"")): "Expired");
330  }
331  else return "unavailable";
332  }
333  static bool ravelAvailable() {return ravelCAPI::available();}
334  static bool ravelExpired() {return ravelCAPI::available() && ravelCAPI::daysUntilExpired()<0;}
335  static int daysUntilRavelExpires() {return ravelCAPI::daysUntilExpired();}
336 
337  std::string fileVersion;
338 
339  unsigned maxHistory{100};
340  int maxWaitMS=100;
341 
343  std::string autoSaveFile() const {return autoSaver? autoSaver->fileName: std::string();}
346  void setAutoSaveFile(const std::string& file);
347 
349  void clearHistory() {history.clear(); historyPtr=0;}
351  void checkPushHistory() {if (historyPtr==history.size()) pushHistory();}
352 
354  bool pushHistory();
355 
360  bool commandHook(const std::string& command, unsigned nargs);
361 
362  enum CmdData {no_command, is_const, is_setterGetter, generic};
363 
365  virtual CmdData getCommandData(const std::string& command) const {return generic;}
366 
370  bool doPushHistory=true;
371 
374  long undo(int changes=1);
375 
378  void convertVarType(const std::string& name, VariableType::Type type);
379 
382  void addIntegral();
383 
385  bool inputWired(const std::string& name) const {return definingVar(name).get();}
386 
388  void renderCanvasToPS(const std::string& filename) {canvas.renderToPS(filename);}
390  void renderCanvasToPDF(const std::string& filename) {canvas.renderToPDF(filename);}
392  void renderCanvasToSVG(const std::string& filename) {canvas.renderToSVG(filename);}
394  void renderCanvasToPNG(const std::string& filename) {canvas.renderToPNG(filename);}
395 
396 
400  void renderCanvasToPNG(const std::string& filename, const Canvas::ZoomCrop& z)
401  {canvas.renderToPNGCropped(filename,z);}
402 
404  void renderCanvasToEMF(const std::string& filename) {canvas.renderToEMF(filename);}
405 
407  void renderAllPlotsAsSVG(const string& prefix) const;
409  void exportAllPlotsAsCSV(const string& prefix) const;
410 
412  void setAllDEmode(bool);
414  void srand(int seed) {::srand(seed);}
415 
416  // godley table display values preferences
417  bool displayValues=false;
419 
421  void setGodleyDisplayValue(bool displayValues, GodleyTable::DisplayStyle displayStyle);
422 
424  void importVensim(const std::string&);
425 
427  void redrawAllGodleyTables();
428 
430  virtual void setBusyCursor() {}
431  virtual void clearBusyCursor() {}
433  virtual void progress(const std::string& title,int) {}
434 
436  virtual void bookmarkRefresh() {}
437 
439  virtual void resetScroll() {}
440 
442  virtual void message(const std::string&) {}
443 
445  virtual void runItemDeletedCallback(const Item&) {}
446 
449  enum MemCheckResult {OK, proceed, abort};
450  virtual MemCheckResult checkMemAllocation(size_t bytes) const {return OK;}
451 
453  static std::size_t physicalMem();
454 
455  vector<string> listFonts() const {
456  vector<string> r;
457 #ifdef PANGO
458  PangoFontFamily **families;
459  int num;
460  pango_font_map_list_families(pango_cairo_font_map_get_default(),
461  &families,&num);
462  for (int i=0; i<num; ++i)
463  r.push_back(pango_font_family_get_name(families[i]));
464  g_free(families);
465  std::sort(r.begin(),r.end());
466 #endif
467  return r;
468  }
469 
471  static std::string defaultFont();
472  static std::string defaultFont(const std::string& x);
474 
476  static double fontScale();
477  static double fontScale(double);
479 
480  static int numOpArgs(OperationType::Type o);
482 
483  void latex(const std::string& filename, bool wrapLaTeXLines);
484 
485  void matlab(const std::string& filename) {
486  if (cycleCheck()) throw error("cyclic network detected");
487  ofstream f(filename);
489  }
490 
491  // for testing purposes
492  string latex2pango(const std::string& x) {return latexToPango(x.c_str());}
493 
495  static std::vector<std::string> availableOperations();
496  using AvailableOperationsMapping=classdesc::StringKeyMap<std::vector<OperationType::Type>>;
497  static Minsky::AvailableOperationsMapping availableOperationsMapping();
498 
500  static std::vector<std::string> variableTypes();
502  static std::vector<std::string> assetClasses();
503 
504  void autoLayout();
505  void randomLayout();
506  void openGroupInCanvas() {canvas.openGroupInCanvas(canvas.item);}
509  void openModelInCanvas() {canvas.openGroupInCanvas(model);}
510 
512  std::shared_ptr<VariableInstanceList> variableInstanceList;
513  void listAllInstances();
514 
515  std::map<std::string,std::weak_ptr<Item>> namedItems;
516  void nameCurrentItem(const std::string& name) {namedItems[name]=canvas.item;}
517  void itemFromNamedItem(const std::string& name) {canvas.item=namedItems[name].lock();}
518 
521  {return checkMemAllocation(std::numeric_limits<size_t>::max());}
522 
524 
526  char getc() const {return std::getc(stdin);}
527 
529  void setDefinition(const std::string& valueId, const std::string& definition);
530 
532  void reloadAllCSVParameters();
533  };
534 
536  Minsky& minsky();
538  inline const Minsky& cminsky() {return minsky();}
540  struct LocalMinsky
541  {
542  LocalMinsky(Minsky& m);
543  ~LocalMinsky();
544  };
545 
546 
547 
548 }
549 
550 #ifdef _CLASSDESC
551 #pragma omit pack minsky::MinskyExclude
552 #pragma omit unpack minsky::MinskyExclude
553 #pragma omit TCL_obj minsky::MinskyExclude
554 #pragma omit xml_pack minsky::MinskyExclude
555 #pragma omit xml_unpack minsky::MinskyExclude
556 #pragma omit xsd_generate minsky::MinskyExclude
557 
558 #pragma omit xml_pack minsky::Integral
559 #pragma omit xml_unpack minsky::Integral
560 
561 #pragma omit pack minsky::MinskyMatrix
562 #pragma omit unpack minsky::MinskyMatrix
563 #pragma omit xml_pack minsky::MinskyMatrix
564 #pragma omit xml_unpack minsky::MinskyMatrix
565 #pragma omit xsd_generate minsky::MinskyMatrix
566 #endif
567 
568 #include "minsky.cd"
569 #endif
virtual void message(const std::string &)
display a message in a popup box on the GUI
Definition: minsky.h:442
static SVGRenderer svgRenderer
Definition: group.h:257
function f
Definition: canvas.m:1
std::set< RenderNativeWindow * > nativeWindowsToRedraw
record nativeWindows that have requested redrawing
Definition: minsky.h:103
PannableTab< EquationDisplay > equationDisplay
Definition: minsky.h:141
void matlab(const std::string &filename)
Definition: minsky.h:485
std::string latexToPango(const char *s)
Definition: latexMarkup.h:30
string latex2pango(const std::string &x)
Definition: minsky.h:492
void pushFlags()
push and pop state of the flags
Definition: minsky.h:173
void setGodleyIconResource(const string &s)
Definition: minsky.h:203
vector< string > listFonts() const
Definition: minsky.h:455
char getc() const
Used to implement a pause until return pressed for attaching debugger purposes.
Definition: minsky.h:526
virtual void setBusyCursor()
set/clear busy cursor in GUI
Definition: minsky.h:430
static bool ravelExpired()
Definition: minsky.h:334
std::set< string > logVarList
set of variables (valueIds) to log
Definition: minsky.h:289
Clipboard clipboard
clipboard manager
Definition: minsky.h:94
virtual void clearBusyCursor()
Definition: minsky.h:431
MinskyExclude & operator=(const MinskyExclude &)
Definition: minsky.h:100
void closeLogFile()
closes log file
Definition: minsky.h:287
bool inputWired(const std::string &name) const
returns true if any variable of name name has a wired input
Definition: minsky.h:385
VariableValues variableValues
Definition: minsky.h:188
virtual void runItemDeletedCallback(const Item &)
run callback attached to item
Definition: minsky.h:445
std::vector< int > flagStack
Definition: minsky.h:92
std::map< Units, double > maxValue
stash the maximum absolute value obtained by a dimensioned quantity
Definition: minsky.h:192
void checkPushHistory()
called periodically to ensure history up to date
Definition: minsky.h:351
virtual MemCheckResult checkMemAllocation(size_t bytes) const
Definition: minsky.h:450
MemCheckResult
check whether to proceed or abort, given a request to allocate bytes of memory. Implemented in Minsky...
Definition: minsky.h:449
bool edited() const
reflects whether the model has been changed since last save
Definition: minsky.h:157
STL namespace.
std::map< Units, double > maxFlowValue
Definition: minsky.h:193
void renderCanvasToEMF(const std::string &filename)
render canvas to a EMF image file (Windows only)
Definition: minsky.h:404
void setResource(const std::string &resource)
initialise object from an SVG file
Definition: SVGItem.cc:57
void addNewPublicationTab(const std::string &name)
Definition: minsky.h:146
static SVGRenderer svgRenderer
SVG icon to display when not in editor mode.
Definition: ravelWrap.h:83
static int daysUntilRavelExpires()
Definition: minsky.h:335
bool loggingEnabled() const
returns true if logging is in operation
Definition: minsky.h:291
void setLockIconResource(const string &locked, const string &unlocked)
Definition: minsky.h:207
ItemType
Definition: minsky.h:117
void nameCurrentItem(const std::string &name)
Definition: minsky.h:516
string valueId(const string &name)
construct a valueId from fully qualified name @ name should not be canonicalised
Definition: valueId.cc:75
void renderCanvasToSVG(const std::string &filename)
render canvas to an SVG file
Definition: minsky.h:392
bool resetIfFlagged() override
checks whether a reset is required, and resets the simulation if so
Definition: minsky.h:182
bool clipboardEmpty() const
return true if nothing available in clipboard
Definition: minsky.h:267
void markEdited()
indicate model has been changed since last saved
Definition: minsky.h:161
void renderCanvasToPS(const std::string &filename)
render canvas to a postscript file
Definition: minsky.h:388
static bool ravelAvailable()
Definition: minsky.h:333
virtual CmdData getCommandData(const std::string &command) const
return meta information on a given command
Definition: minsky.h:365
bool reset_flag() const
true if reset needs to be called prior to numerical integration
Definition: minsky.h:159
std::size_t historyPtr
Definition: minsky.h:113
VariablePane variablePane
Definition: minsky.h:523
static OperationType::Group classifyOp(OperationType::Type o)
Definition: minsky.h:481
classdesc::StringKeyMap< std::vector< OperationType::Type > > AvailableOperationsMapping
Definition: minsky.h:496
static SVGRenderer svgRenderer
SVG icon to display when not in editor mode.
Definition: godleyIcon.h:62
void populateMissingDimensionsFromVariable(const VariableValue &v)
Definition: minsky.h:199
std::string autoSaveFile() const
name of an auto save file
Definition: minsky.h:343
bool triggerCheckMemAllocationCallback() const
trigger checkMem callback for testing purposes
Definition: minsky.h:520
std::deque< classdesc::pack_t > history
save history of model for undo
Definition: minsky.h:112
void renderCanvasToPNG(const std::string &filename)
render canvas to a PNG image file
Definition: minsky.h:394
Exclude< ptime > lastRedraw
Definition: minsky.h:130
static SVGRenderer lockedIcon
Definition: lock.h:42
An RAII wrapper around jtanx&#39;s libclipboard (https://github.com/jtanx/libclipboard) ...
Definition: clipboard.h:28
static std::string ravelVersion()
Definition: minsky.h:325
void setRavelIconResource(const string &s)
Definition: minsky.h:211
std::vector< PubTab > publicationTabs
Definition: minsky.h:144
void clearAllMapsTCL()
Definition: minsky.h:248
Mixin implementing common panning functionality in tabs.
Definition: pannableTab.h:36
double deltaT() const
Definition: minsky.h:308
virtual void bookmarkRefresh()
refresh the bookmark menu after changes
Definition: minsky.h:436
shared_ptr< ofstream > outputDataFile
Definition: minsky.h:75
#define CLASSDESC_ACCESS(type)
std::shared_ptr< VariableInstanceList > variableInstanceList
supports navigation to all instances of current variable
Definition: minsky.h:512
void addCanvasItemToPublicationTab(size_t i)
Definition: minsky.h:147
const Minsky & cminsky()
const version to help in const correctness
Definition: minsky.h:538
ostream & matlab(ostream &) const
render as MatLab code create equations suitable for Runge-Kutta solver
Definition: equations.cc:963
Progress progressState
Definition: minsky.h:89
bool multipleEquities() const
Definition: minsky.h:153
SVGRenderer histogramResource
Definition: minsky.h:213
void setGroupIconResource(const string &s)
Definition: minsky.h:205
static const std::string minskyVersion
Definition: minsky.h:323
void saveCanvasItemAsFile(const string &fileName) const
Definition: minsky.h:254
Exclude< std::map< std::string, std::shared_ptr< CallableFunction > > > userFunctions
Definition: minsky.h:240
virtual void resetScroll()
reset main window scroll bars after model has been panned
Definition: minsky.h:439
static SVGRenderer unlockedIcon
Definition: lock.h:43
virtual void progress(const std::string &title, int)
set progress bar, out of 100, labelling the progress bar with title
Definition: minsky.h:433
std::map< std::string, std::weak_ptr< Item > > namedItems
Definition: minsky.h:515
void openModelInCanvas()
reinitialises canvas to the toplevel group
Definition: minsky.h:509
MinskyExclude(const MinskyExclude &)
Definition: minsky.h:99
std::shared_ptr< Group > GroupPtr
Definition: port.h:32
void itemFromNamedItem(const std::string &name)
Definition: minsky.h:517
PhillipsDiagram phillipsDiagram
Definition: minsky.h:143
RAII set the minsky object to a different one for the current scope.
Definition: minsky.h:540
void clearAllMaps()
Definition: minsky.h:246
string latex(double)
convert double to a LaTeX string representing that value
Definition: node_latex.cc:28
void renderCanvasToPDF(const std::string &filename)
render canvas to a PDF file
Definition: minsky.h:390
Minsky & minsky()
global minsky object
Definition: addon.cc:545
FontDisplay fontSampler
Definition: minsky.h:142
void popFlags()
push and pop state of the flags
Definition: minsky.h:174
Conversions conversions
Definition: minsky.h:190
void srand(int seed)
set std library RNG seed
Definition: minsky.h:414
void saveSelectionAsFile(const string &fileName) const
Definition: minsky.h:268
static std::string ecolabVersion()
Definition: minsky.h:324
std::chrono::milliseconds resetDuration
Definition: minsky.h:87
Dimensions dimensions
Definition: minsky.h:189
void renderCanvasToPNG(const std::string &filename, const Canvas::ZoomCrop &z)
Render canvas to a PNG file filename, scaling the canvas temporarily by zoom, shifts it to left...
Definition: minsky.h:400
static Group classify(Type t)
std::string fileVersion
Minsky version file was saved under.
Definition: minsky.h:337
unique_ptr< BackgroundSaver > autoSaver
Definition: minsky.h:76
void clearHistory()
clear history
Definition: minsky.h:349