From 9c5959adbc11acba3c2375020b9cdb1c16960052 Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Fri, 24 Aug 2018 19:49:07 +0200 Subject: [PATCH 1/2] better dumping --- .gitignore | 2 + package.json | 4 +- simple-visualization.ipynb | 249 ++++++++++++++++++++++++++++++++++++ src/abstract-combinators.js | 36 ++++-- src/lambda-calculus.js | 4 +- src/main.js | 29 +++-- 6 files changed, 295 insertions(+), 29 deletions(-) create mode 100644 simple-visualization.ipynb diff --git a/.gitignore b/.gitignore index c2658d7..bf76261 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules/ +.* +lib/test.lam diff --git a/package.json b/package.json index 980d579..2b8c397 100644 --- a/package.json +++ b/package.json @@ -25,5 +25,7 @@ "url": "https://github.com/maiavictor/abstract-algorithm/issues" }, "homepage": "https://github.com/maiavictor/abstract-algorithm#readme", - "dependencies": {} + "dependencies": { + "numjs": "^0.16.0" + } } diff --git a/simple-visualization.ipynb b/simple-visualization.ipynb new file mode 100644 index 0000000..7370724 --- /dev/null +++ b/simple-visualization.ipynb @@ -0,0 +1,249 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "import matplotlib.pyplot as plt\n", + "from matplotlib.widgets import Slider\n", + "from networkx.drawing.nx_agraph import graphviz_layout\n", + "import ipywidgets as widgets" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from pandas import DataFrame\n", + "with open('absal-last-run.dump', 'r') as file:\n", + " history = [json.loads(line) for line in file.readlines()]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "754fc2aae03047ef81a0983b85da5667", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(IntSlider(value=24, description='iteration', max=49), Output()), _dom_classes=('widget-i…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "nodes = history[0]['nodes']\n", + "ports = [(i >> 2, t >> 2) for i, t in enumerate(nodes) if (i+1) % 4 != 0 and i >> 2 not in history[0]['reuse']]\n", + "\n", + "plt.figure(figsize=(10,10))\n", + "G = nx.DiGraph()\n", + "G.add_edges_from(ports)\n", + "pos = graphviz_layout(G)\n", + "\n", + "@widgets.interact(iteration=(0, len(history)-1))\n", + "def draw(iteration):\n", + " net = history[iteration]\n", + " nodes = net['nodes']\n", + "\n", + " ports = [(i >> 2, t >> 2) for i, t in enumerate(nodes) if (i+1) % 4 != 0 and i >> 2 not in net['reuse']]\n", + " types = [ t >> 2 for i, t in enumerate(nodes) if (i+1) % 4 == 0 and i >> 2 not in net['reuse']]\n", + " crrnt = (nodes[net['next']] >> 2, net['next'] >> 2)\n", + "\n", + "\n", + " plt.figure(figsize=(10,10))\n", + " \n", + " G = nx.DiGraph()\n", + " G.add_edges_from(ports)\n", + " pos = graphviz_layout(G, )\n", + " \n", + " nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), alpha=0.0, node_color = types, node_size = 500)\n", + " nx.draw_networkx_labels(G, pos)\n", + " nx.draw_networkx_edges(G, pos, edgelist=[crrnt], edge_color='grey', width=10) \n", + " nx.draw_networkx_edges(G, pos, edgelist=ports[0:-1:3], alpha=.5, edge_color='red', width=4)\n", + " nx.draw_networkx_edges(G, pos, edgelist=ports[1:-1:3], alpha=.5, edge_color='blue', width=4)\n", + " nx.draw_networkx_edges(G, pos, edgelist=ports[2:-1:3], alpha=.5, edge_color='grey', width=3)\n", + " plt.show()\n", + " print('reuse: ', net['reuse'])\n", + " print('warp: ', net['warp'])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function graphviz_layout in module networkx.drawing.nx_agraph:\n", + "\n", + "graphviz_layout(G, prog='neato', root=None, args='')\n", + " Create node positions for G using Graphviz.\n", + " \n", + " Parameters\n", + " ----------\n", + " G : NetworkX graph\n", + " A graph created with NetworkX\n", + " prog : string\n", + " Name of Graphviz layout program\n", + " root : string, optional\n", + " Root node for twopi layout\n", + " args : string, optional\n", + " Extra arguments to Graphviz layout program\n", + " \n", + " Returns : dictionary\n", + " Dictionary of x, y, positions keyed by node.\n", + " \n", + " Examples\n", + " --------\n", + " >>> G = nx.petersen_graph()\n", + " >>> pos = nx.nx_agraph.graphviz_layout(G)\n", + " >>> pos = nx.nx_agraph.graphviz_layout(G, prog='dot')\n", + " \n", + " Notes\n", + " -----\n", + " This is a wrapper for pygraphviz_layout.\n", + "\n" + ] + } + ], + "source": [ + "help(graphviz_layout)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/abstract-combinators.js b/src/abstract-combinators.js index 3875bea..61fda60 100644 --- a/src/abstract-combinators.js +++ b/src/abstract-combinators.js @@ -3,23 +3,25 @@ function port(node, slot) { } function node(port) { - return port >>> 2; + return port >> 2; } function slot(port) { return port & 3; } -function newNet(nodes) { +function newNet() { return { - nodes: nodes || [], + debug: null, + nodes: [], reuse: [], stats: {loops:0, rules:0, betas:0, dupls:0, annis:0} }; } function newNode(net, kind) { - var node = net.reuse.pop() || (net.nodes.length / 4); + var node = net.reuse.pop() || (net.nodes.length / 4); + if(net.debug) net.debug.chnge.add(node) net.nodes[node * 4 + 0] = node * 4 + 0; net.nodes[node * 4 + 1] = node * 4 + 1; net.nodes[node * 4 + 2] = node * 4 + 2; @@ -32,33 +34,34 @@ function enterPort(net, w) { } function kind(net, node) { - return net.nodes[node * 4 + 3] >>> 2; + return net.nodes[node * 4 + 3] >>> 2; } function exit(net, node) { - return (net.nodes[node * 4 + 3] >>> 0) & 3; + return (net.nodes[node * 4 + 3] >>> 0) & 3; } function setExit(net, node, exit) { - return net.nodes[node * 4 + 3] = net.nodes[node * 4 + 3] & 0xFFFFFFFC | exit; + return net.nodes[node * 4 + 3] = net.nodes[node * 4 + 3] & 0xFFFFFFFC | exit; } function link(net, a, b) { - net.nodes[a] = b; - net.nodes[b] = a; + net.nodes[a] = b; if (net.debug) net.debug.chnge.add(node(a)) + net.nodes[b] = a; if (net.debug) net.debug.chnge.add(node(b)) } function reduce(net) { var prev, back; var warp = []; var next = net.nodes[0]; + if (net.debug) net.debug.flush(); while (next || warp.length) { next = next || enterPort(net, port(warp.pop(), 2)); prev = enterPort(net, next); next = enterPort(net, prev); if (slot(next) === 0 && slot(prev) === 0 && node(prev)) { back = enterPort(net, port(node(prev), exit(net, node(prev)))); - rewrite(net, node(prev), node(next), net.stats); + rewrite(net, node(prev), node(next)); next = enterPort(net, back); } else if (slot(next) === 0) { warp.push(node(next)); @@ -69,19 +72,20 @@ function reduce(net) { next = enterPort(net, port(node(next), 0)); } ++net.stats.loops; + if(net.debug) net.debug.flush() } return net; } function rewrite(net, A, B) { - if (kind(net,A) === kind(net,B)) { + if (kind(net, A) === kind(net, B)) { // 1 2 1 2 // \ / \ / // A == B --> X // / \ / \ // 2 1 2 1 - link(net, enterPort(net, port(A, 1)), enterPort(net, port(B, 1))); - link(net, enterPort(net, port(A, 2)), enterPort(net, port(B, 2))); + link(net, enterPort(net, port(A, 1)), enterPort(net, port(B, 1))); + link(net, enterPort(net, port(A, 2)), enterPort(net, port(B, 2))); net.stats.betas += kind(net, A) === 1 ? 1 : 0; net.stats.annis += 1; net.reuse.push(A, B); @@ -108,6 +112,12 @@ function rewrite(net, A, B) { net.stats.rules += 1; } +function toJson(net, index) { + var node = { + + } +} + module.exports = { port, node, diff --git a/src/lambda-calculus.js b/src/lambda-calculus.js index b421534..d961e2e 100644 --- a/src/lambda-calculus.js +++ b/src/lambda-calculus.js @@ -77,9 +77,9 @@ const toString = (term, bruijn) => { return go(term, 0); }; -const toNet = term => { +const toNet = (net, term) => { var kind = 1; - var net = I.newNet([0, 2, 1, 4]); + I.newNode(net, kind); I.link(net, 1, 2); var ptr = (function encode(term, scope){ switch (term.tag){ // Arg diff --git a/src/main.js b/src/main.js index fed184d..a9a77c0 100755 --- a/src/main.js +++ b/src/main.js @@ -3,13 +3,14 @@ var fs = require("fs"); var path = require("path"); var L = require("./lambda-calculus.js"); +var A = require("./abstract-combinators.js"); try { var args = [].slice.call(process.argv, 2); var stats = args.indexOf("-s") !== -1 || args.indexOf("--stats") !== -1; var bruijn = args.indexOf("-b") !== -1 || args.indexOf("--bruijn") !== -1; var nobase = args.indexOf("-n") !== -1 || args.indexOf("--nobase") !== -1; - var dump = args.indexOf("-d") !== -1 || args.indexOf("--dump") !== -1; + var debug = args.indexOf("-d") !== -1 || args.indexOf("--debug") !== -1; var file = args[args.length - 1]; var base = fs.readFileSync(path.join(__dirname, "..", "lib", "base.lam"), "utf8"); var code = fs.readFileSync("./" + (file.indexOf(".") === -1 ? file + ".lam" : file), "utf8"); @@ -34,24 +35,26 @@ try { process.exit(); } -function print(net) { - for (var i=0; i < net.nodes.length; i+=4) { - if (net.reuse.some(x => x === i >> 2)) { - console.log(i>>2); - continue; +var net = A.newNet(); +if (debug) { + fs.writeFileSync('debug.txt', ''); + var file = fs.createWriteStream('debug.txt', {'flags':'a'}); + net.debug = { + chnge: new Set([]), + flush: () => { + net.debug.chnge.forEach( i => file.write(`${i} ${net.nodes[i+0]} ${net.nodes[i+1]} ${net.nodes[i+2]} ${net.nodes[i+3]}\n`)); + net.debug.chnge.clear() + file.write('\n'); } - [a,b,c,d] = net.nodes.slice(i, i+4); - console.log(i>>2, `${a>>2}:${a&3} ${b>>2}:${b&3} ${c>>2}:${c&3} ${d>>2}:${d&3}`); } } var start = Date.now(); -var net = L.toNet(L.fromString(nobase ? code : base + " " + code)); -if (dump) { print(net); } +var net = L.toNet(net, L.fromString(nobase ? code : base + " " + code)); var net = L.net.reduce(net); -if (dump) { print(net); } -var result = {term: L.toString(L.fromNet(net), bruijn), stats: net.stats}; -var time = Date.now() - start; +var result = { term: L.toString(L.fromNet(net), bruijn), stats: net.stats }; + +if (debug) file.end('') console.log(result.term); if (stats) { From a572a495de5ac96df8d99fc2af3b2a5a8e65ab53 Mon Sep 17 00:00:00 2001 From: Josef Vonasek Date: Sun, 26 Aug 2018 18:49:57 +0200 Subject: [PATCH 2/2] Finally working, but a little bit slow --- __pycache__/nodes.cpython-36.pyc | Bin 0 -> 2361 bytes debug.txt | 657 ++++++++++++++++++ nodes.py | 58 ++ src/abstract-combinators.js | 44 +- src/lambda-calculus.js | 2 +- src/main.js | 11 +- ...visualization.ipynb => visualization.ipynb | 58 +- 7 files changed, 774 insertions(+), 56 deletions(-) create mode 100644 __pycache__/nodes.cpython-36.pyc create mode 100644 debug.txt create mode 100644 nodes.py rename simple-visualization.ipynb => visualization.ipynb (74%) diff --git a/__pycache__/nodes.cpython-36.pyc b/__pycache__/nodes.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1fa8599f0e4bbd1ad0ad0ac393318c9858aabdca GIT binary patch literal 2361 zcmbVN&2Jk;6n``O;q}IGlQcw4fvDtEBe0M_Dhei4Pzk}oDzuV|X|-}a8+Q|XZO?9y z8?8CuD)dGX962K)apcUO!C|kQ@-O59zc(8@p{jadS8sM^-kbM(^S<`o=a+)kJP5VSn#8I^DXpbHDR2Np+{2zTN5fhB`_g4elHH z`sneg-%wFE?G6W{U5^c7{VpAC8~4E2f`Aw1)+COW=U|4@W&QlPAikZ!`V*5(0E-T6 zy`h}@)>KZdsU7>OG@nn7nV*RROaGc7bq=KdID-mASKNTv0Zp#6wJe3`BJ;TxrViFJ zLn`5GWln>}cUv^Mc0m#~0m+Jygv5t5{I4lK0FHEB}90b8K_{miagy2`CFDt^Ms@M?gAfB&@qt$tg7N-_*;!v)GOq`B! zMYS}QJ(^m`4V39jJ`+DYn%b$z?0q>yxx$amzBNPjKNFMBAFrf#u?EL&QM_SO>Kyp` zu7HG~+w>L1@*X-Bca}nO-<_GlpO)a=(!Q6uJv0sF{9ar>hTNd3goZLSczlwzsR}xQw@KJTw-l868MH!E8QsBtCiL~pDprtNKCrNJ z)tswh?VEE8zG+^U=JE~X%=vtLoLO^>@i8*4k(FTed($#xfTdQ9?uOC5dOW>qebI-i(2SnU(lBXUvV?M+%##G3%w{`E-lWSJD`MP*29&N*n&ef6F-`Ech)L$ zD~eOJJ}$!-r4V{pKT3)ocAfQ|^{}lXQ@A5t=wAy_q%{Mdr)Mtw|7D-%jD3lH`c?4x z7jfyhRh;wy^FRM<<0+EQ*0M`4`XC>EWU`Ck1f4ij#mT)jbHEXkMeq{Go?km;n+ zFvc%p)Q{4lJ-eL|G^nCpSJ`a8s8??<>W9tFAZ$B>&LmQ8CsvV4a+~*a$KV)u;olPu zhTnv_&3mvVR+HyST5}n{&iCEHK*GjbiWST~Q_?;PT8cHSDk$(Zysu$al~ojf zRa_BA{&@hKwUW6eEDVC&4}!r^9rk%%34-xqrym=RUICz9=dOzYt;p}GGt zCHzbBq*wARZ^i7Ma2qrEdcv*oRJ_rwIfj!9I8%4xUTCr~cSahC`6BhX*C_1UH5iOo L-EncLbzJaYND$aA literal 0 HcmV?d00001 diff --git a/debug.txt b/debug.txt new file mode 100644 index 0000000..4c76ee0 --- /dev/null +++ b/debug.txt @@ -0,0 +1,657 @@ + +4 +50 4 +0 4 2 1 4 +1 0 40 12 4 +2 26 13 21 4 +3 6 9 22 4 +4 13 18 17 0 +5 42 10 14 4 +6 28 41 8 4 +7 24 64 36 4 +8 50 37 45 4 +9 30 33 46 4 +10 5 25 20 8 +11 66 34 38 4 +12 52 65 32 4 +13 48 88 60 4 +14 74 61 69 4 +15 54 57 70 4 +16 29 49 44 16 +17 90 58 62 4 +18 76 89 56 4 +19 72 112 84 4 +20 98 85 93 4 +21 78 81 94 4 +22 53 73 68 24 +23 114 82 86 4 +24 100 113 80 4 +25 96 136 108 4 +26 122 109 117 4 +27 102 105 118 4 +28 77 97 92 32 +29 138 106 110 4 +30 124 137 104 4 +31 120 160 132 4 +32 146 133 141 4 +33 126 129 142 4 +34 101 121 116 40 +35 162 130 134 4 +36 148 161 128 4 +37 144 184 156 4 +38 170 157 165 4 +39 150 153 166 4 +40 125 145 140 48 +41 186 154 158 4 +42 172 185 152 4 +43 168 208 180 4 +44 194 181 189 4 +45 174 177 190 4 +46 149 169 164 56 +47 210 178 182 4 +48 196 209 176 4 +49 192 212 204 4 +50 197 202 201 0 +51 198 213 214 4 +52 173 193 188 64 +53 197 205 206 4 + +40 + + +25 + + +28 + + +64 +6 7 +10 5 64 20 11 +16 41 49 44 16 +2 36 13 21 4 +9 8 33 46 4 + +49 + + +52 + + +88 +12 13 +16 41 88 44 16 +22 65 73 68 24 +8 60 37 45 4 +15 32 57 70 4 + +73 + + +76 + + +112 +18 19 +22 65 112 68 24 +28 89 97 92 32 +14 84 61 69 4 +21 56 81 94 4 + +97 + + +100 + + +136 +24 25 +28 89 136 92 32 +34 113 121 116 40 +20 108 85 93 4 +27 80 105 118 4 + +121 + + +124 + + +160 +30 31 +34 113 160 116 40 +40 137 145 140 48 +26 132 109 117 4 +33 104 129 142 4 + +145 + + +148 + + +184 +36 37 +40 137 184 140 48 +46 161 169 164 56 +32 156 133 141 4 +39 128 153 166 4 + +169 + + +172 + + +208 +42 43 +46 161 208 164 56 +52 185 193 188 64 +38 180 157 165 4 +45 152 177 190 4 + +193 + + +196 + + +212 +48 49 +52 185 212 188 64 +53 209 205 206 4 +44 204 181 189 4 +51 176 213 214 4 + +205 + + +176 + + +181 +51 44 +53 209 181 189 4 +45 152 213 190 4 +47 210 214 182 4 + +152 + + +157 +45 38 +53 209 157 189 4 +39 128 213 166 4 +47 210 214 165 4 +41 186 190 158 4 + +128 + + +133 +39 32 +53 209 133 189 4 +33 104 213 142 4 +41 186 190 141 4 +35 162 166 134 4 + +104 + + +109 +33 26 +53 209 109 189 4 +27 80 213 118 4 +35 162 166 117 4 +29 138 142 110 4 + +80 + + +85 +27 20 +53 209 85 189 4 +21 56 213 94 4 +29 138 142 93 4 +23 114 118 86 4 + +56 + + +61 +21 14 +53 209 61 189 4 +15 32 213 70 4 +23 114 118 69 4 +17 90 94 62 4 + +32 + + +37 +15 8 +53 209 37 189 4 +9 8 213 46 4 +17 90 94 45 4 +11 66 70 38 4 + +8 + + +13 +9 2 +53 209 13 189 4 +3 6 213 22 4 +11 66 70 21 4 +5 42 46 14 4 + +6 + + +0 + + +210 + + +185 + + +161 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +214 + + +209 + + +185 + + +161 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +186 + + +161 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +190 + + +210 + + +185 + + +161 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +162 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +166 + + +186 + + +161 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +138 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +142 + + +162 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +114 + + +89 + + +65 + + +41 + + +5 + + +0 + + +118 + + +138 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +90 + + +65 + + +41 + + +5 + + +0 + + +94 + + +114 + + +89 + + +65 + + +41 + + +5 + + +0 + + +66 + + +41 + + +5 + + +0 + + +70 + + +90 + + +65 + + +41 + + +5 + + +0 + + +42 + + +5 + + +0 + + +46 + + +66 + + +41 + + +5 + + +0 + + +6 + + +0 + + +213 + + +209 + + +185 + + +161 + + +137 + + +113 + + +89 + + +65 + + +41 + + +5 + + +0 + + +42 + + +5 + + +0 + diff --git a/nodes.py b/nodes.py new file mode 100644 index 0000000..2278f31 --- /dev/null +++ b/nodes.py @@ -0,0 +1,58 @@ +class Nodes: + + def __init__(self): + self.nodes = [] + self.steps = [] + self.read('debug.txt') + self.cur_index = 0 + self.cur_nodes = {i: self.nodes[i] for i in self.steps[0]['mnodes'] if not i in self.steps[0]['rnodes']} + + def __len__(self): + return len(self.steps) + + def __getitem__(self, index): + if index > self.cur_index: + add, mnodes, rnodes = 1, 'mnodes', 'rnodes' + else: + add, mnodes, rnodes = -1, 'rnodes', 'mnodes' + + while self.cur_index != index: + if add == 1: self.cur_index += 1 + for i in self.steps[self.cur_index][mnodes]: + self.cur_nodes[i] = self.nodes[i] + for i in self.steps[self.cur_index][rnodes]: + del self.cur_nodes[i] + if add == -1: self.cur_index -= 1 + return (self.steps[self.cur_index]['gonext'], self.cur_nodes) + + + def read(self, fileName): + maxid = -1 + ndids = [] + with open(fileName, 'r') as file: + lines = iter(file.readlines()) + lines.__next__() + while True: + try: + gonext = int(lines.__next__()) + except StopIteration: + break + remove = [int(i) for i in lines.__next__().split()] + self.steps.append({'gonext': gonext, 'mnodes': [], 'rnodes': []}) + for line in lines: + if line == '\n': break + line = [int(i) for i in line.split()] + maxid += 1 + self.nodes.append(line) + self.steps[-1]['mnodes'].append(maxid) + if len(ndids) > line[0]: + if ndids[line[0]] != -1: + self.steps[-1]['rnodes'].append(ndids[line[0]]) + ndids[line[0]] = -1 + ndids[line[0]] = maxid + else: + ndids.append(maxid) + for indx in remove: + if ndids[indx] != -1: + self.steps[-1]['rnodes'].append(ndids[indx]) + ndids[indx] = -1 \ No newline at end of file diff --git a/src/abstract-combinators.js b/src/abstract-combinators.js index 61fda60..c495a4f 100644 --- a/src/abstract-combinators.js +++ b/src/abstract-combinators.js @@ -13,6 +13,7 @@ function slot(port) { function newNet() { return { debug: null, + gonxt: 0, nodes: [], reuse: [], stats: {loops:0, rules:0, betas:0, dupls:0, annis:0} @@ -21,11 +22,11 @@ function newNet() { function newNode(net, kind) { var node = net.reuse.pop() || (net.nodes.length / 4); - if(net.debug) net.debug.chnge.add(node) net.nodes[node * 4 + 0] = node * 4 + 0; net.nodes[node * 4 + 1] = node * 4 + 1; net.nodes[node * 4 + 2] = node * 4 + 2; net.nodes[node * 4 + 3] = kind << 2; + if(net.debug) { net.debug.nodes.add(node); net.debug.rmove.delete(node) } return node; } @@ -46,30 +47,35 @@ function setExit(net, node, exit) { } function link(net, a, b) { - net.nodes[a] = b; if (net.debug) net.debug.chnge.add(node(a)) - net.nodes[b] = a; if (net.debug) net.debug.chnge.add(node(b)) + net.nodes[a] = b; if (net.debug) net.debug.nodes.add(node(a)) + net.nodes[b] = a; if (net.debug) net.debug.nodes.add(node(b)) +} + +function reuse(net, node) { + net.reuse.push(node); if (net.debug) net.debug.rmove.add(node) } function reduce(net) { var prev, back; var warp = []; - var next = net.nodes[0]; + net.gonxt = net.nodes[0]; if (net.debug) net.debug.flush(); - while (next || warp.length) { - next = next || enterPort(net, port(warp.pop(), 2)); - prev = enterPort(net, next); - next = enterPort(net, prev); - if (slot(next) === 0 && slot(prev) === 0 && node(prev)) { + while (net.gonxt || warp.length) { + // console.log(JSON.stringify(net.nodes, space=0)); console.log(JSON.stringify(net.reuse, space=0)); + net.gonxt = net.gonxt || enterPort(net, port(warp.pop(), 2)); + prev = enterPort(net, net.gonxt); + net.gonxt = enterPort(net, prev); + if (slot(net.gonxt) === 0 && slot(prev) === 0 && node(prev)) { back = enterPort(net, port(node(prev), exit(net, node(prev)))); - rewrite(net, node(prev), node(next)); - next = enterPort(net, back); - } else if (slot(next) === 0) { - warp.push(node(next)); - next = enterPort(net, port(node(next), 1)); - setExit(net, node(next), 3); + rewrite(net, node(prev), node(net.gonxt)); + net.gonxt = enterPort(net, back); + } else if (slot(net.gonxt) === 0) { + warp.push(node(net.gonxt)); + net.gonxt = enterPort(net, port(node(net.gonxt), 1)); + setExit(net, node(net.gonxt), 3); } else { - setExit(net, node(next), slot(next)); - next = enterPort(net, port(node(next), 0)); + setExit(net, node(net.gonxt), slot(net.gonxt)); + net.gonxt = enterPort(net, port(node(net.gonxt), 0)); } ++net.stats.loops; if(net.debug) net.debug.flush() @@ -88,7 +94,8 @@ function rewrite(net, A, B) { link(net, enterPort(net, port(A, 2)), enterPort(net, port(B, 2))); net.stats.betas += kind(net, A) === 1 ? 1 : 0; net.stats.annis += 1; - net.reuse.push(A, B); + reuse(net, A); + reuse(net, B) } else { // 1 2 1 = B --- A = 2 // \ / \ / @@ -129,6 +136,7 @@ module.exports = { exit, setExit, link, + reuse, reduce, rewrite, }; diff --git a/src/lambda-calculus.js b/src/lambda-calculus.js index d961e2e..336018a 100644 --- a/src/lambda-calculus.js +++ b/src/lambda-calculus.js @@ -114,7 +114,7 @@ const toNet = (net, term) => { var [lam,kin] = scope[term.idx]; var arg = I.enterPort(net, I.port(lam,1)); if (I.kind(net, I.node(arg)) === 0) { - net.reuse.push(I.node(arg)); + I.reuse(net, I.node(arg)); return I.port(lam, 1); } else { var dup = I.newNode(net, kin); diff --git a/src/main.js b/src/main.js index a9a77c0..b66728e 100755 --- a/src/main.js +++ b/src/main.js @@ -40,11 +40,14 @@ if (debug) { fs.writeFileSync('debug.txt', ''); var file = fs.createWriteStream('debug.txt', {'flags':'a'}); net.debug = { - chnge: new Set([]), + rmove: new Set([]), + nodes: new Set([]), flush: () => { - net.debug.chnge.forEach( i => file.write(`${i} ${net.nodes[i+0]} ${net.nodes[i+1]} ${net.nodes[i+2]} ${net.nodes[i+3]}\n`)); - net.debug.chnge.clear() - file.write('\n'); + file.write(`\n${net.gonxt}\n`); + net.debug.rmove.forEach( i => file.write(`${i} `)); file.write('\n'); + net.debug.nodes.forEach( i => file.write(`${i} ${net.nodes[i*4+0]} ${net.nodes[i*4+1]} ${net.nodes[i*4+2]} ${net.nodes[i*4+3]}\n`)); + net.debug.nodes.clear() + net.debug.rmove.clear(); } } } diff --git a/simple-visualization.ipynb b/visualization.ipynb similarity index 74% rename from simple-visualization.ipynb rename to visualization.ipynb index 7370724..d2c205e 100644 --- a/simple-visualization.ipynb +++ b/visualization.ipynb @@ -15,39 +15,36 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ - "import json\n", - "from pandas import DataFrame\n", - "with open('absal-last-run.dump', 'r') as file:\n", - " history = [json.loads(line) for line in file.readlines()]" + "from nodes import Nodes" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "nodess = Nodes()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, "metadata": {}, "outputs": [ - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "754fc2aae03047ef81a0983b85da5667", + "model_id": "86b44f9caf9f412ab359ac4229b11489", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(IntSlider(value=24, description='iteration', max=49), Output()), _dom_classes=('widget-i…" + "interactive(children=(IntSlider(value=89, description='iteration', max=179), Output()), _dom_classes=('widget-…" ] }, "metadata": {}, @@ -55,39 +52,34 @@ } ], "source": [ - "nodes = history[0]['nodes']\n", - "ports = [(i >> 2, t >> 2) for i, t in enumerate(nodes) if (i+1) % 4 != 0 and i >> 2 not in history[0]['reuse']]\n", + "_, nodes = nodess[0]\n", + "\n", + "ports = [(node[0], t >> 2) for node in nodes.values() for t in node[1:4]]\n", "\n", - "plt.figure(figsize=(10,10))\n", "G = nx.DiGraph()\n", "G.add_edges_from(ports)\n", "pos = graphviz_layout(G)\n", "\n", - "@widgets.interact(iteration=(0, len(history)-1))\n", + "@widgets.interact(iteration=(0, len(nodess)-1,1))\n", "def draw(iteration):\n", - " net = history[iteration]\n", - " nodes = net['nodes']\n", - "\n", - " ports = [(i >> 2, t >> 2) for i, t in enumerate(nodes) if (i+1) % 4 != 0 and i >> 2 not in net['reuse']]\n", - " types = [ t >> 2 for i, t in enumerate(nodes) if (i+1) % 4 == 0 and i >> 2 not in net['reuse']]\n", - " crrnt = (nodes[net['next']] >> 2, net['next'] >> 2)\n", + " gonxt, nodes = nodess[iteration]\n", "\n", + " ports = [(node[0], t >> 2) for node in nodes.values() for t in node[1:4]]\n", + " types = [ node[4] >> 2 for node in nodes.values() ]\n", "\n", " plt.figure(figsize=(10,10))\n", " \n", " G = nx.DiGraph()\n", " G.add_edges_from(ports)\n", - " pos = graphviz_layout(G, )\n", + "# pos = graphviz_layout(G) #comment this line if you don't want to create new layout each iteration\n", " \n", - " nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), alpha=0.0, node_color = types, node_size = 500)\n", + " nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), alpha=0.0, node_size = 500)\n", + " nx.draw_networkx_nodes(G, pos, nodelist=[gonxt >> 2], alpha=1, node_size = 500)\n", " nx.draw_networkx_labels(G, pos)\n", - " nx.draw_networkx_edges(G, pos, edgelist=[crrnt], edge_color='grey', width=10) \n", " nx.draw_networkx_edges(G, pos, edgelist=ports[0:-1:3], alpha=.5, edge_color='red', width=4)\n", " nx.draw_networkx_edges(G, pos, edgelist=ports[1:-1:3], alpha=.5, edge_color='blue', width=4)\n", " nx.draw_networkx_edges(G, pos, edgelist=ports[2:-1:3], alpha=.5, edge_color='grey', width=3)\n", - " plt.show()\n", - " print('reuse: ', net['reuse'])\n", - " print('warp: ', net['warp'])" + " plt.show()" ] }, {