diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2dd65bb --- /dev/null +++ b/.gitignore @@ -0,0 +1,247 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,pycharm +# Edit at https://www.toptal.com/developers/gitignore?templates=python,visualstudiocode,pycharm + +### PyCharm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### PyCharm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +# End of https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,pycharm diff --git a/Examples/TTT.flow b/Examples/TTT.flow new file mode 100644 index 0000000..93219dd --- /dev/null +++ b/Examples/TTT.flow @@ -0,0 +1,139 @@ +blockdiag { +initialization_code=" + +global X +X=lambda i: 'X'+str(i) + +global O +O=lambda i: 'O'+str(i) + +global anyX +anyX = (lambda e: e[0]=='X') + +global anyMove +anyMove = (lambda e: anyX(e) or anyO(e)) + +global anyO +anyO = (lambda e: e[0]=='O') + +global toX +toX = (lambda e: 'X' + e[1:]) + +global toO +toO = (lambda e: 'O' + e[1:]) +" + event_selection_mechanism = "priority" + + lines [type=start, initial="[ + {'c1':1,'c2':2,'c3':3}, + {'c1':4,'c2':5,'c3':6}, + {'c1':7,'c2':8,'c3':9}, + {'c1':1,'c2':4,'c3':7}, + {'c1':2,'c2':5,'c3':8}, + {'c1':3,'c2':6,'c3':9}, + {'c1':1,'c2':5,'c3':9}, + {'c1':3,'c2':5,'c3':7}]", width=350]; + perm [type=permutation, keys="['c1','c2','c3']", width=200] + + lines -> perm -> def_wt1 -> def_wt2 -> def_req; + + def_wt1 [type=sync, wait="[X(c1)]", width=100, tokens_display="count only"] + def_wt2 [type=sync, wait="[X(c2)]", width=150, tokens_display="count only"] + def_req [type=sync, req="[O(c3)]", width=150, tokens_display="count only"] + + ######################################################################## + + perm -> ofn_wt1 -> ofn_wt2 -> ofn_req; + ofn_wt1 [type=sync, wait="[O(c1)]", width=100, tokens_display="count only"] + ofn_wt2 [type=sync, wait="[O(c2)]", width=150, tokens_display="count only"] + ofn_req [type=sync, req="[O(c2)]", priority=10, width=150, tokens_display="count only"] + + ######################################################################## + perm -> owin_wt1 -> owin_wt2 -> owin_wt3 -> owin_req; + + owin_wt1 [type=sync, wait="[O(c1)]", width=100, tokens_display="count only"] + owin_wt2 [type=sync, wait="[O(c2)]", width=150, tokens_display="count only"] + owin_wt3 [type=sync, wait="[O(c2)]", width=150, tokens_display="count only"] + owin_req [type=sync, req="['Player O wins']", block=anyMove, priority=100, width=150] + + ######################################################################## + + perm -> xwin_wt1 -> xwin_wt2 ->xwin_wt3 -> xwin_req; + + xwin_wt1 [type=sync, wait="[X(c1)]", width=100, tokens_display="count only"] + xwin_wt2 [type=sync, wait="[X(c2)]", width=150, tokens_display="count only"] + xwin_wt3 [type=sync, wait="[X(c2)]", width=150, tokens_display="count only"] + xwin_req [type=sync, req="['Player X wins']", block=anyMove, priority=100, width=150] + + ######################################################################## + + + tie_st -> tie_loop -> tie_wait -> tie_loop + tie_loop -> tie_req [label=after] + + + tie_st [type=start] + tie_loop [type=loop, count=9, width=200] + tie_wait [type=sync, wait=anyMove] + tie_req [type=sync, req="['No winner']", priority=100] + + + ######################################################################## + + int_st -> int_1 -> int_2 -> int_1; + + int_st [type=start] + int_1 [type=sync, wait=anyX, block=anyO, width=100] + int_2 [type=sync, wait=anyO, block=anyX, width=100] + + ########### + + once_st -> once_wt -> once_bl + once_wt -> once_wt + once_st [type=start] + once_wt [type=sync, wait=anyMove] + once_bl [type=sync, block="[toX(event), toO(event)]", width=300, tokens_display="full with event"] + + + ############ + + st -> rq1 + st [type=start] + rq1 [type=sync, req="['O5']", priority="-1"] + + st -> rq2 -> rq2 + rq2 [type=sync, req="['O1','O3','O7','O9']", priority="-2", width=200] + + st -> rq3 -> rq3 + rq3 [type=sync, req="['O2','O4','O6','O8']", priority="-3", width=200] + + + +run=" +run_init(diagram) +setup_diagram(diagram) + +print_state(False) + +board = [' ' for i in range(9)] + +while True: + while step_to_next_state(diagram): print_state(False) + + try: + e = select_event(diagram) + except: + e = 'X'+input('Enter cell number to put X in:') + + if e[0] in ['O','X'] and e[1] in ['1','2','3','4','5','6','7','8','9']: + board[int(e[1])-1] = e[0] + print( '\n-----\n'.join([ '|'.join(board[i*3:(i+1)*3]) for i in range(3)])) + print() + wake_up_tokens(diagram, e) + else: + print('Game ended: ' + e) + break +" + + +} diff --git a/Examples/TTT.png b/Examples/TTT.png new file mode 100644 index 0000000..3665449 Binary files /dev/null and b/Examples/TTT.png differ diff --git a/Examples/TTT2.flow b/Examples/TTT2.flow new file mode 100644 index 0000000..7ba590f --- /dev/null +++ b/Examples/TTT2.flow @@ -0,0 +1,75 @@ +diagram { +initialization_code=" + +global X +X=lambda i: 'X'+str(i) + +global O +O=lambda i: 'O'+str(i) + +global anyX +anyX = (lambda e: e[0]=='X') + +global anyMove +anyMove = (lambda e: anyX(e) or anyO(e)) + +global anyO +anyO = (lambda e: e[0]=='O') + +global toX +toX = (lambda e: 'X' + e[1:]) + +global toO +toO = (lambda e: 'O' + e[1:]) +" + event_selection_mechanism = "priority" + + lines [type=start, initial= + "[{'line':[1,2,3]}, + {'line':[4,5,6]}, + {'line':[7,8,9]}, + {'line':[1,4,7]}, + {'line':[2,5,8]}, + {'line':[3,6,9]}, + {'line':[1,5,9]}, + {'line':[3,5,7]}]", width=350]; + + + lines -> def_wt1 -> def_join -> def_req + lines -> def_wt2 -> def_join + lines -> def_wt3 -> def_join + + def_wt1 -> xwin_join -> xwin_req + def_wt2 -> xwin_join + def_wt3 -> xwin_join + + + def_wt1 [type=sync, wait="[X(line[0])]", width=250] + def_wt2 [type=sync, wait="[X(line[1])]", width=250] + def_wt3 [type=sync, wait="[X(line[2])]", width=250] + + def_req [type=sync, req="[O(last)]", width=350] + def_join [type=join, count=2, join_by="['line']", join="lambda g: { 'last': (set(g[0]['line']) - {int(t['event'][1]) for t in g}).pop()}", width=400] + + xwin_join [type=join, count=3, join_by="['line']", join="lambda g: {}", width=400] + xwin_req [type=sync, req="['X Player wins']", width=350] + + + ######################################################################## + + st -> r1 -> r2 -> r3; + st [type=start] + r1 [type=sync, req="[X(5)]"] + r2 [type=sync, req="[X(6)]"] + r3 [type=sync, req="[X(4)]"] + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + + + +} diff --git a/Examples/TTT2.png b/Examples/TTT2.png new file mode 100644 index 0000000..d5242ca Binary files /dev/null and b/Examples/TTT2.png differ diff --git a/Examples/TTT2_run/1.png b/Examples/TTT2_run/1.png new file mode 100644 index 0000000..51e567e Binary files /dev/null and b/Examples/TTT2_run/1.png differ diff --git a/Examples/TTT2_run/10.png b/Examples/TTT2_run/10.png new file mode 100644 index 0000000..18c5338 Binary files /dev/null and b/Examples/TTT2_run/10.png differ diff --git a/Examples/TTT2_run/11.png b/Examples/TTT2_run/11.png new file mode 100644 index 0000000..93867a2 Binary files /dev/null and b/Examples/TTT2_run/11.png differ diff --git a/Examples/TTT2_run/12.png b/Examples/TTT2_run/12.png new file mode 100644 index 0000000..93867a2 Binary files /dev/null and b/Examples/TTT2_run/12.png differ diff --git a/Examples/TTT2_run/2.png b/Examples/TTT2_run/2.png new file mode 100644 index 0000000..6419593 Binary files /dev/null and b/Examples/TTT2_run/2.png differ diff --git a/Examples/TTT2_run/3.png b/Examples/TTT2_run/3.png new file mode 100644 index 0000000..3d3ac26 Binary files /dev/null and b/Examples/TTT2_run/3.png differ diff --git a/Examples/TTT2_run/4.png b/Examples/TTT2_run/4.png new file mode 100644 index 0000000..67c4b0b Binary files /dev/null and b/Examples/TTT2_run/4.png differ diff --git a/Examples/TTT2_run/5.png b/Examples/TTT2_run/5.png new file mode 100644 index 0000000..0405fea Binary files /dev/null and b/Examples/TTT2_run/5.png differ diff --git a/Examples/TTT2_run/6.png b/Examples/TTT2_run/6.png new file mode 100644 index 0000000..9cd3f20 Binary files /dev/null and b/Examples/TTT2_run/6.png differ diff --git a/Examples/TTT2_run/7.png b/Examples/TTT2_run/7.png new file mode 100644 index 0000000..f3c8f43 Binary files /dev/null and b/Examples/TTT2_run/7.png differ diff --git a/Examples/TTT2_run/8.png b/Examples/TTT2_run/8.png new file mode 100644 index 0000000..d4b38e0 Binary files /dev/null and b/Examples/TTT2_run/8.png differ diff --git a/Examples/TTT2_run/9.png b/Examples/TTT2_run/9.png new file mode 100644 index 0000000..18c5338 Binary files /dev/null and b/Examples/TTT2_run/9.png differ diff --git a/Examples/TTT_run/1.png b/Examples/TTT_run/1.png new file mode 100644 index 0000000..19a271d Binary files /dev/null and b/Examples/TTT_run/1.png differ diff --git a/Examples/TTT_run/10.png b/Examples/TTT_run/10.png new file mode 100644 index 0000000..f292136 Binary files /dev/null and b/Examples/TTT_run/10.png differ diff --git a/Examples/TTT_run/11.png b/Examples/TTT_run/11.png new file mode 100644 index 0000000..3f08372 Binary files /dev/null and b/Examples/TTT_run/11.png differ diff --git a/Examples/TTT_run/12.png b/Examples/TTT_run/12.png new file mode 100644 index 0000000..4b6fcf0 Binary files /dev/null and b/Examples/TTT_run/12.png differ diff --git a/Examples/TTT_run/13.png b/Examples/TTT_run/13.png new file mode 100644 index 0000000..ae9ce62 Binary files /dev/null and b/Examples/TTT_run/13.png differ diff --git a/Examples/TTT_run/14.png b/Examples/TTT_run/14.png new file mode 100644 index 0000000..fcb8ada Binary files /dev/null and b/Examples/TTT_run/14.png differ diff --git a/Examples/TTT_run/15.png b/Examples/TTT_run/15.png new file mode 100644 index 0000000..d6bc722 Binary files /dev/null and b/Examples/TTT_run/15.png differ diff --git a/Examples/TTT_run/16.png b/Examples/TTT_run/16.png new file mode 100644 index 0000000..d3218eb Binary files /dev/null and b/Examples/TTT_run/16.png differ diff --git a/Examples/TTT_run/17.png b/Examples/TTT_run/17.png new file mode 100644 index 0000000..cc21518 Binary files /dev/null and b/Examples/TTT_run/17.png differ diff --git a/Examples/TTT_run/18.png b/Examples/TTT_run/18.png new file mode 100644 index 0000000..09bd24a Binary files /dev/null and b/Examples/TTT_run/18.png differ diff --git a/Examples/TTT_run/19.png b/Examples/TTT_run/19.png new file mode 100644 index 0000000..a0ddcaf Binary files /dev/null and b/Examples/TTT_run/19.png differ diff --git a/Examples/TTT_run/2.png b/Examples/TTT_run/2.png new file mode 100644 index 0000000..0ba7ace Binary files /dev/null and b/Examples/TTT_run/2.png differ diff --git a/Examples/TTT_run/20.png b/Examples/TTT_run/20.png new file mode 100644 index 0000000..6ee4a65 Binary files /dev/null and b/Examples/TTT_run/20.png differ diff --git a/Examples/TTT_run/21.png b/Examples/TTT_run/21.png new file mode 100644 index 0000000..57c8351 Binary files /dev/null and b/Examples/TTT_run/21.png differ diff --git a/Examples/TTT_run/3.png b/Examples/TTT_run/3.png new file mode 100644 index 0000000..b3ff847 Binary files /dev/null and b/Examples/TTT_run/3.png differ diff --git a/Examples/TTT_run/4.png b/Examples/TTT_run/4.png new file mode 100644 index 0000000..4493f48 Binary files /dev/null and b/Examples/TTT_run/4.png differ diff --git a/Examples/TTT_run/5.png b/Examples/TTT_run/5.png new file mode 100644 index 0000000..6632458 Binary files /dev/null and b/Examples/TTT_run/5.png differ diff --git a/Examples/TTT_run/6.png b/Examples/TTT_run/6.png new file mode 100644 index 0000000..845f402 Binary files /dev/null and b/Examples/TTT_run/6.png differ diff --git a/Examples/TTT_run/7.png b/Examples/TTT_run/7.png new file mode 100644 index 0000000..1180a77 Binary files /dev/null and b/Examples/TTT_run/7.png differ diff --git a/Examples/TTT_run/8.png b/Examples/TTT_run/8.png new file mode 100644 index 0000000..d81278c Binary files /dev/null and b/Examples/TTT_run/8.png differ diff --git a/Examples/TTT_run/9.png b/Examples/TTT_run/9.png new file mode 100644 index 0000000..657a100 Binary files /dev/null and b/Examples/TTT_run/9.png differ diff --git a/hotcold1.flow b/Examples/hotcold1.flow similarity index 96% rename from hotcold1.flow rename to Examples/hotcold1.flow index 2150619..3ef028c 100644 --- a/hotcold1.flow +++ b/Examples/hotcold1.flow @@ -1,25 +1,25 @@ -blockdiag { - st1 -> lp1 -> bs1 -> lp1; - st2 -> lp2 -> bs2 -> lp2; - st3 -> in1 -> in2 -> in1; - - st1 [type=start]; - bs1 [type=sync, req="['hot']"]; - lp1 [type=loop, count=3]; - - st2 [type=start]; - bs2 [type=sync, req="['cold']"]; - lp2 [type=loop, count=3]; - - st3 [type=start]; - in1 [type=sync, wait="['hot']", block="['cold']"]; - in2 [type=sync, wait="['cold']", block="['hot']"]; - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> logger -> listener [style = "none"]; - listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; - logger [type=logger, label="Events log", autoformat='false'] - stt [type=start, class = "hidden", autoformat='false']; - -} +blockdiag { + st1 -> lp1 -> bs1 -> lp1; + st2 -> lp2 -> bs2 -> lp2; + st3 -> in1 -> in2 -> in1; + + st1 [type=start]; + bs1 [type=sync, req="['hot']"]; + lp1 [type=loop, count=3]; + + st2 [type=start]; + bs2 [type=sync, req="['cold']"]; + lp2 [type=loop, count=3]; + + st3 [type=start]; + in1 [type=sync, wait="['hot']", block="['cold']"]; + in2 [type=sync, wait="['cold']", block="['hot']"]; + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/hotcold1.png b/Examples/hotcold1.png similarity index 100% rename from hotcold1.png rename to Examples/hotcold1.png diff --git a/Examples/hotcold1_run/1.png b/Examples/hotcold1_run/1.png new file mode 100644 index 0000000..40e966f Binary files /dev/null and b/Examples/hotcold1_run/1.png differ diff --git a/Examples/hotcold1_run/10.png b/Examples/hotcold1_run/10.png new file mode 100644 index 0000000..5087e29 Binary files /dev/null and b/Examples/hotcold1_run/10.png differ diff --git a/Examples/hotcold1_run/11.png b/Examples/hotcold1_run/11.png new file mode 100644 index 0000000..e58fba7 Binary files /dev/null and b/Examples/hotcold1_run/11.png differ diff --git a/Examples/hotcold1_run/12.png b/Examples/hotcold1_run/12.png new file mode 100644 index 0000000..3f5dd44 Binary files /dev/null and b/Examples/hotcold1_run/12.png differ diff --git a/Examples/hotcold1_run/13.png b/Examples/hotcold1_run/13.png new file mode 100644 index 0000000..85bb2a8 Binary files /dev/null and b/Examples/hotcold1_run/13.png differ diff --git a/Examples/hotcold1_run/14.png b/Examples/hotcold1_run/14.png new file mode 100644 index 0000000..8177bae Binary files /dev/null and b/Examples/hotcold1_run/14.png differ diff --git a/Examples/hotcold1_run/15.png b/Examples/hotcold1_run/15.png new file mode 100644 index 0000000..374ab4a Binary files /dev/null and b/Examples/hotcold1_run/15.png differ diff --git a/Examples/hotcold1_run/2.png b/Examples/hotcold1_run/2.png new file mode 100644 index 0000000..2b3eb3f Binary files /dev/null and b/Examples/hotcold1_run/2.png differ diff --git a/Examples/hotcold1_run/3.png b/Examples/hotcold1_run/3.png new file mode 100644 index 0000000..25e8057 Binary files /dev/null and b/Examples/hotcold1_run/3.png differ diff --git a/Examples/hotcold1_run/4.png b/Examples/hotcold1_run/4.png new file mode 100644 index 0000000..d4e2b5b Binary files /dev/null and b/Examples/hotcold1_run/4.png differ diff --git a/Examples/hotcold1_run/5.png b/Examples/hotcold1_run/5.png new file mode 100644 index 0000000..ab889ab Binary files /dev/null and b/Examples/hotcold1_run/5.png differ diff --git a/Examples/hotcold1_run/6.png b/Examples/hotcold1_run/6.png new file mode 100644 index 0000000..74c3b2c Binary files /dev/null and b/Examples/hotcold1_run/6.png differ diff --git a/Examples/hotcold1_run/7.png b/Examples/hotcold1_run/7.png new file mode 100644 index 0000000..effa0d1 Binary files /dev/null and b/Examples/hotcold1_run/7.png differ diff --git a/Examples/hotcold1_run/8.png b/Examples/hotcold1_run/8.png new file mode 100644 index 0000000..3b87807 Binary files /dev/null and b/Examples/hotcold1_run/8.png differ diff --git a/Examples/hotcold1_run/9.png b/Examples/hotcold1_run/9.png new file mode 100644 index 0000000..64adb6b Binary files /dev/null and b/Examples/hotcold1_run/9.png differ diff --git a/NodeLibrary.py b/NodeLibrary.py index 4647116..b6ea12b 100644 --- a/NodeLibrary.py +++ b/NodeLibrary.py @@ -1,276 +1,342 @@ import abc import copy -from blockdiag.builder import * +from collections import Counter from itertools import permutations -from funcy import join from typing import * -import json + +from blockdiag.builder import * def run_init(diagram): - exec(diagram.initialization_code) + exec(diagram.initialization_code) class NodeType(metaclass=abc.ABCMeta): - - @abc.abstractmethod - def type_string(self) -> str: - pass - - def node_manipulator(self, n: DiagramNode) -> None: - n.org_label = n.label - n.org_height = n.height - if n.priority != 0: n.numbered = n.priority - - def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: - return [copy.deepcopy(t) for t in tokens] - - def state_visualization(self, n: DiagramNode) -> None: - n.label = n.org_label - n.height = n.org_height - - if n.org_label != "": n.label = n.org_label + "\n-------------" - - if n.height is None: - n.height = 80 - else: - n.height += 20 - - if n.tokens_display == 'full': - for t in n.tokens: - n.label += "\n" + str(t) - n.height += 10 - elif n.tokens_display == 'count only': - n.label += "\n" + len(n.tokens) + " tokens" - else: - raise Exception("Illegal value for 'tokens_display': " + n.tokens_display) - - def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> (Sequence[Dict], Sequence[Dict]): - return (tokens, []) + + @abc.abstractmethod + def type_string(self) -> str: + pass + + def node_manipulator(self, n: DiagramNode) -> None: + n.org_label = n.label + n.org_height = n.height + if n.priority != 0: + n.numbered = n.priority + + def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: + return [copy.deepcopy(t) for t in tokens] + + def state_visualization(self, n: DiagramNode) -> None: + n.label = n.org_label + n.height = n.org_height + + if n.org_label != "": + n.label = n.org_label + "\n-------------" + + if n.height is None: + n.height = 80 + else: + n.height += 20 + + if n.tokens_display == 'full': + for t in n.tokens: + n.label += "\n" + str(t) + n.height += 10 + elif n.tokens_display == 'count only': + n.label += "\n" + len(n.tokens) + " tokens" + else: + raise Exception( + "Illegal value for 'tokens_display': " + n.tokens_display) + + def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> ( + Sequence[Dict], Sequence[Dict]): + return (tokens, []) ###################################################################################### class StartType(NodeType): - - def type_string(self) -> str: - return "start" - - def node_manipulator(self, node: DiagramNode) -> None: - node.shape = "beginpoint" - node.label = "" - - if node.initial is None: - node.tokens = [{}] - else: - node.tokens = eval(node.initial) - - super().node_manipulator(node) + + def type_string(self) -> str: + return "start" + + def node_manipulator(self, node: DiagramNode) -> None: + node.shape = "beginpoint" + node.label = "" + + if node.initial is None: + node.tokens = [{}] + else: + node.tokens = eval(node.initial) + + super().node_manipulator(node) ###################################################################################### class SyncType(NodeType): - - def type_string(self) -> str: - return "sync" - - def node_manipulator(self, node: DiagramNode) -> None: - node.label = 'SYNC' - h = 30 - if node.req != "[]": node.label += "\nreq:" + node.req; h += 10 - if node.wait != "[]": node.label += "\nwait:" + node.wait; h += 10 - if node.block != "[]": node.label += "\nblock:" + node.block; h += 10 - if node.height is None: node.height = h - node.block_text = node.block; - node.wait_text = node.block; - if node.autoformat != 'false': node.color = '#fcfbe3' - super().node_manipulator(node) - - def state_visualization(self, n: DiagramNode) -> None: - n.label = n.org_label + "\n-----------" - n.height = 60 - - if n.tokens_display == 'full' or n.tokens_display == 'full with event': - for t in n.sync: - t = copy.deepcopy(t) - if "REQ" in t: del t["REQ"] - if "WAIT" in t: del t["WAIT"] - if "BLOCK" in t: del t["BLOCK"] - n.label += "\n" + str(t) - n.height += 20 - elif n.tokens_display == 'count only': - if len(n.sync) > 0: - n.label += "\n %d tokens" % len(n.sync) - else: - raise Exception("Illegal value for 'tokens_display': " + n.tokens_display) - - def genF(self, l): - return lambda e: e in l - - def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> Sequence[Dict]: - sync = copy.deepcopy(sync) - for t in tokens: - t = copy.deepcopy(t) - - if node.req != "[]": t['REQ'] = eval(node.req) - - if node.wait != "[]": - w = eval(node.wait) - t['WAIT'] = w if callable(w) else self.genF(w) - - if node.block != "[]": - b = eval(node.block) - t['BLOCK'] = b if callable(b) else self.genF(b) - - if node.tokens_display != 'full with event': - if 'event' in t: del t['event'] - - sync.append(t) - - return ([], sync) + + def type_string(self) -> str: + return "sync" + + def node_manipulator(self, node: DiagramNode) -> None: + node.label = 'SYNC' + h = 30 + if node.req != "[]": + node.label += "\nreq:" + node.req + h += 10 + if node.wait != "[]": + node.label += "\nwait:" + node.wait + h += 10 + if node.block != "[]": + node.label += "\nblock:" + node.block + h += 10 + if node.height is None: + node.height = h + node.block_text = node.block + node.wait_text = node.block + if node.autoformat != 'false': + node.color = '#fcfbe3' + super().node_manipulator(node) + + def state_visualization(self, n: DiagramNode) -> None: + n.label = n.org_label + "\n-----------" + n.height = 60 + + if n.tokens_display == 'full' or n.tokens_display == 'full with event': + for t in n.sync: + t = copy.deepcopy(t) + if "REQ" in t: + del t["REQ"] + if "WAIT" in t: + del t["WAIT"] + if "BLOCK" in t: + del t["BLOCK"] + n.label += "\n" + str(t) + n.height += 20 + elif n.tokens_display == 'count only': + if len(n.sync) > 0: + n.label += "\n %d tokens" % len(n.sync) + else: + raise Exception( + "Illegal value for 'tokens_display': " + n.tokens_display) + + def genF(self, l): + return lambda e: e in l + + def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> Sequence[Dict]: + sync = copy.deepcopy(sync) + for t in tokens: + t = copy.deepcopy(t) + + if node.req != "[]": + t['REQ'] = eval(node.req, globals(), t) + + if node.wait != "[]": + w=eval(node.wait, globals(), t) + t['WAIT']=w if callable(w) else self.genF(w) + + if node.block != "[]": + b=eval(node.block, globals(), t) + t['BLOCK']=b if callable(b) else self.genF(b) + + if node.tokens_display != 'full with event': + if 'event' in t: + del t['event'] + + sync.append(t) + + return ([], sync) ###################################################################################### class LoopType(NodeType): - - def type_string(self) -> str: - return "loop" - - def node_manipulator(self, node: DiagramNode) -> None: - node.label = 'LOOP' - node.label += "\ncount:" + node.count - super().node_manipulator(node) - - def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: - nxtt = [] - - for pt in tokens: - t = copy.deepcopy(pt) - - try: - t["COUNT"] = t["COUNT"] - 1 - except KeyError: - t["COUNT"] = int(node.count) - - if port == 'after': - if t["COUNT"] == 0: - nxtt.append(t) - else: - if t["COUNT"] != 0: - nxtt.append(t) - - return nxtt + + def type_string(self) -> str: + return "loop" + + def node_manipulator(self, node: DiagramNode) -> None: + node.label='LOOP' + node.label += "\ncount:" + node.count + super().node_manipulator(node) + + def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: + nxtt=[] + + for pt in tokens: + t=copy.deepcopy(pt) + + try: + t["COUNT"]=t["COUNT"] - 1 + except KeyError: + t["COUNT"]=int(node.count) + + if port == 'after': + if t["COUNT"] == 0: + nxtt.append(t) + else: + if t["COUNT"] != 0: + nxtt.append(t) + + return nxtt ###################################################################################### class PassType(NodeType): - - def type_string(self) -> str: - return "pass" - - def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: - return [copy.deepcopy(t) for t in tokens] + + def type_string(self) -> str: + return "pass" + + def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: + return [copy.deepcopy(t) for t in tokens] ###################################################################################### class PermutationType(NodeType): - - def type_string(self) -> str: - return "permutation" - - def node_manipulator(self, node: DiagramNode) -> None: - node.label = 'PERMUTATION' - node.label += "\nkeys:" + node.keys - super().node_manipulator(node) - - def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: - ret = [] - - for t in tokens: - keys = eval(node.keys) - values = [t[k] for k in keys] - pvalues = permutations(values) - - for pval in pvalues: - t = copy.deepcopy(t) - for k in range(len(pval)): - t[keys[k]] = pval[k] - ret.append(t) - - return ret + + def type_string(self) -> str: + return "permutation" + + def node_manipulator(self, node: DiagramNode) -> None: + node.label='PERMUTATION' + node.label += "\nkeys:" + node.keys + super().node_manipulator(node) + + def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: + ret=[] + + for t in tokens: + keys=eval(node.keys, globals(), t) + values=[t[k] for k in keys] + pvalues=permutations(values) + + for pval in pvalues: + t=copy.deepcopy(t) + for k in range(len(pval)): + t[keys[k]]=pval[k] + ret.append(t) + + return ret ###################################################################################### class JoinType(NodeType): - - def type_string(self) -> str: - return "join" - - def node_manipulator(self, node: DiagramNode) -> None: - n.label = 'JOIN' - super().node_manipulator(node) - - def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: - return [join(tokens)] if len(tokens) is not 0 else [] + + def type_string(self) -> str: + return "join" + + def node_manipulator(self, node: DiagramNode) -> None: + node.label='JOIN\nCOUNT=%s' % node.count + node.log=[] + super().node_manipulator(node) + + def state_visualization(self, n: DiagramNode) -> None: + n.label=n.org_label + n.height=50 + + n.label += "\n---------------------" + for t in n.log: + n.label += "\n" + str(t) + n.height += 20 + + def get_groups(self, node: DiagramNode): + ret=[] + + join_by=eval(node.join_by) + def joinby(t): return [t[i] for i in join_by] + + node.log.sort(key=joinby) + + join=None + for t in node.log: + if joinby(t) != join: + join=joinby(t) + group=[t] + else: + group.append(t) + if(len(group) >= eval(node.count)): + ret.append(group) + + return ret + + def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> (Sequence[Dict], Sequence[Dict]): + if len(tokens) is not 0: + node.log.extend(tokens) + + return (tokens, []) + + def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: + groups=self.get_groups(node) + if len(groups) != 0: + for g in groups: + for t in g: + node.log.remove(t) + + if node.join is None: + return [{'group': g} for g in groups] + else: + return [eval(node.join)(g) for g in groups] + + return [] ###################################################################################### class WaitForSetType(NodeType): - - def type_string(self) -> str: - return "waitforset" - - def node_manipulator(self, node: DiagramNode) -> None: - node.label = "ANY " + node.threshold + " OF \n" + node.set; - node.set = eval(node.set) - node.visited = [] - node.threshold = int(node.threshold) - # node.width = 400 - node.height = 100 - super().node_manipulator(node) - - def state_visualization(self, n: DiagramNode) -> None: - n.label = n.org_label - n.height = 80 - - n.label += "\n---------------------" - n.label += "\nhistory=" + str(n.visited) - for t in n.tokens: - n.label += "\n" + str(t) - n.height += 10 - - def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: - node.visited += [t for t in tokens if t in node.set and t not in node.visited] - - if len(node.visited) >= node.threshold: - tmp = node.visited - node.visited = [] - return [{'subset': tmp}] - else: - return [] + + def type_string(self) -> str: + return "waitforset" + + def node_manipulator(self, node: DiagramNode) -> None: + node.label="ANY " + node.threshold + " OF \n" + node.set + node.set=eval(node.set) + node.visited=[] + node.threshold=int(node.threshold) + # node.width = 400 + node.height=100 + super().node_manipulator(node) + + def state_visualization(self, n: DiagramNode) -> None: + n.label=n.org_label + n.height=80 + + n.label += "\n---------------------" + n.label += "\nhistory=" + str(n.visited) + for t in n.tokens: + n.label += "\n" + str(t) + n.height += 10 + + def transformation(self, tokens: Sequence[Dict], node: DiagramNode, port: str) -> Sequence[Dict]: + node.visited += [t for t in tokens if t in node.set and t not in node.visited] + + if len(node.visited) >= node.threshold: + tmp=node.visited + node.visited=[] + return [{'subset': tmp}] + else: + return [] ###################################################################################### class LoggerType(NodeType): - - def type_string(self) -> str: - return "logger" - - def node_manipulator(self, node: DiagramNode) -> None: - node.label = 'LOG' - node.log = [] - super().node_manipulator(node) - - def state_visualization(self, n: DiagramNode) -> None: - n.label = n.org_label - n.height = 50 - - n.label += "\n---------------------" - for t in n.log: - n.label += "\n" + str(t) - n.height += 10 - - def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> (Sequence[Dict], Sequence[Dict]): - if len(tokens) is not 0: - node.log.append(tokens) - - return (tokens, []) + + def type_string(self) -> str: + return "logger" + + def node_manipulator(self, node: DiagramNode) -> None: + node.label='LOG' + node.log=[] + super().node_manipulator(node) + + def state_visualization(self, n: DiagramNode) -> None: + n.label=n.org_label + n.height=50 + + n.label += "\n---------------------" + for t in n.log: + n.label += "\n" + str(t) + n.height += 10 + + def synchronization(self, tokens: Sequence[Dict], sync: Sequence[Dict], node: DiagramNode) -> ( + Sequence[Dict], Sequence[Dict]): + if len(tokens) != 0: + node.log.append(tokens) + + return (tokens, []) diff --git a/README.md b/README.md deleted file mode 100644 index a026f24..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Python-BFlow- -An implementation of Behavioral Flow diagrams in python diff --git a/TTT1.flow b/TTT1.flow deleted file mode 100644 index 0344c37..0000000 --- a/TTT1.flow +++ /dev/null @@ -1,23 +0,0 @@ -blockdiag { - rows -> perm -> wt1 -> wt2 -> req; - - rows [type=start, initial="[{1:'1',2:'2',3:'3'}, {1:'4',2:'5',3:'6'}, {1:'7',2:'8',3:'9'}]"]; - wt1 [type=sync, wait="['X'+t[1]]"] - wt2 [type=sync, wait="['X'+t[2]]"] - req [type=sync, req="['O'+t[3]]"] - perm [type=permutation, keys="[1,2,3]"] - - x -> rq; - x [type=start, initial="[{'e':'X1'}, {'e':'X2'}, {'e':'X3'}, {'e':'X4'}, {'e':'X5'}, {'e':'X6'}, {'e':'X7'}, {'e':'X8'}, {'e':'X9'} ]"] - rq [type=sync, req="[t['e']]"] - - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> logger [style = "none"]; - listener -> listener [style = "none"]; - listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; - logger [type=logger, label="Events log", autoformat='false'] - stt [type=start, class = "hidden", autoformat='false']; - -} diff --git a/TTT1.png b/TTT1.png deleted file mode 100644 index d9b8e54..0000000 Binary files a/TTT1.png and /dev/null differ diff --git a/TTT2.png b/TTT2.png deleted file mode 100644 index 3acdb83..0000000 Binary files a/TTT2.png and /dev/null differ diff --git a/TTT.flow b/Tests/TTT.flow similarity index 96% rename from TTT.flow rename to Tests/TTT.flow index c4f1e2a..4e2fa01 100644 --- a/TTT.flow +++ b/Tests/TTT.flow @@ -1,131 +1,131 @@ -blockdiag { -initialization_code=" - -global X -X=lambda i: 'X'+str(i) - -global O -O=lambda i: 'O'+str(i) - -global anyX -anyX = (lambda e: e[0]=='X') - -global anyMove -anyMove = (lambda e: anyX(e) or anyO(e)) - -global anyO -anyO = (lambda e: e[0]=='O') - -global toX -toX = (lambda e: 'X' + e[1:]) - -global toO -toO = (lambda e: 'O' + e[1:]) -" - event_selection_mechanism = "priority" - - lines [type=start, initial="[{1:1,2:2,3:3}, {1:4,2:5,3:6}, {1:7,2:8,3:9}, {1:1,2:4,3:7}, {1:2,2:5,3:8}, {1:3,2:6,3:9},{1:1,2:5,3:9},{1:3,2:5,3:7}]", width=350]; - perm [type=permutation, keys="[1,2,3]"] - - lines -> perm -> def_wt1 -> def_wt2 -> def_req; - - def_wt1 [type=sync, wait="[X(t[1])]", width=100, tokens_display="count only"] - def_wt2 [type=sync, wait="[X(t[2])]", width=150, tokens_display="count only"] - def_req [type=sync, req="[O(t[3])]", width=150, tokens_display="count only"] - - ######################################################################## - - perm -> ofn_wt1 -> ofn_wt2 -> ofn_req; - - ofn_wt1 [type=sync, wait="[O(t[1])]", width=100, tokens_display="count only"] - ofn_wt2 [type=sync, wait="[O(t[2])]", width=150, tokens_display="count only"] - ofn_req [type=sync, req="[O(t[3])]", priority=10, width=150, tokens_display="count only"] - - ######################################################################## - - perm -> owin_wt1 -> owin_wt2 -> owin_wt3 -> owin_req; - - owin_wt1 [type=sync, wait="[O(t[1])]", width=100, tokens_display="count only"] - owin_wt2 [type=sync, wait="[O(t[2])]", width=150, tokens_display="count only"] - owin_wt3 [type=sync, wait="[O(t[3])]", width=150, tokens_display="count only"] - owin_req [type=sync, req="['Player O wins']", block=anyMove, priority=100, width=150] - - ######################################################################## - - perm -> xwin_wt1 -> xwin_wt2 ->xwin_wt3 -> xwin_req; - - xwin_wt1 [type=sync, wait="[X(t[1])]", width=100, tokens_display="count only"] - xwin_wt2 [type=sync, wait="[X(t[2])]", width=150, tokens_display="count only"] - xwin_wt3 [type=sync, wait="[X(t[3])]", width=150, tokens_display="count only"] - xwin_req [type=sync, req="['Player X wins']", block=anyMove, priority=100, width=150] - - ######################################################################## - - tie_st -> tie_loop -> tie_wait -> tie_loop - tie_loop -> tie_req [label=after] - - tie_st [type=start] - tie_loop [type=loop, count=9, width=200] - tie_wait [type=sync, wait=anyMove] - tie_req [type=sync, req="['No winner']", priority=100] - - - ######################################################################## - - int_st -> int_1 -> int_2 -> int_1; - - int_st [type=start] - int_1 [type=sync, wait=anyX, block=anyO, width=100] - int_2 [type=sync, wait=anyO, block=anyX, width=100] - - ########### - - once_st -> once_wt -> once_bl - once_wt -> once_wt - once_st [type=start] - once_wt [type=sync, wait=anyMove] - once_bl [type=sync, block="[toX(t['event']), toO(t['event'])]", width=300, tokens_display="full with event"] - - - ############ - - st -> rq1 - st [type=start] - rq1 [type=sync, req="['O5']", priority="-1"] - - st -> rq2 -> rq2 - rq2 [type=sync, req="['O1','O3','O7','O9']", priority="-2", width=200] - - st -> rq3 -> rq3 - rq3 [type=sync, req="['O2','O4','O6','O8']", priority="-3", width=200] - - - -run=" -run_init(diagram) -setup_diagram(diagram) - -print_state(False) - -board = [' ' for i in range(9)] - -while True: - while step_to_next_state(diagram): print_state(False) - - try: - e = select_event(diagram) - except: - e = 'X'+input('Enter cell number to put X in:') - - if e[0] in ['O','X'] and e[1] in ['1','2','3','4','5','6','7','8','9']: - board[int(e[1])-1] = e[0] - print( '\n-----\n'.join([ '|'.join(board[i*3:(i+1)*3]) for i in range(3)])) - print() - wake_up_tokens(diagram, e) - else: - print('Game ended: ' + e) - break -" - - -} +blockdiag { +initialization_code=" + +global X +X=lambda i: 'X'+str(i) + +global O +O=lambda i: 'O'+str(i) + +global anyX +anyX = (lambda e: e[0]=='X') + +global anyMove +anyMove = (lambda e: anyX(e) or anyO(e)) + +global anyO +anyO = (lambda e: e[0]=='O') + +global toX +toX = (lambda e: 'X' + e[1:]) + +global toO +toO = (lambda e: 'O' + e[1:]) +" + event_selection_mechanism = "priority" + + lines [type=start, initial="[{1:1,2:2,3:3}, {1:4,2:5,3:6}, {1:7,2:8,3:9}, {1:1,2:4,3:7}, {1:2,2:5,3:8}, {1:3,2:6,3:9},{1:1,2:5,3:9},{1:3,2:5,3:7}]", width=350]; + perm [type=permutation, keys="[1,2,3]"] + + lines -> perm -> def_wt1 -> def_wt2 -> def_req; + + def_wt1 [type=sync, wait="[X(t[1])]", width=100, tokens_display="count only"] + def_wt2 [type=sync, wait="[X(t[2])]", width=150, tokens_display="count only"] + def_req [type=sync, req="[O(t[3])]", width=150, tokens_display="count only"] + + ######################################################################## + + perm -> ofn_wt1 -> ofn_wt2 -> ofn_req; + ofn_wt1 [type=sync, wait="[O(t[1])]", width=100, tokens_display="count only"] + ofn_wt2 [type=sync, wait="[O(t[2])]", width=150, tokens_display="count only"] + ofn_req [type=sync, req="[O(t[3])]", priority=10, width=150, tokens_display="count only"] + + ######################################################################## + perm -> owin_wt1 -> owin_wt2 -> owin_wt3 -> owin_req; + + owin_wt1 [type=sync, wait="[O(t[1])]", width=100, tokens_display="count only"] + owin_wt2 [type=sync, wait="[O(t[2])]", width=150, tokens_display="count only"] + owin_wt3 [type=sync, wait="[O(t[3])]", width=150, tokens_display="count only"] + owin_req [type=sync, req="['Player O wins']", block=anyMove, priority=100, width=150] + + ######################################################################## + + perm -> xwin_wt1 -> xwin_wt2 ->xwin_wt3 -> xwin_req; + + xwin_wt1 [type=sync, wait="[X(t[1])]", width=100, tokens_display="count only"] + xwin_wt2 [type=sync, wait="[X(t[2])]", width=150, tokens_display="count only"] + xwin_wt3 [type=sync, wait="[X(t[3])]", width=150, tokens_display="count only"] + xwin_req [type=sync, req="['Player X wins']", block=anyMove, priority=100, width=150] + + ######################################################################## + + + tie_st -> tie_loop -> tie_wait -> tie_loop + tie_loop -> tie_req [label=after] + + + tie_st [type=start] + tie_loop [type=loop, count=9, width=200] + tie_wait [type=sync, wait=anyMove] + tie_req [type=sync, req="['No winner']", priority=100] + + + ######################################################################## + + int_st -> int_1 -> int_2 -> int_1; + + int_st [type=start] + int_1 [type=sync, wait=anyX, block=anyO, width=100] + int_2 [type=sync, wait=anyO, block=anyX, width=100] + + ########### + + once_st -> once_wt -> once_bl + once_wt -> once_wt + once_st [type=start] + once_wt [type=sync, wait=anyMove] + once_bl [type=sync, block="[toX(t['event']), toO(t['event'])]", width=300, tokens_display="full with event"] + + + ############ + + st -> rq1 + st [type=start] + rq1 [type=sync, req="['O5']", priority="-1"] + + st -> rq2 -> rq2 + rq2 [type=sync, req="['O1','O3','O7','O9']", priority="-2", width=200] + + st -> rq3 -> rq3 + rq3 [type=sync, req="['O2','O4','O6','O8']", priority="-3", width=200] + + + +run=" +run_init(diagram) +setup_diagram(diagram) + +print_state(False) + +board = [' ' for i in range(9)] + +while True: + while step_to_next_state(diagram): print_state(False) + + try: + e = select_event(diagram) + except: + e = 'X'+input('Enter cell number to put X in:') + + if e[0] in ['O','X'] and e[1] in ['1','2','3','4','5','6','7','8','9']: + board[int(e[1])-1] = e[0] + print( '\n-----\n'.join([ '|'.join(board[i*3:(i+1)*3]) for i in range(3)])) + print() + wake_up_tokens(diagram, e) + else: + print('Game ended: ' + e) + break +" + + +} diff --git a/TTT.png b/Tests/TTT.png similarity index 100% rename from TTT.png rename to Tests/TTT.png diff --git a/TTT2.flow b/Tests/TTT2.flow similarity index 95% rename from TTT2.flow rename to Tests/TTT2.flow index c01cb37..dee18e9 100644 --- a/TTT2.flow +++ b/Tests/TTT2.flow @@ -1,24 +1,24 @@ -blockdiag { - st -> join -> req; - - st [type=start, initial="[{1:'1'},{2:'2'},{3:'3'}]"]; - join [type=join] - req [type=sync, req="['O'+t[3]]"] - - - - - - - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> "Event viewer" -> listener [style = "none"]; - - listener [type=sync, - wait="['X'+str(i) for i in range(1,9)]+['O'+str(i) for i in range(1,9)]", - class = "hidden", autoformat='false']; - - stt [type=start, class = "hidden", autoformat='false']; - -} +blockdiag { + st -> join -> req; + + st [type=start, initial="[{1:'1'},{2:'2'},{3:'3'}]"]; + join [type=join] + req [type=sync, req="['O'+t[3]]"] + + + + + + + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> "Event viewer" -> listener [style = "none"]; + + listener [type=sync, + wait="['X'+str(i) for i in range(1,9)]+['O'+str(i) for i in range(1,9)]", + class = "hidden", autoformat='false']; + + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/TTT3.flow b/Tests/TTT3.flow similarity index 96% rename from TTT3.flow rename to Tests/TTT3.flow index 9c4191f..9842f0f 100644 --- a/TTT3.flow +++ b/Tests/TTT3.flow @@ -1,30 +1,30 @@ -blockdiag { - st -> wait -> waitforset -> req1; - wait -> wait; - - - st [type=start]; - wait [type=sync, wait = "['X1','X2','X3']"] - # waitforset [type=waitforset, set="[{'event':'X1'},{'event':'X2'}, {'event':'X3'}]", threshold=2] - waitforset [type=waitforset, set="[{'event':'X'+str(i)} for i in range(1,10) ]", threshold=2] - req1 [type=sync, req="['@']"] - - st -> req2 -> req3; - - req2 [type=sync, req="['X1']"] - req3 [type=sync, req="['X3']"] - - - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> logger -> listener [style = "none"]; - - listener [type=sync, - wait="['X'+str(i) for i in range(1,9)]+['O'+str(i) for i in range(1,9)] + ['@']", - class = "hidden", autoformat='false']; - - logger [type=logger, label="Events log", autoformat='false'] - stt [type=start, class = "hidden", autoformat='false']; - -} +blockdiag { + st -> wait -> waitforset -> req1; + wait -> wait; + + + st [type=start]; + wait [type=sync, wait = "['X1','X2','X3']"] + # waitforset [type=waitforset, set="[{'event':'X1'},{'event':'X2'}, {'event':'X3'}]", threshold=2] + waitforset [type=waitforset, set="[{'event':'X'+str(i)} for i in range(1,10) ]", threshold=2] + req1 [type=sync, req="['@']"] + + st -> req2 -> req3; + + req2 [type=sync, req="['X1']"] + req3 [type=sync, req="['X3']"] + + + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + + listener [type=sync, + wait="['X'+str(i) for i in range(1,9)]+['O'+str(i) for i in range(1,9)] + ['@']", + class = "hidden", autoformat='false']; + + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/TTT3.png b/Tests/TTT3.png similarity index 100% rename from TTT3.png rename to Tests/TTT3.png diff --git a/Tests/TTT3_run/1.png b/Tests/TTT3_run/1.png new file mode 100644 index 0000000..2b2eaf5 Binary files /dev/null and b/Tests/TTT3_run/1.png differ diff --git a/Tests/TTT3_run/2.png b/Tests/TTT3_run/2.png new file mode 100644 index 0000000..2418f9c Binary files /dev/null and b/Tests/TTT3_run/2.png differ diff --git a/Tests/TTT3_run/3.png b/Tests/TTT3_run/3.png new file mode 100644 index 0000000..e6b4b95 Binary files /dev/null and b/Tests/TTT3_run/3.png differ diff --git a/Tests/TTT3_run/4.png b/Tests/TTT3_run/4.png new file mode 100644 index 0000000..5d7ae1b Binary files /dev/null and b/Tests/TTT3_run/4.png differ diff --git a/Tests/TTT3_run/5.png b/Tests/TTT3_run/5.png new file mode 100644 index 0000000..447026a Binary files /dev/null and b/Tests/TTT3_run/5.png differ diff --git a/Tests/TTT3_run/6.png b/Tests/TTT3_run/6.png new file mode 100644 index 0000000..f28aab8 Binary files /dev/null and b/Tests/TTT3_run/6.png differ diff --git a/Tests/TTT3_run/7.png b/Tests/TTT3_run/7.png new file mode 100644 index 0000000..a063d56 Binary files /dev/null and b/Tests/TTT3_run/7.png differ diff --git a/Tests/TTT3_run/8.png b/Tests/TTT3_run/8.png new file mode 100644 index 0000000..a063d56 Binary files /dev/null and b/Tests/TTT3_run/8.png differ diff --git a/Tests/TTT_run/1.png b/Tests/TTT_run/1.png new file mode 100644 index 0000000..c5bf561 Binary files /dev/null and b/Tests/TTT_run/1.png differ diff --git a/Tests/TTT_run/2.png b/Tests/TTT_run/2.png new file mode 100644 index 0000000..14c9658 Binary files /dev/null and b/Tests/TTT_run/2.png differ diff --git a/Tests/hotcold1.flow b/Tests/hotcold1.flow new file mode 100644 index 0000000..c75ad4f --- /dev/null +++ b/Tests/hotcold1.flow @@ -0,0 +1,25 @@ +diagram { + st1 -> lp1 -> bs1 -> lp1; + st2 -> lp2 -> bs2 -> lp2; + st3 -> in1 -> in2 -> in1; + + st1 [type=start]; + bs1 [type=sync, req="['hot']"]; + lp1 [type=loop, count=3]; + + st2 [type=start]; + bs2 [type=sync, req="['cold']"]; + lp2 [type=loop, count=3]; + + st3 [type=start]; + in1 [type=sync, wait="['hot']", block="['cold']"]; + in2 [type=sync, wait="['cold']", block="['hot']"]; + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/Tests/hotcold1.png b/Tests/hotcold1.png new file mode 100644 index 0000000..4d39618 Binary files /dev/null and b/Tests/hotcold1.png differ diff --git a/Tests/hotcold1_run/1.png b/Tests/hotcold1_run/1.png new file mode 100644 index 0000000..40e966f Binary files /dev/null and b/Tests/hotcold1_run/1.png differ diff --git a/Tests/hotcold1_run/10.png b/Tests/hotcold1_run/10.png new file mode 100644 index 0000000..5087e29 Binary files /dev/null and b/Tests/hotcold1_run/10.png differ diff --git a/Tests/hotcold1_run/11.png b/Tests/hotcold1_run/11.png new file mode 100644 index 0000000..e58fba7 Binary files /dev/null and b/Tests/hotcold1_run/11.png differ diff --git a/Tests/hotcold1_run/12.png b/Tests/hotcold1_run/12.png new file mode 100644 index 0000000..3f5dd44 Binary files /dev/null and b/Tests/hotcold1_run/12.png differ diff --git a/Tests/hotcold1_run/13.png b/Tests/hotcold1_run/13.png new file mode 100644 index 0000000..85bb2a8 Binary files /dev/null and b/Tests/hotcold1_run/13.png differ diff --git a/Tests/hotcold1_run/14.png b/Tests/hotcold1_run/14.png new file mode 100644 index 0000000..8177bae Binary files /dev/null and b/Tests/hotcold1_run/14.png differ diff --git a/Tests/hotcold1_run/15.png b/Tests/hotcold1_run/15.png new file mode 100644 index 0000000..374ab4a Binary files /dev/null and b/Tests/hotcold1_run/15.png differ diff --git a/Tests/hotcold1_run/2.png b/Tests/hotcold1_run/2.png new file mode 100644 index 0000000..2b3eb3f Binary files /dev/null and b/Tests/hotcold1_run/2.png differ diff --git a/Tests/hotcold1_run/3.png b/Tests/hotcold1_run/3.png new file mode 100644 index 0000000..25e8057 Binary files /dev/null and b/Tests/hotcold1_run/3.png differ diff --git a/Tests/hotcold1_run/4.png b/Tests/hotcold1_run/4.png new file mode 100644 index 0000000..d4e2b5b Binary files /dev/null and b/Tests/hotcold1_run/4.png differ diff --git a/Tests/hotcold1_run/5.png b/Tests/hotcold1_run/5.png new file mode 100644 index 0000000..ab889ab Binary files /dev/null and b/Tests/hotcold1_run/5.png differ diff --git a/Tests/hotcold1_run/6.png b/Tests/hotcold1_run/6.png new file mode 100644 index 0000000..74c3b2c Binary files /dev/null and b/Tests/hotcold1_run/6.png differ diff --git a/Tests/hotcold1_run/7.png b/Tests/hotcold1_run/7.png new file mode 100644 index 0000000..effa0d1 Binary files /dev/null and b/Tests/hotcold1_run/7.png differ diff --git a/Tests/hotcold1_run/8.png b/Tests/hotcold1_run/8.png new file mode 100644 index 0000000..3b87807 Binary files /dev/null and b/Tests/hotcold1_run/8.png differ diff --git a/Tests/hotcold1_run/9.png b/Tests/hotcold1_run/9.png new file mode 100644 index 0000000..64adb6b Binary files /dev/null and b/Tests/hotcold1_run/9.png differ diff --git a/hotcold2.flow b/Tests/hotcold2.flow similarity index 95% rename from hotcold2.flow rename to Tests/hotcold2.flow index e5e9ef3..5a807c3 100644 --- a/hotcold2.flow +++ b/Tests/hotcold2.flow @@ -1,29 +1,29 @@ -blockdiag { - st1 -> lp1 -> bs11 -> lp1; - st2 -> lp2 -> bs21 -> lp2; - st3 -> in1 -> in2 -> in1; - lp1 -> bs12 [label=after]; - lp2 -> bs22 [label=after]; - - st1 [type=start]; - bs11 [type=sync, req="['hot']"]; - lp1 [type=loop, count=3]; - bs12 [type=sync, req="['done']"]; - - st2 [type=start]; - bs21 [type=sync, req="['cold']", block="['done']"]; - lp2 [type=loop, count=3]; - bs22 [type=sync, req="['done']"]; - - st3 [type=start]; - in1 [type=sync, wait="['hot']", block="['cold']"]; - in2 [type=sync, wait="['cold']", block="['hot']"]; - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> logger -> listener [style = "none"]; - listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; - logger [type=logger, label="Events log", autoformat='false'] - stt [type=start, class = "hidden", autoformat='false']; - -} +daigram { + st1 -> lp1 -> bs11 -> lp1; + st2 -> lp2 -> bs21 -> lp2; + st3 -> in1 -> in2 -> in1; + lp1 -> bs12 [label=after]; + lp2 -> bs22 [label=after]; + + st1 [type=start]; + bs11 [type=sync, req="['hot']"]; + lp1 [type=loop, count=3]; + bs12 [type=sync, req="['done']"]; + + st2 [type=start]; + bs21 [type=sync, req="['cold']", block="['done']"]; + lp2 [type=loop, count=3]; + bs22 [type=sync, req="['done']"]; + + st3 [type=start]; + in1 [type=sync, wait="['hot']", block="['cold']"]; + in2 [type=sync, wait="['cold']", block="['hot']"]; + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/hotcold2.png b/Tests/hotcold2.png similarity index 100% rename from hotcold2.png rename to Tests/hotcold2.png diff --git a/Tests/hotcold2_run/1.png b/Tests/hotcold2_run/1.png new file mode 100644 index 0000000..bbdb26f Binary files /dev/null and b/Tests/hotcold2_run/1.png differ diff --git a/Tests/hotcold2_run/10.png b/Tests/hotcold2_run/10.png new file mode 100644 index 0000000..4e546b3 Binary files /dev/null and b/Tests/hotcold2_run/10.png differ diff --git a/Tests/hotcold2_run/11.png b/Tests/hotcold2_run/11.png new file mode 100644 index 0000000..0043833 Binary files /dev/null and b/Tests/hotcold2_run/11.png differ diff --git a/Tests/hotcold2_run/12.png b/Tests/hotcold2_run/12.png new file mode 100644 index 0000000..cb01757 Binary files /dev/null and b/Tests/hotcold2_run/12.png differ diff --git a/Tests/hotcold2_run/13.png b/Tests/hotcold2_run/13.png new file mode 100644 index 0000000..bddb229 Binary files /dev/null and b/Tests/hotcold2_run/13.png differ diff --git a/Tests/hotcold2_run/14.png b/Tests/hotcold2_run/14.png new file mode 100644 index 0000000..e73c911 Binary files /dev/null and b/Tests/hotcold2_run/14.png differ diff --git a/Tests/hotcold2_run/15.png b/Tests/hotcold2_run/15.png new file mode 100644 index 0000000..43106a4 Binary files /dev/null and b/Tests/hotcold2_run/15.png differ diff --git a/Tests/hotcold2_run/16.png b/Tests/hotcold2_run/16.png new file mode 100644 index 0000000..89a6096 Binary files /dev/null and b/Tests/hotcold2_run/16.png differ diff --git a/Tests/hotcold2_run/17.png b/Tests/hotcold2_run/17.png new file mode 100644 index 0000000..89a6096 Binary files /dev/null and b/Tests/hotcold2_run/17.png differ diff --git a/Tests/hotcold2_run/2.png b/Tests/hotcold2_run/2.png new file mode 100644 index 0000000..f8f1020 Binary files /dev/null and b/Tests/hotcold2_run/2.png differ diff --git a/Tests/hotcold2_run/3.png b/Tests/hotcold2_run/3.png new file mode 100644 index 0000000..58580b2 Binary files /dev/null and b/Tests/hotcold2_run/3.png differ diff --git a/Tests/hotcold2_run/4.png b/Tests/hotcold2_run/4.png new file mode 100644 index 0000000..3f8ae17 Binary files /dev/null and b/Tests/hotcold2_run/4.png differ diff --git a/Tests/hotcold2_run/5.png b/Tests/hotcold2_run/5.png new file mode 100644 index 0000000..f2a0c3a Binary files /dev/null and b/Tests/hotcold2_run/5.png differ diff --git a/Tests/hotcold2_run/6.png b/Tests/hotcold2_run/6.png new file mode 100644 index 0000000..1bac850 Binary files /dev/null and b/Tests/hotcold2_run/6.png differ diff --git a/Tests/hotcold2_run/7.png b/Tests/hotcold2_run/7.png new file mode 100644 index 0000000..37c424f Binary files /dev/null and b/Tests/hotcold2_run/7.png differ diff --git a/Tests/hotcold2_run/8.png b/Tests/hotcold2_run/8.png new file mode 100644 index 0000000..3599a6b Binary files /dev/null and b/Tests/hotcold2_run/8.png differ diff --git a/Tests/hotcold2_run/9.png b/Tests/hotcold2_run/9.png new file mode 100644 index 0000000..6c000d7 Binary files /dev/null and b/Tests/hotcold2_run/9.png differ diff --git a/hotcold3.flow b/Tests/hotcold3.flow similarity index 96% rename from hotcold3.flow rename to Tests/hotcold3.flow index afd728a..ea46990 100644 --- a/hotcold3.flow +++ b/Tests/hotcold3.flow @@ -1,23 +1,23 @@ -blockdiag { - st1 -> lp1 -> bs1 -> lp1; - st1 -> lp1 -> bs2 -> lp1; - st1 -> in1 -> in2 -> in1; - - st1 [type=start]; - bs1 [type=sync, req="['hot']"]; - lp1 [type=loop, count=3, width=200]; - - bs2 [type=sync, req="['cold']"]; - - in1 [type=sync, wait="['hot']", block="['cold']"]; - in2 [type=sync, wait="['cold']", block="['hot']"]; - - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> logger -> listener [style = "none"]; - listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; - logger [type=logger, label="Events log", autoformat='false'] - stt [type=start, class = "hidden", autoformat='false']; - -} +blockdiag { + st1 -> lp1 -> bs1 -> lp1; + st1 -> lp1 -> bs2 -> lp1; + st1 -> in1 -> in2 -> in1; + + st1 [type=start]; + bs1 [type=sync, req="['hot']"]; + lp1 [type=loop, count=3, width=200]; + + bs2 [type=sync, req="['cold']"]; + + in1 [type=sync, wait="['hot']", block="['cold']"]; + in2 [type=sync, wait="['cold']", block="['hot']"]; + + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/hotcold3.png b/Tests/hotcold3.png similarity index 100% rename from hotcold3.png rename to Tests/hotcold3.png diff --git a/Tests/hotcold3_run/1.png b/Tests/hotcold3_run/1.png new file mode 100644 index 0000000..c95ea30 Binary files /dev/null and b/Tests/hotcold3_run/1.png differ diff --git a/Tests/hotcold3_run/10.png b/Tests/hotcold3_run/10.png new file mode 100644 index 0000000..2712e3a Binary files /dev/null and b/Tests/hotcold3_run/10.png differ diff --git a/Tests/hotcold3_run/11.png b/Tests/hotcold3_run/11.png new file mode 100644 index 0000000..3ef6354 Binary files /dev/null and b/Tests/hotcold3_run/11.png differ diff --git a/Tests/hotcold3_run/12.png b/Tests/hotcold3_run/12.png new file mode 100644 index 0000000..c250010 Binary files /dev/null and b/Tests/hotcold3_run/12.png differ diff --git a/Tests/hotcold3_run/13.png b/Tests/hotcold3_run/13.png new file mode 100644 index 0000000..57a521f Binary files /dev/null and b/Tests/hotcold3_run/13.png differ diff --git a/Tests/hotcold3_run/14.png b/Tests/hotcold3_run/14.png new file mode 100644 index 0000000..5e466cf Binary files /dev/null and b/Tests/hotcold3_run/14.png differ diff --git a/Tests/hotcold3_run/15.png b/Tests/hotcold3_run/15.png new file mode 100644 index 0000000..5bbaf56 Binary files /dev/null and b/Tests/hotcold3_run/15.png differ diff --git a/Tests/hotcold3_run/2.png b/Tests/hotcold3_run/2.png new file mode 100644 index 0000000..5c9e3ca Binary files /dev/null and b/Tests/hotcold3_run/2.png differ diff --git a/Tests/hotcold3_run/3.png b/Tests/hotcold3_run/3.png new file mode 100644 index 0000000..950c679 Binary files /dev/null and b/Tests/hotcold3_run/3.png differ diff --git a/Tests/hotcold3_run/4.png b/Tests/hotcold3_run/4.png new file mode 100644 index 0000000..c53324b Binary files /dev/null and b/Tests/hotcold3_run/4.png differ diff --git a/Tests/hotcold3_run/5.png b/Tests/hotcold3_run/5.png new file mode 100644 index 0000000..657c7c6 Binary files /dev/null and b/Tests/hotcold3_run/5.png differ diff --git a/Tests/hotcold3_run/6.png b/Tests/hotcold3_run/6.png new file mode 100644 index 0000000..bd71ad2 Binary files /dev/null and b/Tests/hotcold3_run/6.png differ diff --git a/Tests/hotcold3_run/7.png b/Tests/hotcold3_run/7.png new file mode 100644 index 0000000..f3d624e Binary files /dev/null and b/Tests/hotcold3_run/7.png differ diff --git a/Tests/hotcold3_run/8.png b/Tests/hotcold3_run/8.png new file mode 100644 index 0000000..cae9fc9 Binary files /dev/null and b/Tests/hotcold3_run/8.png differ diff --git a/Tests/hotcold3_run/9.png b/Tests/hotcold3_run/9.png new file mode 100644 index 0000000..cab5215 Binary files /dev/null and b/Tests/hotcold3_run/9.png differ diff --git a/hotcold4.flow b/Tests/hotcold4.flow similarity index 97% rename from hotcold4.flow rename to Tests/hotcold4.flow index 16cadc0..124650f 100644 --- a/hotcold4.flow +++ b/Tests/hotcold4.flow @@ -1,16 +1,16 @@ -blockdiag { - st -> lp -> bs1 -> bs2 -> lp; - - st [type=start]; - bs1 [type=sync, req="['hot']"]; - bs2 [type=sync, req="['cold']"]; - lp [type=loop, count=3]; - - # For debugging - class hidden [color = none, style = none, textcolor = white]; - stt -> listener -> logger -> listener [style = "none"]; - listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; - logger [type=logger, label="Events log", autoformat='false'] - stt [type=start, class = "hidden", autoformat='false']; - -} +blockdiag { + st -> lp -> bs1 -> bs2 -> lp; + + st [type=start]; + bs1 [type=sync, req="['hot']"]; + bs2 [type=sync, req="['cold']"]; + lp [type=loop, count=3]; + + # For debugging + class hidden [color = none, style = none, textcolor = white]; + stt -> listener -> logger -> listener [style = "none"]; + listener [type=sync, wait="lambda e : True", class = "hidden", autoformat='false']; + logger [type=logger, label="Events log", autoformat='false'] + stt [type=start, class = "hidden", autoformat='false']; + +} diff --git a/hotcold4.png b/Tests/hotcold4.png similarity index 100% rename from hotcold4.png rename to Tests/hotcold4.png diff --git a/Tests/hotcold4_run/1.png b/Tests/hotcold4_run/1.png new file mode 100644 index 0000000..27b55e3 Binary files /dev/null and b/Tests/hotcold4_run/1.png differ diff --git a/Tests/hotcold4_run/10.png b/Tests/hotcold4_run/10.png new file mode 100644 index 0000000..3bdac2f Binary files /dev/null and b/Tests/hotcold4_run/10.png differ diff --git a/Tests/hotcold4_run/11.png b/Tests/hotcold4_run/11.png new file mode 100644 index 0000000..9dbaf21 Binary files /dev/null and b/Tests/hotcold4_run/11.png differ diff --git a/Tests/hotcold4_run/12.png b/Tests/hotcold4_run/12.png new file mode 100644 index 0000000..5f5e4c4 Binary files /dev/null and b/Tests/hotcold4_run/12.png differ diff --git a/Tests/hotcold4_run/13.png b/Tests/hotcold4_run/13.png new file mode 100644 index 0000000..5f5e4c4 Binary files /dev/null and b/Tests/hotcold4_run/13.png differ diff --git a/Tests/hotcold4_run/14.png b/Tests/hotcold4_run/14.png new file mode 100644 index 0000000..cb5d879 Binary files /dev/null and b/Tests/hotcold4_run/14.png differ diff --git a/Tests/hotcold4_run/15.png b/Tests/hotcold4_run/15.png new file mode 100644 index 0000000..37c25d6 Binary files /dev/null and b/Tests/hotcold4_run/15.png differ diff --git a/Tests/hotcold4_run/2.png b/Tests/hotcold4_run/2.png new file mode 100644 index 0000000..b98a96d Binary files /dev/null and b/Tests/hotcold4_run/2.png differ diff --git a/Tests/hotcold4_run/3.png b/Tests/hotcold4_run/3.png new file mode 100644 index 0000000..e5160fd Binary files /dev/null and b/Tests/hotcold4_run/3.png differ diff --git a/Tests/hotcold4_run/4.png b/Tests/hotcold4_run/4.png new file mode 100644 index 0000000..604061e Binary files /dev/null and b/Tests/hotcold4_run/4.png differ diff --git a/Tests/hotcold4_run/5.png b/Tests/hotcold4_run/5.png new file mode 100644 index 0000000..604061e Binary files /dev/null and b/Tests/hotcold4_run/5.png differ diff --git a/Tests/hotcold4_run/6.png b/Tests/hotcold4_run/6.png new file mode 100644 index 0000000..325ce4b Binary files /dev/null and b/Tests/hotcold4_run/6.png differ diff --git a/Tests/hotcold4_run/7.png b/Tests/hotcold4_run/7.png new file mode 100644 index 0000000..b9aff76 Binary files /dev/null and b/Tests/hotcold4_run/7.png differ diff --git a/Tests/hotcold4_run/8.png b/Tests/hotcold4_run/8.png new file mode 100644 index 0000000..d018e49 Binary files /dev/null and b/Tests/hotcold4_run/8.png differ diff --git a/Tests/hotcold4_run/9.png b/Tests/hotcold4_run/9.png new file mode 100644 index 0000000..d018e49 Binary files /dev/null and b/Tests/hotcold4_run/9.png differ diff --git a/Tests/propose-approve.flow b/Tests/propose-approve.flow new file mode 100644 index 0000000..18d4658 --- /dev/null +++ b/Tests/propose-approve.flow @@ -0,0 +1,12 @@ +blockdiag { + st -> wt1 + st -> st + wt1 -> wt2 + wt2 -> req [label=approve] + + + st [type=start]; + wt1 [type=sync, wait="p=propose(id?,grade)"]; + wt2 [type=sync, wait="[approve(p), approve(propose(id,?))]", width=200]; + req [type=sync, wait="['cold']", block="['hot']"]; +} diff --git a/Tests/propose-approve.png b/Tests/propose-approve.png new file mode 100644 index 0000000..a7d210f Binary files /dev/null and b/Tests/propose-approve.png differ diff --git a/Tests/propose-approve_run/1.png b/Tests/propose-approve_run/1.png new file mode 100644 index 0000000..6bf3e8a Binary files /dev/null and b/Tests/propose-approve_run/1.png differ diff --git a/Tests/testLiat.py b/Tests/testLiat.py new file mode 100644 index 0000000..f79eb2e --- /dev/null +++ b/Tests/testLiat.py @@ -0,0 +1,32 @@ +import matplotlib.pyplot as plt +import numpy as np +import scipy.stats +from sympy import * +from sympy.stats import Normal, E, Expectation, where +from sympy.abc import x + + +def d2aExpctation(thresholds, levels): + levels = len(thresholds) + + X1 = Normal('X1', 0, 1) + X2 = Normal('X2', 0, 1) + + print(E(X1 + X2, X1 < 10).simplify() ) + + print("thresholds=", thresholds) + arr = [(i, x <= thresholds[i]) for i in range(levels)] + [(levels, True)] + a2d = Lambda(x, Piecewise(*arr)) + + print(a2d) + for i in range(2 * levels - 1): + print(i, "-->") + if i==0: + print("\t", E(X1 + X2, And(Le(X1,thresholds[0]), Le(X2, thresholds[0]))).evalf(2)) + elif i==1: + print("\t", E(X1 + X2, (X1 < thresholds[0] and X2 < thresholds[1] and X2 > thresholds[0]) or (X2 < thresholds[0] and X1 < thresholds[1] and X1 > thresholds[0])).evalf(2)) + else: + print("\t", E(X1 + X2, Eq(a2d(X1) + a2d(X2), i)).evalf(2)) + + +d2aExpctation([-1.1, 0, 1.1], 0) \ No newline at end of file diff --git a/all.ps1 b/all.ps1 index d19cf62..4b72eb9 100644 Binary files a/all.ps1 and b/all.ps1 differ diff --git a/flow.py b/flow.py index 9dd0b7a..07a48eb 100644 --- a/flow.py +++ b/flow.py @@ -1,5 +1,9 @@ from blockdiag import parser, builder, drawer -import copy, random, sys, os, glob +import copy +import random +import sys +import os +import glob from NodeLibrary import * @@ -20,137 +24,162 @@ builder.DiagramNode.set = None builder.DiagramNode.threshold = None builder.DiagramNode.tokens_display = "full" -builder.DiagramNode.priority=0 +builder.DiagramNode.priority = 0 +builder.DiagramNode.join_by = [] +builder.DiagramNode.join = None builder.Diagram.run = None -builder.Diagram.initialization_code = None +builder.Diagram.initialization_code = "" builder.Diagram.event_selection_mechanism = 'random' -node_types = (StartType(), SyncType(), LoopType(), PassType(), PermutationType(), JoinType(), WaitForSetType(), LoggerType()) +node_types = (StartType(), SyncType(), LoopType(), PassType(), PermutationType(), + JoinType(), WaitForSetType(), LoggerType()) + + +def traverse_nodes(n): + if not hasattr(n, 'nodes'): + yield n + else: + for nn in n.nodes: + yield from traverse_nodes(nn) def setup_diagram(diagram): - for n in diagram.nodes: - n.pred = [] - - for nt in node_types: - if nt.type_string() == n.type: - n.node_type = nt - nt.node_manipulator(n) - - if n.node_type is None: - raise AttributeError("Unknown type '" + n.type + "'") - - build_predessessors_field(diagram) - print_diagram(diagram, sys.argv[1]) - create_run_directory() + global nodes + nodes = [n for n in traverse_nodes(diagram)] + + for n in nodes: + n.pred = [] + + for nt in node_types: + if nt.type_string() == n.type: + n.node_type = nt + nt.node_manipulator(n) + + if n.node_type is None: + raise AttributeError("Unknown type '" + n.type + "'") + + build_predessessors_field(diagram) + print_diagram(diagram, sys.argv[1]) + create_run_directory() def build_predessessors_field(diagram): - for e in diagram.edges: - e.node2.pred.append((e.node1, e.label)) + for e in diagram.traverse_edges(): + e.node2.pred.append((e.node1, e.label)) def print_diagram(diagram, file_name): - draw = drawer.DiagramDraw('PNG', diagram, file_name + ".png") - draw.draw() - draw.save() + draw = drawer.DiagramDraw('png', diagram, file_name + ".png") + draw.draw() + draw.save() def create_run_directory(): - try: - os.mkdir(sys.argv[1] + "_run") - except FileExistsError: - for f in glob.glob(sys.argv[1] + "_run/*"): - os.remove(f) + try: + os.mkdir(sys.argv[1] + "_run") + except FileExistsError: + for f in glob.glob(sys.argv[1] + "_run/*"): + os.remove(f) def print_state(terminal_output=True): - global statecount - statecount = statecount + 1 + global statecount + statecount = statecount + 1 + + if terminal_output: + print("--- State:", statecount, "---") + for n in nodes: + print(n.id, "-->", "tokens:", n.tokens, "sync:", n.sync) - if terminal_output: - print("--- State:", statecount, "---") - for n in diagram.nodes: - print(n.id, "-->", "tokens:", n.tokens, "sync:", n.sync) - - for n in diagram.nodes: - n.node_type.state_visualization(n) - - print_diagram(diagram, sys.argv[1] + "_run/" + str(statecount)) + for n in nodes: + n.node_type.state_visualization(n) + + print_diagram(diagram, sys.argv[1] + "_run/" + str(statecount)) def step_to_next_state(diagram): - tmp, changed = {}, False - for n in diagram.nodes: - tmp[n] = [t for pn, p in n.pred for t in pn.node_type.transformation(pn.tokens, pn, p)] - - for n in diagram.nodes: - tmp[n], n.sync = n.node_type.synchronization(tmp[n], n.sync, n) - if n.tokens != tmp[n]: changed = True - n.tokens = tmp[n] - - return changed + tmp, changed = {}, False + for n in nodes: + tmp[n] = [t for pn, p in n.pred for t in pn.node_type.transformation( + pn.tokens, pn, p)] + + for n in nodes: + tmp[n], n.sync = n.node_type.synchronization(tmp[n], n.sync, n) + if n.tokens != tmp[n]: + changed = True + n.tokens = tmp[n] + + return changed def select_event(diagram): - requested = [(r,n.priority) for n in diagram.nodes for sync in n.sync if 'REQ' in sync for r in sync['REQ']] - block_statements = [sync['BLOCK'] for n in diagram.nodes for sync in n.sync if 'BLOCK' in sync] - candidates = [(e,p) for (e,p) in requested if not any([b(e) for b in block_statements])] - - if diagram.event_selection_mechanism == 'random': - pass - elif diagram.event_selection_mechanism == 'priority': - p = max(candidates, key = lambda e: int(e[1]))[1] - candidates = [e for e in candidates if e[1]==p] - else: - raise Exception("Illegal value of event_selection_mechanism:" + diagram.event_selection_mechanism) + requested = [(r, n.priority) + for n in nodes for sync in n.sync if 'REQ' in sync for r in sync['REQ']] + block_statements = [sync['BLOCK'] + for n in nodes for sync in n.sync if 'BLOCK' in sync] + candidates = [(e, p) for (e, p) in requested if not any([b(e) + for b in block_statements])] + + if diagram.event_selection_mechanism == 'random': + pass + elif diagram.event_selection_mechanism == 'priority': + p = max(candidates, key=lambda e: int(e[1]))[1] + candidates = [e for e in candidates if e[1] == p] + else: + raise Exception("Illegal value of event_selection_mechanism:" + + diagram.event_selection_mechanism) - return random.choice(candidates)[0] + return random.choice(candidates)[0] def wake_up_tokens(diagram, e): - for n in diagram.traverse_nodes(): - keep = [] - for t in n.sync: - if ("REQ" in t and e in t["REQ"]) or ("WAIT" in t and t["WAIT"](e)): - t = copy.deepcopy(t) - if "REQ" in t: del t["REQ"] - if "WAIT" in t: del t["WAIT"] - if "BLOCK" in t: del t["BLOCK"] - t["event"] = e - n.tokens.append(t) - else: - keep.append(t) - n.sync = keep + for n in nodes: + keep = [] + for t in n.sync: + if ("REQ" in t and e in t["REQ"]) or ("WAIT" in t and t["WAIT"](e)): + t = copy.deepcopy(t) + if "REQ" in t: + del t["REQ"] + if "WAIT" in t: + del t["WAIT"] + if "BLOCK" in t: + del t["BLOCK"] + t["event"] = e + n.tokens.append(t) + else: + keep.append(t) + n.sync = keep def run_diagram(diagram): - setup_diagram(diagram) - - print_state() - - try: - while True: - while step_to_next_state(diagram): print_state() - - e = select_event(diagram) - print("********************** Event:", e, "***************************") - - wake_up_tokens(diagram, e) - except (ValueError, IndexError): - pass + setup_diagram(diagram) + + print_state() + + try: + while True: + while step_to_next_state(diagram): + print_state() + + e = select_event(diagram) + print("*** Event:", e, "***") + + wake_up_tokens(diagram, e) + except (ValueError, IndexError): + pass if __name__ == "__main__": - if len(sys.argv) != 2: - print("Usage: python flow.py [diagram file name without the .flow extension]") - else: - model = parser.parse_file(sys.argv[1] + ".flow") - diagram = builder.ScreenNodeBuilder.build(model) - - if diagram.run is None: - run_init(diagram) - run_diagram(diagram) + if len(sys.argv) != 2: + print( + "Usage: python flow.py [diagram file name without the .flow extension]") else: - exec(diagram.run) + model = parser.parse_file(sys.argv[1] + ".flow") + diagram = builder.ScreenNodeBuilder.build(model) + + if diagram.run is None: + run_init(diagram) + run_diagram(diagram) + else: + exec(diagram.run)